检测是否证明谓词统一了什么

时间:2016-04-18 18:04:38

标签: prolog unification

我有一个可以统一其论点的谓词,例如:

foo(X) :- X = 42.

如何在证明foo(X)时,统一是否改变了X?例如,我想知道writeln(X), foo(X), writeln(X)是否会为X打印两次相同的值,而不会实际打印。

foo/1的实际实施实际上要复杂得多,所以请不要特别针对上面的简化版本提出建议。在我的计划中,foo(X)使用统一简化了X,但foo(X)可能需要多次验证,直到执行所有简化为止。我希望能够编写一个foohelper(X)谓词来调用foo(X),直到X停止统一。

2 个答案:

答案 0 :(得分:3)

假设我们只有句法统一 - 即没有约束:

:- meta_predicate(call_instantiated(0,?)).

call_instantiated(Goal_0, Instantiated) :-
    copy_term(Goal_0, Copy_0),
    Goal_0,
    (  subsumes_term(Goal_0, Copy_0) ->  % succeeds iff equal u.t.r.
       Instantiated = false
    ;  Instantiated = true
    ).

请注意,Goal_0将会或不会被进一步实例化。上述subsumes_term/2测试Goal_0现在是否比Copy_0更“一般”。当然,它不能更通用,如此有效,测试测试这些术语是否与变量重命名相同。

与使用term_variables/2相比,正如@PauloMoura指出的那样,这可能更有效。它主要取决于subsumes_term/2的效率。

答案 1 :(得分:2)

也许您可以使用标准term_variables/2谓词?您可以在调用目标之前和之后使用您的目标调用它,并检查返回的变量列表是否不同。类似的东西:

...,
term_variables(foo(X), Vars0),
foo(X),
term_variables(foo(X), Vars),
(  Vars0 == Vars ->
   write(simplified)
;  write(not_simplified)
),
...