检测是否证明谓词统一了某些东西
Detecting whether proving a predicate unified something
我有一个谓词可以统一其参数,例如:
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
停止统一。
也许你可以使用标准的 term_variables/2
谓词?您可以在调用目标之前和之后用您的目标调用它,并检查返回的变量列表是否不同。类似于:
...,
term_variables(foo(X), Vars0),
foo(X),
term_variables(foo(X), Vars),
( Vars0 == Vars ->
write(simplified)
; write(not_simplified)
),
...
假设我们只有句法统一——即没有约束:
:- 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
现在是否 "more general" 而不是 Copy_0
。当然,它不能更通用,如此有效以至于 test 测试术语是否相同直到重命名变量。
与使用 term_variables/2
相比,正如@PauloMoura 所指出的,这可能效率更高。主要看subsumes_term/2
.
的效率
我有一个谓词可以统一其参数,例如:
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
停止统一。
也许你可以使用标准的 term_variables/2
谓词?您可以在调用目标之前和之后用您的目标调用它,并检查返回的变量列表是否不同。类似于:
...,
term_variables(foo(X), Vars0),
foo(X),
term_variables(foo(X), Vars),
( Vars0 == Vars ->
write(simplified)
; write(not_simplified)
),
...
假设我们只有句法统一——即没有约束:
:- 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
现在是否 "more general" 而不是 Copy_0
。当然,它不能更通用,如此有效以至于 test 测试术语是否相同直到重命名变量。
与使用 term_variables/2
相比,正如@PauloMoura 所指出的,这可能效率更高。主要看subsumes_term/2
.