【问题标题】:Spurious attribute_goal/2 in SICStus Prolog 4.7.1SICStus Prolog 4.7.1 中的虚假 attribute_goal/2
【发布时间】:2022-12-20 04:08:38
【问题描述】:

鉴于 SICStus Prolog 中的以下简约“求解器”......

:- 模块(附加,[附加/1])。
:- use_module(库(atts))。
:- 属性 a/0。

附加(X):- put_atts(X,a)。

验证属性(_,_,[])。

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

...我观察到:

| ?- 附加(X),copy_term(X,Xc,Xcc),copy_term(X,Yc,Ycc)。
Xcc = 附加:附加(Xc),Ycc = 真

残留的目标去哪儿了?!

不是attribute_goal/2中的put_atts/2撤消


编辑。previous answer(有点相关的问题)暗示了使用内置谓词when/2 时的类似问题。

【问题讨论】:

    标签: prolog sicstus-prolog


    【解决方案1】:

    不,attribute_goal/2 的副作用(删除属性的put_atts(V, -a))不会被copy_term/3(或frozen/2 等)消除,我认为SICStus documentation 中没有任何内容这表明它会是。

    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.
    

    因此,如果 attribute_goal/2 删除了一个属性,就像在您的示例中一样,当 (my_)copy_term/3 成功时,该属性仍然不存在。

    put_atts/2 的效果将在回溯时取消,如以下两个示例所示,第一个是您的示例,第二个是相同的,但在调用第二个 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
    

    【讨论】:

    • 所以这意味着attribute_goal/2应该尽其所能保持“纯粹”,以免copy_term/3出现上述异常现象?
    • 是的,它应该只是从属性中读取信息,而不是修改属性(或变量)。
    • 此外,它不应该改变一些其他共享变量(例如,在与 attribute_goal/2 的其他调用的某种协调工作中)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多