2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/*************************************************************************
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								*									 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								*	 YAP Prolog 							 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								*									 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								*	Yap Prolog was developed at NCCUP - Universidade do Porto	 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								*									 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997	 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								*									 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								**************************************************************************
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								*									 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								* File:		corout.pl						 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								* Last rev:								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								* mods:									 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								* comments:	Coroutines implementation				 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								*									 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								*************************************************************************/
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 22:41:30 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								:- module('$coroutining',[
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											  op(1150, fx, block)
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												%dif/2,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												%when/2,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												%block/1,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												%wait/1,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												%frozen/2
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 22:41:30 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											 ]).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								attr_unify_hook(DelayList, _) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									wake_delays(DelayList).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								wake_delays([]).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								wake_delays(Delay.List) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									wake_delay(Delay),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									wake_delays(List).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Interface to attributed variables.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								wake_delay(redo_dif(Done, X, Y)) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									redo_dif(Done, X, Y).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								wake_delay(redo_freeze(Done, V, Goal)) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									redo_freeze(Done, V, Goal).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								wake_delay(redo_eq(Done, X, Y, Goal)) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									redo_eq(Done, X, Y, Goal, G).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								wake_delay(redo_ground(Done, X, Goal)) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									redo_ground(Done, X, Goal).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								attribute_goals(Var) -->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ get_attr(Var, '$coroutining', Delays) },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									attgoal_for_delays(Delays, Var).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								attgoal_for_delays([], V) --> [].
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								attgoal_for_delays([G|AllAtts], V) -->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									attgoal_for_delay(G, V),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									attgoal_for_delays(AllAtts, V).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								attgoal_for_delay(redo_dif(Done, X, Y), V) --> { var(Done), first_att(dif(X,Y), V) }, !, [prolog:dif(X,Y)].
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								attgoal_for_delay(redo_freeze(Done, V, Goal), V) --> { var(Done) },  !, [prolog:freeze(V,Goal)].
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								attgoal_for_delay(redo_eq(Done, X, Y, Goal), V) --> { var(Done), first_att(Goal, V) }, !, [prolog:when(X=Y,Goal)].
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								attgoal_for_delay(redo_ground(Done, X, Goal), V) --> { var(Done) },  !, [prolog:when(ground(X),Goal)].
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								attgoal_for_delay(_, V) --> [].
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												%
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% operators defined in this module:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								prolog:freeze(V, G) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									var(V), !,
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									freeze_goal(V,G).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								prolog:freeze(_, G) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$execute'(G).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								freeze_goal(V,VG) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									var(VG), !,
							 | 
						
					
						
							
								
									
										
										
										
											2001-06-06 19:10:51 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									'$current_module'(M),
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									internal_freeze(V, redo_freeze(_Done,V,M:VG)).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								freeze_goal(V,M:G) :- !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									internal_freeze(V, redo_freeze(_Done,V,M:G)).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								freeze_goal(V,G) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-06-06 19:10:51 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									'$current_module'(M),
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									internal_freeze(V, redo_freeze(_Done,V,M:G)).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Dif is tricky because we need to wake up on the two variables being
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% bound together, or on any variable of the term being bound to
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% another. Also, the day YAP fully supports infinite rational trees,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% dif should work for them too. Hence, term comparison should not be
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% implemented in Prolog.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% This is the way dif works. The '$can_unify' predicate does not know
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% anything about dif semantics, it just compares two terms for
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% equaility and is based on compare. If it succeeds without generating
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% a list of variables, the terms are equal and dif fails. If it fails,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% dif succeeds.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% If it succeeds but it creates a list of variables, dif creates
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% suspension records for all these variables on the '$redo_dif'(V,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% X, Y) goal. V is a flag that says whether dif has completed or not,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% X and Y are the original goals. Whenever one of these variables is
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% bound, it calls '$redo_dif' again. '$redo_dif' will then check whether V
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% was bound. If it was, dif has succeeded and redo_dif just
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% exits. Otherwise, '$redo_dif' will call dif again to see what happened.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Dif needs two extensions from the suspension engine:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% First, it needs
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% for the engine to be careful when binding two suspended
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% variables. Basically, in this case the engine must be sure to wake
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% up one of the goals, as they may make dif fail. The way the engine
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% does so is by searching the list of suspended variables, and search
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% whether they share a common suspended goal. If they do, that
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% suspended goal is added to the WokenList.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Second, thanks to dif we may try to suspend on the same variable
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% several times. dif calls a special version of freeze that checks
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% whether that is in fact the case.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								prolog:dif(X, Y) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$can_unify'(X, Y, LVars), !,
							 | 
						
					
						
							
								
									
										
										
										
											2003-10-17 02:11:21 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									LVars = [_|_], 
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									dif_suspend_on_lvars(LVars, redo_dif(_Done, X, Y)).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								prolog:dif(_, _).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								dif_suspend_on_lvars([], _).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								dif_suspend_on_lvars([H|T], G) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									internal_freeze(H, G),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									dif_suspend_on_lvars(T, G).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% This predicate is called whenever a variable dif was suspended on is
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% bound. Note that dif may have already executed successfully.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Three possible cases: dif has executed and Done is bound; we redo
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% dif and the two terms either unify, hence we fail, or may unify, and
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% we try to increase the number of suspensions; last, the two terms
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% did not unify, we are done, so we succeed and bind the Done variable.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								redo_dif(Done, _, _) :- nonvar(Done), !.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								redo_dif(Done, X, Y) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$can_unify'(X, Y, LVars), !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									LVars = [_|_],
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									dif_suspend_on_lvars(LVars, redo_dif(Done, X, Y)).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								redo_dif('$done', _, _).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% If you called nonvar as condition for when, then you may find yourself
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% here.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% someone else (that is Cond had ;) did the work, do nothing
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								redo_freeze(Done, _, _) :- nonvar(Done), !.
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% We still have some more conditions: continue the analysis.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								redo_freeze(Done, _, '$when'(C, G, Done)) :- !,
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$when'(C, G, Done).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									
							 | 
						
					
						
							
								
									
										
										
										
											2004-09-07 21:08:30 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% check if the variable was really bound
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								redo_freeze(Done, V, G) :- var(V), !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									internal_freeze(V, redo_freeze(Done,V,G)).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% I can't believe it: we're done and can actually execute our
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% goal. Notice we have to say we are done, otherwise someone else in
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% the disjunction might decide to wake up the goal themselves.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								redo_freeze('$done', _, G) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$execute'(G).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% eq is a combination of dif and freeze
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								redo_eq(Done, _, _, _, _) :- nonvar(Done), !.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								redo_eq(_, X, Y, _, G) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$can_unify'(X, Y, LVars),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									LVars = [_|_], !,
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									dif_suspend_on_lvars(LVars, G).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								redo_eq(Done, _, _, when(C, G, Done), _) :- !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									when(C, G, Done).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								redo_eq('$done', _ ,_ , Goal, _) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$execute'(Goal).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% ground is similar to freeze
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								redo_ground(Done, _, _) :- nonvar(Done), !.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								redo_ground(Done, X, Goal) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$non_ground'(X, Var), !,
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									internal_freeze(Var, redo_ground(Done, X, Goal)).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								redo_ground(Done, _, when(C, G, Done)) :- !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									when(C, G, Done).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								redo_ground('$done', _, Goal) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$execute'(Goal).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% support for when/2 built-in
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								prolog:when(Conds,Goal) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-06-06 19:10:51 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									'$current_module'(Mod),
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									prepare_goal_for_when(Goal, Mod, ModG),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									when(Conds, ModG, Done, [], LG), !,
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%write(vsc:freezing(LG,Done)),nl,
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									suspend_when_goals(LG, Done).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								prolog:when(_,Goal) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$execute'(Goal).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% support for when/2 like declaration.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% when will block on a conjunction or disjunction of nonvar, ground,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% ?=, where ?= is both terms being bound together
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								'$declare_when'(Cond, G) :-
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									generate_code_for_when(Cond, G, Code),
							 | 
						
					
						
							
								
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									'$current_module'(Module),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$$compile'(Code, Code, 5, Module), fail.
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								'$declare_when'(_,_).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% use a meta interpreter for now
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								generate_code_for_when(Conds, G,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									( G :- when(Conds, ModG, Done, [], LG), !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									suspend_when_goals(LG, Done)) ) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-06-06 19:10:51 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									'$current_module'(Mod),
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									prepare_goal_for_when(G, Mod, ModG).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% make sure we have module info for G!
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								prepare_goal_for_when(G, Mod, Mod:call(G)) :- var(G), !.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								prepare_goal_for_when(M:G, _,  M:G) :- !.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								prepare_goal_for_when(G, Mod, Mod:G).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% now for the important bit
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Done is used to synchronise: when it is bound someone else did the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% goal and we can give up.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% $when/5 and $when_suspend succeds when there is need to suspend a goal
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								when(V, G, Done, LG0, LGF) :- var(V), !,
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-17 10:58:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									'$do_error'(instantiation_error,when(V,G)).
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								when(nonvar(V), G, Done, LG0, LGF) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									when_suspend(nonvar(V), G, Done, LG0, LGF).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								when(?=(X,Y), G, Done, LG0, LGF) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									when_suspend(?=(X,Y), G, Done, LG0, LGF).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								when(ground(T), G, Done, LG0, LGF) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									when_suspend(ground(T), G, Done, LG0, LGF).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								when((C1, C2), G, Done, LG0, LGF) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									% leave it open to continue with when.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									(
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									    when(C1, when(C2, G, Done), Done, LG0, LGI)
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    LGI = LGF
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    % we solved C1, great, now we just have to solve C2!
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									    when(C2, G, Done, LG0, LGF)
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ).
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								when((G1 ; G2), G, Done, LG0, LGF) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									when(G1, G, Done, LG0, LGI),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									when(G2, G, Done, LGI, LGF).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Auxiliary predicate called from within a conjunction.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Repeat basic code for when,  as inserted in first clause for predicate.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								when(_, _, Done) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									nonvar(Done), !.
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								when(Cond, G, Done) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									when(Cond, G, Done, [], LG),
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									!,
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									suspend_when_goals(LG, Done).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								when(_, G, '$done') :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$execute'(G).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Do something depending on the condition!
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% some one else did the work.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								when_suspend(_, _, Done, _, []) :- nonvar(Done), !.
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% now for the serious stuff.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								when_suspend(nonvar(V), G, Done, LG0, LGF) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									try_freeze(V, G, Done, LG0, LGF).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								when_suspend(?=(X,Y), G, Done, LG0, LGF) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									try_eq(X, Y, G, Done, LG0, LGF).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								when_suspend(ground(X), G, Done, LG0, LGF) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									try_ground(X, G, Done, LG0, LGF).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								try_freeze(V, G, Done, LG0, LGF) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									var(V),
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									LGF = ['$coroutining':internal_freeze(V, redo_freeze(Done, V, G))|LG0].
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								try_eq(X, Y, G, Done, LG0, LGF) :- 
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$can_unify'(X, Y, LVars), LVars = [_|_],
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									LGF = ['$coroutining':dif_suspend_on_lvars(LVars, redo_eq(Done, X, Y, G))|LG0].
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								try_ground(X, G, Done, LG0, LGF) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$non_ground'(X, Var),    % the C predicate that succeds if
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												  % finding out the term is nonground
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												  % and gives the first variable it
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												  % finds. Notice that this predicate
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												  % must know about svars.
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									LGF = ['$coroutining':internal_freeze(Var, redo_ground(Done, X, G))| LG0].
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% When executing a when, if nobody succeeded, we need to create suspensions.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								suspend_when_goals([], _).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								suspend_when_goals(['$coroutining':internal_freeze(V, G)|Ls], Done) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									var(Done), !,
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									internal_freeze(V, G),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									suspend_when_goals(Ls, Done).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								suspend_when_goals([dif_suspend_on_lvars(LVars, G)|LG], Done) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									var(Done), !,
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									dif_suspend_on_lvars(LVars, G),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									suspend_when_goals(LG, Done).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								suspend_when_goals([_|_], _).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Support for wait declarations on goals.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% Or we also use the more powerful, SICStus like, "block" declarations.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% block or wait declarations must precede the first clause.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% I am using the simplest solution now: I'll add an extra clause at
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% the beginning of the procedure to do this work. This creates a
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% choicepoint and make things a bit slower, but it's probably not as
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% significant as the remaining overheads.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								prolog:'$block'(Conds) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									generate_blocking_code(Conds, _, Code),
							 | 
						
					
						
							
								
									
										
										
										
											2002-01-02 16:55:24 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									'$current_module'(Module),
							 | 
						
					
						
							
								
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									'$$compile'(Code, Code, 5, Module), fail.
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								prolog:'$block'(_).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								generate_blocking_code(Conds, G, Code) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$extract_head_for_block'(Conds, G),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$recorded'('$blocking_code','$code'(G,OldConds),R), !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									erase(R),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									functor(G, Na, Ar),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$current_module'(M),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									abolish(M:Na, Ar),
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									generate_blocking_code((Conds,OldConds), G, Code).	
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								generate_blocking_code(Conds, G, (G :- (If, !, when(When, G)))) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									extract_head_for_block(Conds, G),
							 | 
						
					
						
							
								
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									recorda('$blocking_code','$code'(G,Conds),_),
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									generate_body_for_block(Conds, G, If, When).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% find out what we are blocking on.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								extract_head_for_block((C1, _), G) :- !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									extract_head_for_block(C1, G).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								extract_head_for_block(C, G) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									functor(C, Na, Ar),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									functor(G, Na, Ar).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% If we suspend on the conditions, we should continue
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% execution. If we don't suspend we should fail so that we can take
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% the next clause. To
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% know what we have to do we just test how many variables we suspended
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% on ;-).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% We generate code as follows:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% block a(-,-,?) 
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% (var(A1), var(A2) -> true ; fail), !, when((nonvar(A1);nonvar(A2)),G).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% block a(-,-,?), a(?,-, -)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% (var(A1), var(A2) -> true ; (var(A2), var(A3) -> true ; fail)), !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%                   when(((nonvar(A1);nonvar(A2)),(nonvar(A2);nonvar(A3))),G).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								generate_body_for_block((C1, C2), G, (Code1 -> true ; Code2), (WhenConds,OtherWhenConds)) :- !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									generate_for_cond_in_block(C1, G, Code1, WhenConds),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									generate_body_for_block(C2, G, Code2, OtherWhenConds).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								generate_body_for_block(C, G, (Code -> true ; fail), WhenConds) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									generate_for_cond_in_block(C, G, Code, WhenConds).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								generate_for_cond_in_block(C, G, Code, Whens) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									C =.. [_|Args],
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									G =.. [_|GArgs],
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									fetch_out_variables_for_block(Args,GArgs,L0Vars),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									add_blocking_vars(L0Vars, LVars),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									generate_for_each_arg_in_block(LVars, Code, Whens).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								add_blocking_vars([], [_]) :- !.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								add_blocking_vars(LV, LV).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								fetch_out_variables_for_block([], [], []).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fetch_out_variables_for_block(['?'|Args], [_|GArgs], LV) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									fetch_out_variables_for_block(Args, GArgs, LV).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fetch_out_variables_for_block(['-'|Args], [GArg|GArgs],
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									       [GArg|LV]) :-
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									fetch_out_variables_for_block(Args, GArgs, LV).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								generate_for_each_arg_in_block([], false, true).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								generate_for_each_arg_in_block([V], var(V), nonvar(V)) :- !.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								generate_for_each_arg_in_block([V|L], (var(V),If), (nonvar(V);Whens)) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									generate_for_each_arg_in_block(L, If, Whens).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								% The wait declaration is a simpler and more efficient version of block.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								prolog:'$wait'(Na/Ar) :-
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									functor(S, Na, Ar),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									arg(1, S, A),
							 | 
						
					
						
							
								
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									'$current_module'(M),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$$compile'((S :- var(A), !, freeze(A, S)), (S :- var(A), !, freeze(A, S)), 5, M), fail.
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								prolog:'$wait'(_).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								frozen(V, G) :- nonvar(V), !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									'$do_error'(type_error(variable,V),frozen(V,G)).
							 | 
						
					
						
							
								
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								frozen(V, LG) :-
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									'$attributes':get_conj_from_attvars([V], LG).
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-10 14:06:07 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								%internal_freeze(V,G) :-
							 | 
						
					
						
							
								
									
										
										
										
											2004-09-18 14:03:42 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								%	attributes:get_att(V, 0, Gs), write(G+Gs),nl,fail.
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								internal_freeze(V,G) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									update_att(V, G).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								update_att(V, G) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									attributes:get_module_atts(V, '$coroutining'(_,Gs)),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									not_vmember(G, Gs), !,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									attributes:put_module_atts(V, '$coroutining'(_,[G|Gs])).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								update_att(V, G) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									attributes:put_module_atts(V, '$coroutining'(_,[G])).
							 | 
						
					
						
							
								
									
										
										
										
											2005-09-09 17:24:39 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  
							 | 
						
					
						
							
								
									
										
										
										
											2004-09-18 14:03:42 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								not_vmember(_, []).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								not_vmember(V, [V1|DonesSoFar]) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									V \== V1,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									not_vmember(V, DonesSoFar).
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-16 12:00:56 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								first_att(T, V) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									term_variables(T, Vs),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									check_first_attvar(Vs, V).
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-16 12:00:56 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-12 14:26:35 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								check_first_attvar(V.Vs, V0) :- attvar(V), !, V == V0.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								check_first_attvar(_.Vs, V0) :-
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									check_first_attvar(Vs, V0).
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-16 12:00:56 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 |