Matthew, > suspend(C is A+B, 1, A->inst), > > will suspend until A is instantiated, is it possible to suspend until > several variables are instantiated (for example both A and B) as this > is required for certain constraints? > > suspend(C is A+B, 1, [A->inst, B->inst]), > > and > > suspend(C is A+B, 1, [A, B]->inst), > > both seem to suspend until either A or B are instantiated, resulting > in an instantiation fault in some cases. > > Thanks, > Matthew You cannot specify that a suspended predicate wakes only when both variables become instantiated, in the way that you want. You need to define your own predicate that wakes if either variable becomes instantiated but immediately resuspends itself if the other is not. This is discussed in detail in the Advanced Control Features section of the User Manual, but I'll outline briefly what is needed. In this case, you need to do define your own predicate, let's call it my_plus/3, and suspend it pending instantiation of the variables as you did above. Now, when my_plus/3 is woken on instantiation of either A or B, the first thing it should do is check whether both are now instantiated. If they are it will succeed with C being unified with the result; if not it will resuspend itself until the remaining variable is instantiated: Version 5.8 #82, Wed Feb 16 00:08 2005 [eclipse 1]: [user]. my_plus(A,B,C) :- ( var(A) -> % B must have been instantiated to cause this waking suspend(my_plus(A, B, C), 1, A->inst) ; var(B) -> % A must have been instantiated to cause this waking suspend(my_plus(A, B, C), 1, B->inst) ; C is A + B ). user compiled traceable 536 bytes in 0.00 seconds Yes (0.00s cpu) [eclipse 2]: suspend(my_plus(A, B, C), 1, [A, B]->inst). A = A B = B C = C Delayed goals: my_plus(A, B, C) Yes (0.00s cpu) [eclipse 3]: suspend(my_plus(A, B, C), 1, [A, B]->inst), A = 1. A = 1 B = B C = C Delayed goals: my_plus(1, B, C) Yes (0.00s cpu) [eclipse 4]: suspend(my_plus(A, B, C), 1, [A, B]->inst), A = 1, B = 2. A = 1 B = 2 C = 3 Yes (0.00s cpu) Now, each time the goal my_plus wakes and resuspends itself a new suspension is created. In order to support this type of checking and resuspending the same goal, demon predicates are provided. Essentially, you declare a predicate to be a demon, and whenever a suspension for that goal is woken, it is automatically resuspended. If all the pre-conditions for which the goal is waiting have not been satisfied, nothing needs to be done. When all the pre-conditions have been satisfied and the goal has been executed you normally wish for the suspension to be killed: this must now be done explicitly. In order to do this we need to provide the Suspension as an extra argument to the predicate. So: Version 5.8 #82, Wed Feb 16 00:08 2005 [eclipse 1]: [user]. :- demon my_plus/4. my_plus(A,B,C,Susp) :- ( var(A) -> true ; var(B) -> true ; C is A + B, kill_suspension(Susp) ). user compiled traceable 300 bytes in 0.00 seconds Yes (0.00s cpu) [eclipse 2]: suspend(my_plus(A,B,C,Susp),1,[A,B]->inst,Susp). A = A B = B C = C Susp = 'SUSP-_309-susp' Delayed goals: my_plus(A, B, C, 'SUSP-_309-susp') Yes (0.00s cpu) [eclipse 3]: suspend(my_plus(A,B,C,Susp),1,[A,B]->inst,Susp), A = 1. A = 1 B = B C = C Susp = 'SUSP-_337-susp' Delayed goals: my_plus(1, B, C, 'SUSP-_337-susp') Yes (0.00s cpu) [eclipse 4]: suspend(my_plus(A,B,C,Susp),1,[A,B]->inst,Susp), A = 1, B = 2. A = 1 B = 2 C = 3 Susp = 'SUSP-_365-dead' Yes (0.00s cpu) -- Andrew Eremin Research Associate Tel: +44 (0)20 7594 8446 IC-Parc, Imperial College London Fax: +44 (0)20 7594 8432 London SW7 2AZ Email: a.eremin@icparc.imperial.ac.ukReceived on Tue Sep 06 19:55:00 2005
This archive was generated by hypermail 2.1.8 : Wed 16 Nov 2005 06:07:39 PM GMT GMT