ADDED: CLP(B): project_attributes/2. Ready for toplevel integration.
ADDED: CLP(B): project_attributes/2. Ready for toplevel integration.

This is for compatibility with SICStus Prolog, please see their
documentation for more information. In short, project_attributes/2
lets us get rid of residual constraints and variables that are of no
interest for the query at hand. It is called as:

   project_attributes(+QueryVars, +AttrVars)

where QueryVars is the list of variables that occur in the query, and
AttrVars is a list of (possibly attributed) variables created while
solving the query. QueryVars and AttrVars may or may not be disjoint.

Ideally, project_attributes/2 expresses all occurring constraints in
terms of QueryVars.

To see how useful this is, consider again the xor/3 example from Ulf
Nilsson's excellent lecture slides:

   :- use_module(library(clpb)).

   n_mos(S,G,D) :- sat(S*G =:= D*G).

   p_mos(S,G,D) :- sat(S* ~G =:= D* ~G).

   xor(X, Y, Z) :-
           p_mos(Tmp, 1, X),
           n_mos(0, Tmp, X),
           p_mos(Z, X, Y),
           n_mos(Z, Tmp, Y),
           n_mos(Z, Y, Tmp),
           p_mos(Z, Y, X).

Currently, we have:

   ?- xor(X, Y, Z).
   %@ sat(X=:=X),
   %@ sat(1#X#X*Y*Z#X*Y*Z*_G405#X*Y*_G405#X*Z*_G405#Y#Y*Z#Y*Z*_G405#Z),
   %@ sat(_G405=:=_G405),
   %@ sat(Z=:=Z),
   %@ sat(Y=:=Y).

As you see, a new variable has appeared, making the residual
constraints very hard to understand. We only care about X, Y, and Z,
and any other Boolean variable can have either value as long as all
constraints are still satisfiable. Completeness of CLP(B) ensures that
this is the case here, so additional variables can be existentially
quantified without changing the satisfiability of the residual goals.

With project_attributes/2, we can easily project all constraints onto
variables that actually occur in the query:

   ?- xor(X, Y, Z), clpb:project_attributes([X,Y,Z], []).
   %@ sat(X=:=X),
   %@ sat(1#X#Y#Z),
   %@ sat(_G401=:=_G401),
   %@ sat(Z=:=Z),
   %@ sat(Y=:=Y).

One last artificial variable remains. We can easily access all
variables that have attributes attached with call_residue_vars/2, and
use this as the second argument for project_attributes/2. This allows
us to get rid of all constraints that are not relevant in this case:

   ?- call_residue_vars(xor(X,Y,Z), AttrVars),
      clpb:project_attributes([X,Y,Z], AttrVars).
   %@ AttrVars = [X, Y, Z, _G405, _G408],
   %@ sat(X=:=X),
   %@ sat(1#X#Y#Z),
   %@ sat(Z=:=Z),
   %@ sat(Y=:=Y).

This is the mechanism that the Prolog toplevel should use to
automatically project constraints to the variables of interest.

jn7163/swipl-devel,jn7163/swipl-devel,jn7163/swipl-devel,koryonik/swipl-devel,mndrix/swipl-devel,edechter/swipl-devel,jn7163/swipl-devel,mndrix/swipl-devel,jn7163/swipl-devel,edechter/swipl-devel,koryonik/swipl-devel,koryonik/swipl-devel,koryonik/swipl-devel,edechter/swipl-devel,edechter/swipl-devel,mndrix/swipl-devel,edechter/swipl-devel,koryonik/swipl-devel,mndrix/swipl-devel,mndrix/swipl-devel