SLIDE 1 A comparison with LP (I)
- Example (Prolog): q(X, Y, Z) :- Z = f(X, Y).
| ?- q(3, 4, Z). Z = f(3,4) | ?- q(X, Y, f(3,4)). X = 3, Y = 4 | ?- q(X, Y, Z). Z = f(X,Y)
- Example (Prolog): p(X, Y, Z) :- Z is X + Y.
| ?- p(3, 4, Z). Z = 7 | ?- p(X, 4, 7). {INSTANTIATION ERROR: in expression}
1
SLIDE 2 A Comparison with LP (II)
- Example (CLP(ℜ)): p(X, Y, Z) :- Z = X + Y.
2 ?- p(3, 4, Z). Z = 7 *** Yes 3 ?- p(X, 4, 7). X = 3 *** Yes 4 ?- p(X, Y, 7). X = 7 - Y *** Yes
2
SLIDE 3 A Comparison with LP (III)
⋄ Domain of computation (reals, integers, booleans, etc). Have to meet some conditions. ⋄ Type of constraints allowed for each domain: e.g. arithmetic constraints (+, ∗, =, ≤, ≥, <, >) ⋄ Constraint solving algorithms: simplex, gauss, etc.
- LP can be viewed as a constraint logic language over Herbrand terms with a
single constraint predicate symbol: “=”
3
SLIDE 4 A Comparison with LP (IV)
⋄ Helps making programs expressive and flexible. ⋄ May save much coding. ⋄ In some cases, more efficient than traditional LP programs due to solvers typically being very efficiently implemented. ⋄ Also, efficiency due to search space reduction: * LP: generate-and-test. * CLP: constrain-and-generate.
⋄ Complexity of solver algorithms (simplex, gauss, etc) for system developer (and can affect performance).
4
SLIDE 5 Example of Search Space Reduction
- Prolog (generate–and–test):
solution(X, Y, Z) :- p(X), p(Y), p(Z), test(X, Y, Z). p(14). p(15). p(16). p(7). p(3). p(11). test(X, Y, Z) :- Y is X + 1, Z is Y + 1.
| ?- solution(X, Y, Z). X = 14 Y = 15 Z = 16 ? ; no
- 458 steps (all solutions: 465 steps).
5
SLIDE 6 Example of Search Space Reduction
- CLP(ℜ) (using generate–and–test):
solution(X, Y, Z) :- p(X), p(Y), p(Z), test(X, Y, Z). p(14). p(15). p(16). p(7). p(3). p(11). test(X, Y, Z) :- Y = X + 1, Z = Y + 1.
?- solution(X, Y, Z). Z = 16 Y = 15 X = 14 *** Retry? y *** No
- 458 steps (all solutions: 465 steps).
6
SLIDE 7
Generate–and–test Search Tree
A5 Y=14 Y=15 A4 A3 A2 A1 X=15 X=16 X=7 X=3 X=11 X=14 Z=14 Z=15 Z=16 Z=7 Z=3 Z=11 g B5 Y=11 Y=3 Y=7 Y=16 B4 B3 B2 B1 B A
7
SLIDE 8 Example of Search Space Reduction
- Move test(X, Y, Z) at the beginning (constrain–and–generate):
solution(X, Y, Z) :- test(X, Y, Z), p(X), p(Y), p(Z). p(14). p(15). p(16). p(7). p(3). p(11).
- Prolog: test(X, Y, Z) :- Y is X + 1, Z is Y + 1.
| ?- solution(X, Y, Z). {INSTANTIATION ERROR: in expression}
- CLP(ℜ): test(X, Y, Z) :- Y = X + 1, Z = Y + 1.
?- solution(X, Y, Z). Z = 16 Y = 15 X = 14 *** Retry? y *** No
- 11 steps (all solutions: 11 steps).
8
SLIDE 9
Constrain–and–generate Search Tree
Y=15 X=15 X=16 X=7 X=3 X=11 X=14 Z=16 g Y=16
9
SLIDE 10 Fibonaci Revisited (Prolog)
F0 = 0 F1 = 1 Fn+2 = Fn+1 + Fn
- (The good old) Prolog version:
fib(0, 0). fib(1, 1). fib(N, F) :- N > 1, N1 is N - 1, N2 is N - 2, fib(N1, F1), fib(N2, F2), F is F1 + F2.
- Can only be used with the first argument instantiated to a number
10
SLIDE 11 Fibonaci Revisited (CLP(ℜ))
- CLP(ℜ) version: syntactically similar to the previous one
fib(0, 0). fib(1, 1). fib(N, F1 + F2) :- N > 1, F1 >= 0, F2 >= 0, fib(N - 1, F1), fib(N - 2, F2).
- Note all constraints included in program (F1 >= 0, F2 >= 0) – good practice!
- Only real numbers and equations used (no data structures, no other constraint
system): “pure CLP(ℜ)”
- Semantics greatly enhanced! E.g.
?- fib(N, F). F = 0, N = 0 ; F = 1, N = 1 ; F = 1, N = 2 ; F = 2, N = 3 ; F = 3, N = 4 ;
11
SLIDE 12 Analog RLC circuits (CLP(ℜ))
- Analysis and synthesis of analog circuits
- RLC network in steady state
- Each circuit is composed either of:
⋄ A simple component, or ⋄ A connection of simpler circuits
- For simplicity, we will suppose subnetworks connected only in parallel and series
− → Ohm’s laws will suffice (other networks need global, i.e., Kirchoff’s laws)
- We want to relate the current (I), voltage (V) and frequency (W) in steady state
- Entry point: circuit(C, V, I, W) states that:
across the network C, the voltage is V, the current is I and the frequency is W
- V and I must be modeled as complex numbers (the imaginary part takes into
account the angular frequency)
- Note that Herbrand terms are used to provide data structures
12
SLIDE 13 Analog RLC circuits (CLP(ℜ))
- Complex number X + Y i modeled as c(X, Y)
- Basic operations:
c_add(c(Re1,Im1), c(Re2,Im2), c(Re1+Re2,Im1+Im2)). c_mult(c(Re1, Im1), c(Re2, Im2), c(Re3, Im3)) :- Re3 = Re1 * Re2 - Im1 * Im2, Im3 = Re1 * Im2 + Re2 * Im1. (equality is c equal(c(R, I), c(R, I)), can be left to [extended] unification)
13
SLIDE 14 Analog RLC circuits (CLP(ℜ))
circuit(series(N1, N2), V, I, W) :- c_add(V1, V2, V), circuit(N1, V1, I, W), circuit(N2, V2, I, W).
circuit(parallel(N1, N2), V, I, W) :- c_add(I1, I2, I), circuit(N1, V, I1, W), circuit(N2, V, I2, W).
14
SLIDE 15 Analog RLC circuits (CLP(ℜ))
Each basic component can be modeled as a separate unit:
- Resistor: V = I ∗ (R + 0i)
circuit(resistor(R), V, I, _W) :- c_mult(I, c(R, 0), V).
- Inductor: V = I ∗ (0 + WLi)
circuit(inductor(L), V, I, W) :- c_mult(I, c(0, W * L), V).
1 WCi)
circuit(capacitor(C), V, I, W) :- c_mult(I, c(0, -1 / (W * C)), V).
15
SLIDE 16 Analog RLC circuits (CLP(ℜ))
I = 0.65 L = 0.073 C = ? R = ? V = 4.5 ω = 2400
?- circuit(parallel(inductor(0.073), series(capacitor(C), resistor(R))), c(4.5, 0), c(0.65, 0), 2400). R = 6.91229, C = 0.00152546 ?- circuit(C, c(4.5, 0), c(0.65, 0), 2400).
16
SLIDE 17 The N Queens Problem
place N chess queens in a N × N board such that they do not attack each other
- Data structure: a list holding the column position for each row
- The final solution is a permutation of the list [1, 2, ..., N]
- E.g.: the solution
is represented as [2, 4, 1, 3]
⋄ Start with partial solution ⋄ Nondeterministically select new queen ⋄ Check safety of new queen against those already placed ⋄ Add new queen to partial solution if compatible; start again with new partial solution
17
SLIDE 18
The N Queens Problem (Prolog)
queens(N, Qs) :- queens_list(N, Ns), queens(Ns, [], Qs). queens([], Qs, Qs). queens(Unplaced, Placed, Qs) :- select(Unplaced, Q, NewUnplaced), no_attack(Placed, Q, 1), queens(NewUnplaced, [Q|Placed], Qs). no_attack([], _Queen, _Nb). no_attack([Y|Ys], Queen, Nb) :- Queen =\= Y + Nb, Queen =\= Y - Nb, Nb1 is Nb + 1, no_attack(Ys, Queen, Nb1). select([X|Ys], X, Ys). select([Y|Ys], X, [Y|Zs]) :- select(Ys, X, Zs). queens_list(0, []). queens_list(N, [N|Ns]) :- N > 0, N1 is N - 1, queens_list(N1, Ns).
18
SLIDE 19
The N Queens Problem (Prolog)
19
SLIDE 20
The N Queens Problem (CLP(ℜ))
queens(N, Qs) :- constrain_values(N, N, Qs), place_queens(N, Qs). constrain_values(0, _N, []). constrain_values(N, Range, [X|Xs]) :- N > 0, X > 0, X <= Range, constrain_values(N - 1, Range, Xs), no_attack(Xs, X, 1). no_attack([], _Queen, _Nb). no_attack([Y|Ys], Queen, Nb) :- abs(Queen - (Y + Nb)) > 0, % Queen =\= Y + Nb abs(Queen - (Y - Nb)) > 0, % Queen =\= Y - Nb no_attack(Ys, Queen, Nb + 1). place_queens(0, _). place_queens(N, Q) :- N > 0, member(N, Q), place_queens(N - 1, Q). member(X, [X|_]). member(X, [_|Xs]) :- member(X, Xs).
20
SLIDE 21 The N Queens Problem (CLP(ℜ))
- This last program can attack the problem in its most general instance:
?- queens(M,N). N = [], M = 0 ; M = [1], M = 1 ; N = [2, 4, 1, 3], M = 4 ; N = [3, 1, 4, 2], M = 4 ; N = [5, 2, 4, 1, 3], M = 5 ; N = [5, 3, 1, 4, 2], M = 5 ; N = [3, 5, 2, 4, 1], M = 5 ; N = [2, 5, 3, 1, 4], M = 5 ...
- Remark: Herbrand terms used to build the data structures
- But also used as constraints (e.g., length of already built list Xs in no attack(Xs,
X, 1))
- Note that in fact we are using both ℜ and FT
21
SLIDE 22
The N Queens Problem (CLP(ℜ))
22
SLIDE 23 The N Queens Problem (CLP(ℜ))
- CLP(ℜ) generates internally a set of equations for each board size
- They are non–linear and are thus delayed until instantiation wakes them up
?- constrain_values(4, 4, Q). Q = [_t3, _t5, _t13, _t21] _t3 <= 4 0 < abs(-_t13 + _t3 - 2) _t5 <= 4 0 < abs(-_t13 + _t3 + 2) _t13 <= 4 0 < abs(-_t21 + _t3 - 3) _t21 <= 4 0 < abs(-_t21 + _t3 + 3) 0 < _t3 0 < abs(-_t13 + _t5 - 1) 0 < _t5 0 < abs(-_t13 + _t5 + 1) 0 < _t13 0 < abs(-_t21 + _t5 - 2) 0 < _t21 0 < abs(-_t21 + _t5 + 2) 0 < abs(-_t5 + _t3 - 1) 0 < abs(-_t21 + _t13 - 1) 0 < abs(-_t5 + _t3 + 1) 0 < abs(-_t21 + _t13 + 1)
23
SLIDE 24 The N Queens Problem (CLP(ℜ))
- Constraints are (incrementally) simplified as new queens are added
?- constrain_values(4, 4, Qs), Qs = [3,1|OQs]. OQs = [_t16, _t24] 0 < abs(-_t24) Qs = [3, 1, _t16, _t24] 0 < abs(-_t24 + 6) _t16 <= 4 0 < abs(-_t16) _t24 <= 4 0 < abs(-_t16 + 2) 0 < _t16 0 < abs(-_t24 - 1) 0 < _t24 0 < abs(-_t24 + 3) 0 < abs(-_t16 + 1) 0 < abs(-_t24 + _t16 - 1) 0 < abs(-_t16 + 5) 0 < abs(-_t24 + _t16 + 1)
- Bad choices are rejected using constraint consistency:
?- constrain_values(4, 4, Qs), Qs = [3,2|OQs]. *** No
24
SLIDE 25 Some Real Systems (I)
- CLP defines a class of languages obtained by
⋄ Specifying the particular constraint system(s) ⋄ Specifying Computation and Selection rules
- Most share the Herbrand domain with “=”, but add different domains and/or solver
algorithms
- Most use Computation and Selection rules of Prolog
- CLP(ℜ):
⋄ Linear arithmetic over reals (=, ≤, >) ⋄ Gauss elimination and an adaptation of Simplex
⋄ Linear arithmetic over rationals (=, ≤, >, =), Simplex ⋄ Boolean (=), 2-valued Boolean Algebra ⋄ Infinite (rational) trees (=, =) ⋄ Equations over finite strings
25
SLIDE 26 Some Real Systems (II)
⋄ Linear arithmetic over rationals (=, ≤, >, =), Simplex ⋄ Boolean (=), larger Boolean algebra (symbolic values) ⋄ Finite domains ⋄ User–defined constraints and solver algorithms
⋄ Arithmetic over reals (closed intervals) (=, ≤, >, =), Simplex, propagation techniques ⋄ Boolean (=), 2-valued Boolean algebra ⋄ Finite domains, consistency techniques under user–defined strategy
⋄ Linear arithmetic over reals (=, ≤, >, =) ⋄ Linear arithmetic over rationals (=, ≤, >, =) ⋄ Finite domains (in recent versions)
26
SLIDE 27 Some Real Systems (III)
⋄ Finite domains ⋄ Linear arithmetic over reals (=, ≤, >, =) ⋄ Linear arithmetic over rationals (=, ≤, >, =)
⋄ Finite domains
⋄ Real arithmetic terms: any arithmetic constraint over reals ⋄ Improved version of Tarski’s quantifier elimination
⋄ Linear arithmetic over reals (=, ≤, >, =) ⋄ Linear arithmetic over rationals (=, ≤, >, =) ⋄ Finite Domains (currently interpreted) (can be selected on a per-module basis)
27
SLIDE 28 Other Extensions: Functional Notation (functions)
- Functional notation: defined via (local) ops/expansions.
Provides simple syntactic translation to predicate definitions/calls: ⋄ Defining function F/N implies defining predicate F/(N+1). ⋄ Any predicate P/(N+1) can be used as a function P/N. ⋄ The last argument of the predicate holds the result of the function.
- Using functions does not incur in run-time slowdowns.
- Function applications are recognized by:
⋄ Marking them with the prefix operator ˜ ⋄ A :- function(F/N) declaration makes all occurrences of a F/N functor to be regarded as a function call. ⋄ Arithmetic operators are translated to is/2 calls (optional).
- Example: defining fact/1 factorial function (and fact/2 predicate!)
:- use_package(functions). fact(0) := 1. fact(N) := N * ˜fact(--N) :- N > 0.
28
SLIDE 29 Functions Package: Examples – Array Access Syntax
- Assume multi-dimensional arrays such as:
:- use_package(functions). array([N],A) :- functor(A,a,N). array([N|Ms],A) :- functor(A,a,N), rows(N,Ms,A). rows(0,_Ms,_A). rows(N,Ms,A) :- N>0, arg(N,A,Arg), array(Ms,Arg), rows(N-1,Ms,A).
29
SLIDE 30 Functions Package: Examples – Array Access Syntax
- We can now define the array access function with some syntactic sugar:
:- op(45, xfx, [@]). :- function ’@’/2 . @(V,[I]) := ˜arg(I,V). @(V,[I|Js]) := @(˜arg(I,V),Js).
?- array([2,2],M), M@[2,1] = 3, display(M).
- E.g., in a vector addition:
vecplus(V1,V2,V3) :- array([N],V1), array([N],V2), array([N],V3), vecplus_(N,V1,V2,V3). vecplus_(0,_,_,_). vecplus_(N,V1,V2,V3) :- N>0, V3@[N] = V1@[N] + V2@[N], vecplus_(N-1,V1,V2,V3).
30
SLIDE 31 Functions Package: Examples – Sugar for Append
- Some syntactic sugar for append:
:- function append/2. test1 :- set_prolog_flag(write_strings,on), X = " ", write(append("Hello",append(X,"world!"))).
:- function append/2. :- op(200,xfy,[::]). :- function :: /2. A :: B := append(A,B). test2 :- set_prolog_flag(write_strings,on), X = " ", write("Hello" :: X :: "world!").
31
SLIDE 32 Support for Higher-Order Programming
- Ciao provides a number of facilities for easing HO programming [?]
(see the hiord package).
- The family of call/N builtins allows the first argument of a call to call/N to be
instantiated to: ⋄ A “predicate abstraction”: (’’(X,Y) :- Y is X+10) (read ’’ as λ). ⋄ A higher-order term (supporting currying), e.g.: member([1,2])
- Special syntax supported:
P(X,. . . ) is read as call(P,X,. . . ), (X,. . . ) is read as ’’(X,. . . )
- meta predicate/1 declarations extended to reflect higher-order predicates
(pred(N)).
32
SLIDE 33
Simple Higher-Order Programming Examples
?- use_package(hiord). ?- P = >(0), P(3). P = >(0) ? yes ?- P = member([1,2]), P(X). P = member([1,2]), X = 1 ? ; P = member([1,2]), X = 2 ? ; no ?- call(member([1,2]),X). X = 1 ? ; X = 2 ? ; no
33
SLIDE 34
Simple Higher-Order Programming Examples (Contd.)
?- P = ( _(X,Y):- Y is X+10 ), P(2,R). P = (’’(X,Y):-Y is X+10), R = 12 ? yes ?- call(( _(X,Y):- Y is X+10 ), 2, R). R = 12 ? yes ?-
34
SLIDE 35 Simple Higher-Order Programming Examples (Contd.)
- Example, parametric list regular type:
:- use_package(hiord). :- prop list(L,T) + regtype # "@var{L} is a list of @var{T}s.". :- meta_predicate list(?, pred(1)). list([],_). list([X|Xs], T) :- T(X), list(Xs, T).
⋄ list(L, atom) checks that a term L is a list of atoms. ⋄ list(L, list(atom)) checks that a term L is a list of lists of atoms. ⋄ list(L, ( (X) :- write(X), nl)) writes all the elements of L !
35
SLIDE 36 Simple Higher-Order Programming Examples (Contd.)
:- use_package(hiord). :- meta_predicate map(_,pred(2),_). map([], _, []). map([X|Xs], P, [Y|Ys]) :- P(X,Y), map(Xs,P,Ys).
- Example use of map/3: translating a list of indices to a list of terms.
?- map([1,3,2], arg(f(a,b,c,d)), R). R = [a,c,b] ? yes ?- map([1,3,2], ( ’’(X,Y) :- Y is X +1 ), R). R = [2,4,3] ? yes
36
SLIDE 37 Combining Higher-Order with Functional Notation
- They can be combined, resulting in essentially functional-style code
(but sometimes with additional modes of use!).
- Some common examples (in library(hiordlib)):
:- meta_predicate map(_,pred(2),_). map([], _) := []. map([X|Xs], P) := [˜P(X)|˜map(Xs,P)]. :- meta_predicate foldl(_,_,pred(3),_). foldl([], Seed, _Op) := Seed. foldl([X|Xs], Seed, Op) := ˜Op(X,˜foldl(Xs,Seed,Op)).
- Example use of map/3: translating a list of indices to a list of terms.
?- map([1,3,2], arg(f(a,b,c,d)), R). R = [a,c,b] ? yes
37
SLIDE 38 A Currying Model
- A form of currying is provided which is adapted to familiar argument order
conventions in logic programs: ⋄ For unary higher-order predicates, the argument is added first: >(0) checks if a given number is greater than 0 member(L) is true if the argument is member of the list L ⋄ For binary higher-order predicates, the first argument is added first, the second one is added last: append(".") appends to the first argument the string ".", returning the result in the second one /(2) divides by 2 the first argument, returning the result in the second one (given the definition /(X,Y,Z) :- Z is X/Y)
38
SLIDE 39 Higher-Order Programming (Contd.): Currying Rules in Action
:- set_prolog_flag(multi_arity_warnings,off). p(X,Y,Z,W,K,L) :- display(p(X,Y,Z,W,K,L)),nl. ?- use_package(hiord). ?- call(p,1,2,3,4,5,6).
p(1,2,3,4,5,6) ?- call(p(1),2,3,4,5,6).
p(2,1,3,4,5,6) ?- call(p(1,2),3,4,5,6).
p(3,1,2,4,5,6) ?- call(p(1,2,3),4,5,6).
p(4,1,2,3,5,6) ?- call(p(1,2,3,4),5,6).
p(5,1,2,3,4,6) ?- call(p(1,2,3,4,5),6).
p(6,1,2,3,4,5) ?- call(p(1,2,3,4,5,6)).
p(1,2,3,4,5,6)
39
SLIDE 40 Domians for (Constraint) Logic Programs (Set Sharing)
- Even more accurate sharing – set sharing [Jacobs et al.] [Muthukumar et al.]:
sets of sets of variables. θ = {W/a, X/f(A1, A2, A3), Y/g(A2), Z/A3} θα = {∅, {X}, {X, Y }, {X, Z}}
- A bit tricky to understand. Try:
{X} {X, Y } {X, Z} A1 A2 A3 θ = {W/a, X/f(A1, A2, A3, B1), Y/g(h(A2, B1)), Z/A3} θα = {∅, {X}, {X, Y }, {X, Z}} {X} {X, Y } {X, Z} A1 A2 + B1 A3
- Encodes grounding and independence
⋄ W has no ocurrence in any set: it is ground ⋄ {Y, Z} has no ocurrence in any set: they are independent
40
SLIDE 41 Domians for Constraint Logic Programs (Def)
- Example: Definiteness analysis (Def) [G. de la Banda et al.]
Domain: Def = {d, ℘(℘(Pvar)), ⊤}) X = Y + Z ⇒ [(X, [[Y, Z]]), (Y, [[X, Z]]), (Z, [[X, Y ]])] X = f(Y, Z) ⇒ [(X, [[Y, Z]]), (Y, [[X]]), (Z, [[X]])] X :: N ⇒ [(X, ⊤), (N, [[X]])] X > Y ⇒ [(X, ⊤), (Y, ⊤)] X = 3 ⇒ [(X, d)]
⋄ Freeness analysis [Dumortier et al.] and combinations. ⋄ LSign [Marriott, Sondergaard and Stuckey, ILPS’94]
⋄ optimization [Keely et al., CP’96] ⋄ parallelization [Bueno et al., PLILP’96] ⋄ ...
41