如何在SICStus Prolog中恢复使用copy_term/3收集的约束?

如何在SICStus Prolog中恢复使用copy_term/3收集的约束?,prolog,sicstus-prolog,constraint-programming,clpfd,Prolog,Sicstus Prolog,Constraint Programming,Clpfd,文件上说 copy\u term(+term,-copy,-Body)复制term中的所有 变量已被不存在的新变量替换 在新创建的术语之外。如果术语包含属性 变量,Body与一个术语统一,以便执行Body 将恢复Copy中变量的等效属性 我之前肯定了一些变量上的数值CLP(R)约束,在某个时刻,我使用copy_term/3收集这些约束。稍后,当我尝试使用“call(Body)”恢复约束时,我在参数中得到了一个“实例化错误”,其形式为[nfr:resubmit_eq(…)] 下面是一个简化的示例,

文件上说

copy\u term(+term,-copy,-Body)
复制
term
中的所有 变量已被不存在的新变量替换 在新创建的术语之外。如果
术语
包含属性
变量,
Body
与一个术语统一,以便执行
Body
将恢复
Copy
中变量的等效属性

我之前肯定了一些变量上的数值CLP(R)约束,在某个时刻,我使用copy_term/3收集这些约束。稍后,当我尝试使用“call(Body)”恢复约束时,我在参数中得到了一个“实例化错误”,其形式为
[nfr:resubmit_eq(…)]

下面是一个简化的示例,演示了该问题:

:-use_module(library(clpr)).
{Old>=0, A>=0,A=<10, NR= Old+Z, Z=Old*(A/D)}, copy_term(Old,New,CTR), call(CTR).

我的问题是:如何在
New
上恢复
Body
中的约束?我还没有找到具体的例子。

copy\u term/3
是一个相对较新的内置谓词,大约在2006年左右在SICStus中首次引入。它的动机是用一个更干净、更高效的界面来取代语义上麻烦的
call_residence/2
,该界面起源于1987年的SICStus 0.6,将功能分为两部分:

call\u residence\u vars(Goal,vars)
类似于
call(Goal)
,成功后将
vars
与附加到约束的列表变量(未指定顺序)统一起来,这些变量已在
Goal
中创建或影响

copy_term(term,copy,Body)
like
copy_term/2
成功后,将
Body
与一个术语统一起来,以恢复所涉及的实际约束。最初,
Body
是一个可以直接执行的目标。然而,许多采用此接口的系统(如SWI、YAP)转而使用目标列表。这简化了频繁的操作,因为默认情况较少,但代价是使恢复更加复杂。您需要使用
地图列表(呼叫、目标)


大多数情况下,这两个内置谓词将一起使用。你只使用了一个,这让我有点怀疑。您首先需要弄清楚涉及哪些变量,然后才能复制它们。通常,您将使用
call\u residence\u vars/2
进行此操作。如果您只复制了几个变量(如您的示例中所示),则实际上是在投射这些变量上的约束。这可能是您的意图,也可能不是您的意图。

这只是CLPR中的一个错误,不受支持。我们很久以前就与CLPR供应商失去了联系。

@j4nbur53:我想说:无害。重要的是,如果没有剩余内容,则会给出
[]
。是。如果您查看call_residence/2的实现(仍在YAP中),您将看到大量复制仍在进行。但至少这个“新”接口(10年前)的成本更低,并且与旧接口相比保持了一定的一致性。这里的接口是大约20年在SICStus约束方面经验的结果。在此之前,
library(clpfd)
有很多问题。类似地,对于延迟的目标,由您来更有效地实施
copy\u term(X,X,C)
。同样地,
copy_term(G+V,G+L)
也可以以更有效的方式实现。这完全取决于你。
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])])]