Title: K.U.Leuven JCHR a UserFriendly, Flexible and Efficient CHR System for Java
1K.U.Leuven JCHRa User-Friendly, Flexible and
Efficient CHR System for Java
- Peter Van Weert,Tom Schrijvers, Bart Demoen
Department of Computer Science, K.U.Leuven,
Belgium
2Outline
- Related Work
- Goals
- User-friendliness
- Flexibility
- Efficiency
- Conclusion and Future Work
- Questions
3Outline
- Related Work
- Timeline
- Other Java CHR Systems
- Goals
- User-friendliness
- Flexibility
- Efficiency
- Conclusion and Future Work
- Questions
4Timeline (CHR systems Java)
CHR
Oak
Java
5Other Java CHR Systems
- JaCK Java Constraint Kit
- Slim Abdennadher et al., 99-01
- Inefficient
- Inflexible
- DJCHR Armin Wolf, 00-01
- Dynamic Constraint Handling
- No familiar high-level syntax
- Extra requirements
6Goals
- Design and implementation of a new integration
of Java and CHR - User-friendly
- Flexible
- Efficient
- K.U.Leuven JCHR Java CHR CP
7User-friendliness
8Outline
- Related Work
- Goals
- User-friendliness
- Syntax
- Variables and expressions
- Coercion
- Semantics
- Flexibility
- Efficiency
- Conclusion and Future Work
- Questions
9Syntax goals
- Familiar and user-friendly
- for both CHR and Java adepts
- High-level, declarative
- CHR-rules
- Constraints
- Not only in Java, but also for Java
- Portability (mainly to Java)
CHR
CP
Java
10Syntax other Java systems
- JaCK
- High-level, declarative syntax
- Many differences (cf. next slides)
- DJCHR
- No high-level syntax
- Programming directly in Java code
- Increased development time, less readable,
- Portability?
11leq-handler in JaCKs JCHR
- handler leq
- class java.lang.Integer
- constraint leq( ,
) - rules
- variable X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
java.lang.Integer
java.lang.Integer
java.lang.Integer
- class-declarations
- mandatory, even if one uses the fully qualified
name - moreover using the fully qualified name remains
necessary!
12Declarations
import java.lang.Integer
- handler leq
- constraint leq(Integer, Integer)
- rules
- variable Integer X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
- import ? completely analogous to Java
- optional
- fully qualified name no longer required once
imported - first statement
- not explicitly necessary for java.lang.
13Declarations (constraints)
- handler leq
- constraint leq(Integer, Integer)
- rules
- variable Integer X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
- constraint-declarations
- constraints also supported (Prolog keyword)
14Declarations (constraints)
- handler leq
- constraint leq(Integer X, Integer Y)
- rules
- variable Integer X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
- constraint-declarations
- constraints also supported (Prolog keyword)
- naming arguments (typed as in JaCK)
- - syntactical analogy with Java method signature
- debugging readability and usability generated
code
15Declarations (variables)
- handler leq
- constraint leq(Integer X, Integer Y)
- rules
- variable Integer X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
- variables in JaCK
- only typed logical variables
- counterintuitive for Java adept
- no primitive types
16Declarations (variables)
- handler leq
- constraint leq(Integer X, Integer Y)
- rules
- variable Integer X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
- variables in K.U.Leuven JCHR
- regular Java-variables with arbitrary Java-types
17Declarations (variables)
- handler leq
- constraint leq(int X, int Y)
- rules
- variable int X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
- variables in K.U.Leuven JCHR
- regular Java-variables with arbitrary Java-types
- primitive types (efficiency in both space and
time) - gt here neither Integer nor int is what is
intended!
18Declarations (variables)
- import runtime.IntegerLogicalVariable
- handler leq
- constraint leq(IntegerLogicalVariable X,
IntegerLogicalVariable Y) - rules
- variable IntegerLogicalVariable X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
- variables in K.U.Leuven JCHR
- regular Java-variables with arbitrary Java-types
- primitive types (efficiency in both space and
time)
19Declarations (variables)
- import runtime.LogicalVariable
- handler leq
- constraint leq(LogicalVariableltIntegergt X,
LogicalVariableltIntegergt Y) - rules
- variable LogicalVariableltIntegergt X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
- variables in K.U.Leuven JCHR
- regular Java-variables with arbitrary Java-types
- primitive types (efficiency in both space and
time) - generic types (robustness and readability)
- LogicalVariableltTgt is the equivalent of the
variables in JaCK
20Declarations (genericity)
- import runtime.LogicalVariable
- handler leq
- constraint leq(LogicalVariablelt gt X,
LogicalVariablelt gt Y) - rules
- variable LogicalVariablelt gt X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
Integer
Integer
Integer
- handler only for Integers
- strong limitation
- solutions?
- declaring separate handler for each type?
- using general type (Object) explicit type
casting??
21Generic Handlers
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
- generic handler
- powerful, readable and robust
- eases porting from untyped LP (Prolog) to
strongly typed Java - completes syntactical analogy with Java class
(Java 1.5)
22Rule Definitions
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
23Rule Definitions
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- if (X Y) leq(X, Y) ltgt true
reflexivity - leq(X, Y) leq(Y, X) ltgt X Y
antisymmetry - leq(X, Y) \ leq(X, Y) ltgt true
idempotence - leq(X, Y) leq(Y, Z) gt leq(X, Z)
transitivity -
24Rule Definitions
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- reflexivity _at_ if (X Y) leq(X, Y) ltgt
true - antisymmetry _at_ leq(X, Y) leq(Y, X) ltgt
X Y - idempotence _at_ leq(X, Y) \ leq(X, Y) ltgt
true - transitivity _at_ leq(X, Y) leq(Y, Z)
gt leq(X, Z) -
25Rule Definitions
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- reflexivity _at_ if (X Y) leq(X, Y) ltgt
true - antisymmetry _at_ leq(X, Y) leq(Y, X) ltgt
X Y - idempotence _at_ leq(X, Y) \ leq(X, Y) ltgt
true - transitivity _at_ leq(X, Y) leq(Y, Z) gt
leq(X, Z) -
26Rule Definitions
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- reflexivity _at_ if (X Y) leq(X, Y) ltgt true
- antisymmetry _at_ leq(X, Y) leq(Y, X) ltgt X
Y - idempotence _at_ leq(X, Y) \ leq(X, Y) ltgt
true - transitivity _at_ leq(X, Y) leq(Y, Z) gt
leq(X, Z) -
27Rule Definitions
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- reflexivity _at_ leq(X, Y) ltgt X Y true
- antisymmetry _at_ leq(X, Y) leq(Y, X) ltgt X
Y - idempotence _at_ leq(X, Y) \ leq(X, Y) ltgt
true - transitivity _at_ leq(X, Y) leq(Y, Z) gt
leq(X, Z) -
28Rule Definitions
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- reflexivity _at_ leq(X, Y) ltgt X Y true
- antisymmetry _at_ leq(X, Y) leq(Y, X) ltgt X
Y - idempotence _at_ leq(X, Y) \ leq(X, Y) ltgt
true - transitivity _at_ leq(X, Y) leq(Y, Z) gt
leq(X, Z) -
29Rule Definitions
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- reflexivity _at_ leq(X, Y) ltgt X Y true
- antisymmetry _at_ leq(X, Y) leq(Y, X) ltgt
X Y - idempotence _at_ leq(X, Y) \ leq(X, Y) ltgt true
- transitivity _at_ leq(X, Y) leq(Y, Z) gt
leq(X, Z) -
30Rule Definitions
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- reflexivity _at_ leq(X, Y) ltgt X Y true.
- antisymmetry _at_ leq(X, Y) , leq(Y, X) ltgt X
Y. - idempotence _at_ leq(X, Y) \ leq(X, Y) ltgt true.
- transitivity _at_ leq(X, Y) , leq(Y, Z) gt
leq(X, Z). -
31Rule Definitions
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - rules
- variable LogicalVariableltTgt X, Y, Z
- reflexivity _at_ leq(X, Y) ltgt X Y true.
- antisymmetry _at_ leq(X, Y) , leq(Y, X) ltgt X
Y. - idempotence _at_ leq(X, Y) \ leq(X, Y) ltgt true.
- transitivity _at_ leq(X, Y) , leq(Y, Z) gt
leq(X, Z). -
32leq-handler in K.U.Leuven JCHR
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt,
LogicalVariableltTgt) infix lt -
- rules
- variable LogicalVariableltTgt X, Y, Z
- reflexivity _at_ X lt Y ltgt X Y true.
- antisymmetry _at_ X lt Y , Y lt X ltgt X Y.
- idempotence _at_ X lt Y \ X lt Y ltgt true.
- transitivity _at_ X lt Y , Y lt Z gt X lt Z.
-
33leq-handler in K.U.Leuven JCHR
- import runtime.LogicalVariable
- handler leqltTgt
- constraint leq(LogicalVariableltTgt,
LogicalVariableltTgt) infix lt - solver runtime.EqualitySolverltTgt
- rules
- variable LogicalVariableltTgt X, Y, Z
- reflexivity _at_ X lt Y ltgt X Y true.
- antisymmetry _at_ X lt Y , Y lt X ltgt X Y.
- idempotence _at_ X lt Y \ X lt Y ltgt true.
- transitivity _at_ X lt Y , Y lt Z gt X lt Z.
-
- Infix-notation possible
- Declaration built-in solver(s) required
34Variables and expressions
- JaCK
- Only typed logical variables
- Limited Java-like expressions
- E.g. no variables as implicit argument
- Only equality (naive union-find)
- DJCHR
- Only logical variables
- Terms and limited arithmetic
- Only equality over terms (unification)
- Ergo LP in Java
35Variables and expressions
- K.U.Leuven JCHR
- Full-fledged Java variables
- Wide range of Java expressions
- E.g. variables can be used as implicit argument
- Arbitrary built-in constraints
- Logical variables equality is only one of the
possibilities - Ergo Java CHR CP
36ExamplePrimitive variables and arbitr.
Java-expressions
- import java.math.BigInteger
- import runtime.LogicalVariable
- import util.arithmetics.primitives.intUtil
- handler fib
- solver runtime.EqualitySolverltBigIntegergt
- constraint fib(int N, LogicalVariableltBigIntegergt
M) -
- rules
- variable LogicalVariableltBigIntegergt M, M1, M2
- variable int N, N1, N2
- fib(N,M1), fib(N,M2) ltgt M1 M2, fib(N, M1)
- fib(0,M) gt M 1
- fib(1,M) gt M 1
- fib(N,M) gt N gt 1
- N1 intUtil.dec(N), fib(N1,M1),
- N2 intUtil.sub(N, 2), fib(N2,M2),
- M M1.add(M2)
37Coercion
- Transformation of a value of one type
- into a value of another type
- In two directions
- coercion, a generalisation of auto-unboxing
- initialisation, a generalisation of auto-boxing
- Arbitrary expressions used as argument
- Portability!
38Semantics
- JaCK
- Not compliant with refined operational semantics
?r - Not even compliant with theoretical operational
semantics ?t - DJCHR
- Incremental operational semantics
- Dynamic requirements arbitrary deletions and
(re)insertions of constraints - Compliant to declarative semantics
- Relationship to theoretical/refined operational
semantics??
39Semantics
- K.U.Leuven JCHR
- Completely compliant to refined operation
semantics ?r
40Example semantics
- import java.math.BigInteger
- import runtime.LogicalVariable
- import util.arithmetics.primitives.intUtil
- handler fib
- solver runtime.EqualitySolverltBigIntegergt
- constraint fib(int N, LogicalVariableltBigIntegergt
M) -
- rules
- variable LogicalVariableltBigIntegergt M, M1, M2
- variable int N, N1, N2
- fib(N,M1), fib(N,M2) ltgt M1 M2, fib(N, M1)
- fib(0,M) gt M 1
- fib(1,M) gt M 1
- fib(N,M) gt N gt 1
- fib(intUtil.dec(N), M1),
- fib(intUtil.sub(N, 2), M2),
- M M1.add(M2)
41Flexibility
42Outline
- Related Work
- Goals
- User-friendliness
- Flexibility
- Architectural design
- Arbitrary types
- Arbitrary built-in constraints
- Efficiency
- Conclusion and Future Work
- Questions
43Architectural design
Compiler
Runtime
Java 1.5
44Architecture Compiler
Compiler
Runtime
Java 1.5
45Architecture Runtime
Compiler
Runtime
Java 1.5
46Arbitrary Java types
- Other Java systems only logical variables
- K.U.Leuven JCHR arbitrary Java types
- Implicitly known to the system
- 8 primitive types (boolean, int, long, float, )
- wrappers (Boolean, Integer, Long, Float, )
- String
- Other types declaratively marking method(s) for
e.g. coercion using annotations
47Arbitrary built-in constraints
- Other Java systems only equality
- K.U.Leuven JCHR arbitrary built-in constraints
- Implicitly known to the system
- (dis)equality over primitive types and
java.lang.Comparable-objects - java.lang.Comparator-solvers
- equals()- method for objects
- Easy integration of other solvers using explicit
solver-declarations and annotations
48ExampleDeclarative annotation of built-in
constraint
- _at_CHRconstraints(
- _at_CHRconstraint(
- name "eq",
- arity 2,
- infix ""
- )
- )
- public interface EqualitySolverltTgt
- _at_CHRtells("eq")
- public void tellEqual(LogicalVariableltTgt X, T
val) - _at_CHRtells("eq")
- public void tellEqual(T val, LogicalVariableltTgt
X) - _at_CHRtells("eq")
- public void tellEqual(LogicalVariableltTgt X,
LogicalVariableltTgt Y) - _at_CHRasks("eq")
- public boolean askEqual(LogicalVariableltTgt X, T
val) - _at_CHRasks("eq")
- public boolean askEqual(T val, LogicalVariableltTgt
X) - _at_CHRasks("eq")
49Efficiency
50Outline
- Related Work
- Goals
- User-friendliness
- Flexibility
- Efficiency
- Compilation
- Implemented optimisations
- Benchmarks
- Conclusion and Future Work
- Questions
51Compilation
- JaCK
- High-level, declarative syntax
- No compilation to low-level Java-code
- More interpretation
- High runtime penalties
- DJCHR
- No high-level, declarative syntax
- Compilation to more efficient, low-level Java code
52Compilation
- K.U.Leuven JCHR
- Familiar, declarative, high-level syntax
- Compiled using optimised compilation scheme,
tailored for the host language Java - Distributed propagation history
- Sequential continuation-based control flow
- Explicit backjumping
- Generations
- Late storage
- Inlining
- And others
- Gradual movement from generic code towards more
efficient generated code e.g. constraint store
53Implemented optimisations
- Static program analysis scheduling
- Index constraint store hash-index
- Also for arguments that are not fixed
- Built-in equality-solver optimised union-find
algorithm - path compression and union-by-rank
54Union-benchmark
55Leq-benchmark
56Bool-benchmark
57Fib-benchmark
58Primes-benchmark
59Outline
- Related Work
- Goals
- User-friendliness
- Flexibility
- Efficiency
- Conclusion and Future Work
- Questions
60Conclusion
- The K.U.Leuven JCHR system is
- User-Friendly
- Syntax semantics, coercion
- Intuitive look and feel
- Easy porting
- Flexible
- Integrating arbitrary optimisations
- Built-in solvers
- Efficient
- Host language tailored compilation scheme
- Available at http//www.cs.kuleuven.be/toms/CHR/
JCHR/
61Future Work
- Add search / backtracking support
- Interaction with / implementation of new built-in
solvers - Implementation of extra optimisations
- Arithmetic expressions
- Debugging
- etc
- Integration of CHR with other imperative
(object-oriented) languages (e.g. C, C,
Visual Basic, )
62Questions