有没有办法将制表符和子句结合起来?

时间:2019-04-17 13:47:13

标签: prolog

在我的程序中,我使用一个简单的递归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)=af(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 等。

1 个答案:

答案 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系统,可能会有其他反射谓词,使您可以过滤应追踪的内容。例如。仅在白名单文件中定义的谓词。