我有一个可以统一其论点的谓词,例如:
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
停止统一。
答案 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)
),
...