在我的程序中,我使用一个简单的递归clause/2
来跟踪我的证明。
prove(X):-
clause(X, B),
B == true.
prove((X1, X2)):-
prove(X1),
prove(X2).
prove(X):-
X \= true,
X \= (_, _),
clause(X, B),
write(X), write(' <= '), write(B), nl,
prove(B).
此外,我正在尝试使用tabling
解决可交换性/传递性问题。 (我在谈论f(a)=b <=> f(b)=a
,f(a)=b, f(b)=c => f(a)=c
等)。
我知道使用transistive闭包或修饰的谓词可以帮助解决此问题。但是,我正在制定许多规则。如果我对每组规则都做同样的事情,那对我来说将是一个巨大的工作量,并且确实会造成许多错误。
但是,首先clause
会追溯到start_tabling
。
[1] ?- prove(segment_equal(c,d,a,b)).
segment_equal(c,d,a,b) <= start_tabling(user:segment_equal(c,d,a,b),segment_equal tabled(c,d,a,b))
其次,它将引发错误。
ERROR: No permission to access private_procedure `'$tbl_variant_table'/3'
所以我想知道是否可以使用tabling
来保存代码并同时跟踪过程?还是其他更好的做法?
PS:如果背景有帮助,我正在研究几何自动定理证明器,众所周知,那些基本规则出现在许多定理中,例如 segment equal , angle equal 等。
答案 0 :(得分:0)
一个可能的解决方案是使用predicate_property/2
谓词来排除不应跟踪的谓词。例如,以下元解释器将仅跟踪对动态谓词的调用:
prove(X) :-
clause(X, B),
B == true.
prove((X1, X2)) :-
prove(X1),
prove(X2).
prove(X) :-
clause(X, B),
( predicate_property(B, dynamic) ->
write(X), write(' <= '), write(B), nl
; true
),
prove(B).
根据所使用的Prolog系统,可能会有其他反射谓词,使您可以过滤应追踪的内容。例如。仅在白名单文件中定义的谓词。