简体   繁体   English

SICStus Prolog 4.7.1 中的虚假 attribute_goal/2

[英]Spurious attribute_goal/2 in SICStus Prolog 4.7.1

Given the following minimalistic "solver" in SICStus Prolog...鉴于 SICStus Prolog 中的以下简约“求解器”...

:- module(attach, [attach/1]).
:- use_module(library(atts)).
:- attribute a/0.

attach(X) :- put_atts(X,a).

verify_attribute(_,_,[]).

attribute_goal(V,attach(V)) :- get_atts(V,a), put_atts(V,-a).

... I observe: ...我观察到:

| ?- attach(X), copy_term(X,Xc,Xcc), copy_term(X,Yc,Ycc).
Xcc = attach:attach(Xc),
Ycc = true ? 

Where has the residual goal gone?!残留的目标去哪了?!

Wasn't the put_atts/2 in attribute_goal/2 undone ? attribute_goal/2 put_atts/2不是撤消了吗?


Edit.编辑。 This previous answer (of a somewhat related question) hints at a similar issues when using the builtin predicate when/2 . This previous answer (of a somewhat related question) hints at a similar issues when using the builtin predicate when/2

No, the side effects (the put_atts(V, -a) that removes the attribute) of your attribute_goal/2 will not be undone by copy_term/3 (or frozen/2 et al.) and I do not think there is anything in the SICStus documentation that suggests that it would be.不,您的attribute_goal/2的副作用(删除属性的put_atts(V, -a) )不会被copy_term/3 (或frozen/2等)取消,我认为没有任何东西SICStus 文档表明它会是。

A simplified version of copy_term/3 , that only handles variables, would look something like: copy_term/3的简化版本,只处理变量,看起来像:

my_copy_term(Var, Copy, Goal) :-
        (   attribute_goal(Var, VarGoal) ->
            true
        ;   VarGoal = true
        ),
        copy_term(Var-VarGoal, VarCopy-VarGoalCopy),
        Copy = VarCopy,
        Goal = VarGoalCopy.

So, if attribute_goal/2 removes an attribute, like in your example, the attribute will still be absent when ( my_ ) copy_term/3 succeeds.因此,如果attribute_goal/2删除了一个属性,就像在您的示例中一样,当 ( my_ ) copy_term/3成功时,该属性仍然不存在。

The effect of put_atts/2 will be undone on backtracking, as can be seen in the following two examples, where the first is your example, the second is the same but backtracking over the copy_term/3 before the second copy_term/ 3 is invoked. put_atts/2的效果将在回溯时取消,如以下两个示例所示,第一个是您的示例,第二个是相同的,但在调用第二个copy_term/ copy_term/3之前回溯 copy_term/3 。

| ?- attach(X), copy_term(X,Xc,Xcc), copy_term(X,Yc,Ycc).
Xcc = attach:attach(Xc),
Ycc = true ? 
yes
% zip,source_info
| ?- attach(X), (copy_term(X,Xc,Xcc); copy_term(X,Yc,Ycc)).
Xcc = attach:attach(Xc) ? ;
Ycc = attach:attach(Yc) ? ;
no

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM