如何在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)
likecopy_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])])]