/* PROCEDURES THAT IMPLEMENT TASKS FOR BINDING VARIABLES IN EXPRESSIONS */

/* A "bind" task is represented using the following predicate:
		bind(priority,expression,var_index,last_bound)
   priority is the integer priority of the task
   expression is the current expression.  Remaining variables are
      represented by the atom "var" in the expression.
   var_index is an integer -- the number of the next variable in the original
      expression that is being bound in this task
   last_bound is another integer, which indicates the last thing bound to
      the next occurence of "var".  This is used to decide which constant
      or unknown to substitute for "var". */


/* ACCESS TO PARTS */

priority( bind(P,_,_,_), P).



/* PROCEDURE FOR PERFORMING THE "BIND" TASK */

do( bind(Priority,Expr,Var_Index,Last_Bound) ) :-
   I is Last_Bound+1,
   (I>2 -> P1 is 1 ; P1 is 3),
   constant(I,Var_Index,C),
   /* if the following "subst_first" fails, then there are no
      more occurences of "var" */
   subst_first(var,C,Expr,New_Expr),
   /* Success -- insert two new tasks in the agenda:
      one is a new "bind" task with the new value substituted
      for "var"; the other is another "bind" task with
      an incremented value for Last_Bound */
   V1 is Var_Index+1,
   add_task( bind(P1,New_Expr,V1,0) ),
   add_task( bind(P1,Expr,Var_Index,I) ),
   !.

do( bind(Priority,Expr,_,_) ) :-
   /* there are no more variables to be bound -- add a
      "check_gap" task to the agenda */
   P1 is Priority+1,
   add_task( check_gap(P1,Expr) ),
   !.
