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