Download pdf format

Transcript
14.4
Programming Basic Behaviours
As an example, we will look at creating constraint versions of the following predicate. It defines
a relationship between containers of type 1, 2 or 3, and their capacity:
capacity(1, N) :- N>=0.0, N=<350.0.
capacity(2, N) :- N>=0.0, N=<180.0.
capacity(3, N) :- N>=0.0, N=<50.0.
This definition gives the intended declarative meaning, but does not behave as a constraint:
capacity(3, C) will raise an error, and capacity(Type, 30.5) will generate several solutions
nondeterministically. Only calls like capacity(3, 27.1) will act correctly as a test.
14.4.1
Consistency Check
To program the passive consistency check behaviour, we need to wait until both arguments of
the predicate are instantiated. This can be achieved by adding an ECLi PSe delay clause:
delay capacity(T,N) if var(T);var(N).
capacity(1, N) :- N>=0.0, N=<350.0.
capacity(2, N) :- N>=0.0, N=<180.0.
capacity(3, N) :- N>=0.0, N=<50.0.
The delay clause specifies that any call to capacity/2 will delay as long as one of the arguments is a variable. When the variables become instantiated later, execution will be resumed
automatically, and the instantiations will be checked for satisfying the constraint.
14.4.2
Forward Checking
For Forward Checking, we will assume that we have interval domain variables, as provided by
the ic library (without domain variables, there would not be much interesting propagation to
be done).
Here is one implementation of a forward checking version:
:- lib(ic).
delay capacity(T, N) if var(T), var(N).
capacity(T, N) :- nonvar(N), !,
N >= 0,
( N =< 50.0 -> T :: [1,2,3]
; N =< 180.0 -> T :: [1,2]
; N =< 350.0 -> T = 1
; fail
).
152