This is simply a bug in CLPR, which is unsupported. We lost touch with the CLPR supplier a long time ago.
How do I reinstate constraints collected with copy_term/3 in SICStus Prolog?
-
01-07-2022 - |
Question
The documentation says that
copy_term(+Term, -Copy, -Body)
makes a copy ofTerm
in which all variables have been replaced by new variables that occur nowhere outside the newly created term. IfTerm
contains attributed variables,Body
is unified with a term such that executingBody
will reinstate equivalent attributes on the variables inCopy
.
I'm previously affirming numerical CLP(R) constraints over some variables, and at some point I collect these constraints using copy_term/3. Later, when I try to reinstate the constraints using 'call(Body)', I get an "Instantiation error" in arguments of the form [nfr:resubmit_eq(...)]
Here's a simplified example that demonstrates the problem:
:-use_module(library(clpr)).
{Old>=0, A>=0,A=<10, NR= Old+Z, Z=Old*(A/D)}, copy_term(Old,New,CTR), call(CTR).
Results in:
Instantiation error in argument 1 of '.'/2
! goal: [nfr:resubmit_eq([v(-1.0,[_90^ -1,_95^1,_100^1]),v(1.0,[_113^1])])]
My question is: how do I reinstate the constraints in Body
over New
? I haven't been able to find concrete examples.
Solution 2
OTHER TIPS
copy_term/3
is a relatively new built-in predicate, that has been first introduced in SICStus about 2006. Its motivation was to replace the semantically cumbersome call_residue/2
which originated from SICStus 0.6 of 1987 by a cleaner and more efficient interface that splits the functionality in two:
call_residue_vars(Goal, Vars)
which is like call(Goal)
and upon success unifies Vars
with a list variables (in unspecified order) that are attached to constraints and have been created or affected in Goal
.
copy_term(Term, Copy, Body)
like copy_term/2
and upon success unifies Body
with a term to reinstate the actual constraints involved. Originally, Body
was a goal that could be executed directly. Many systems that adopted this interface (like SWI, YAP) however, switched to use a list of goals instead. This simplifies frequent operations since you have less defaultyness, but at the expense of making reinstating more complex. You need to use maplist(call,Goals)
.
Most of the time, these two built-in predicates will be used together. You are using only one which makes me a bit suspicious. You first need to figure out which variables are involved, and only then you can copy them. Typically you will use call_residue_vars/2
for that. If you are copying only a couple of variables (as in your exemple) you are effectively projecting the constraints on these variables. This may or may not be your intention.