Prolog中的元解释逻辑剪切(已编辑以容纳注释)

时间:2019-06-21 20:16:03

标签: prolog prolog-cut

我正在Sicstus Prolog中实现一个几何定理证明者;为了克服I / O的回溯问题,我使用了元解释器。但是,这后一个似乎无法像预期的那样处理切割。

我的元解释器如下所示。 solve/5的第一个参数是要评估的目标,第二个和第三个参数使我可以控制搜索深度,第四个和第五个参数用于处理输出的回溯。

solve(true,_,_, O, O) :- 
        !.
solve(_,CurrentDepth,DepthLimit, _, _) :- 
        CurrentDepth > DepthLimit, 
        !, 
        fail.
solve(nl,_,_, O, [nl|O]):- !.
solve(write(X),_,_, O, [X|O]):- !.
solve((A,B),CurrentDepth,DepthLimit, O0, O2) :- 
        !, 
        solve(A,CurrentDepth,DepthLimit, O0, O1),
        solve(B,CurrentDepth,DepthLimit, O1, O2).
solve((A;B),CurrentDepth,DepthLimit, O0, O2) :- 
        !, 
        (
                (solve(A,CurrentDepth,DepthLimit, O0, O2); 
                solve(B,CurrentDepth,DepthLimit, O0, O2))
        ).

solve(A,_,_, O, O) :-
        (
                predicate_property(A, built_in);
                predicate_property(A, imported_from(lists))
        ),
        !,
        call(A).
solve(Goal,CurrentDepth,DepthLimit, O0, O1) :-  
        !,        
        predicate_property(Goal, interpreted),!,        
        NewDepth is CurrentDepth+1,!,        
        clause(Goal,SubGoals),
        solve(SubGoals,NewDepth,DepthLimit, O0, O1).

我已按照线程Implementing cut in tracing meta interpreter prolog中的说明进行操作 并将元解释器更改为以下内容。

solve(true,_,_, O, O) :- 
        !.
solve(_,CurrentDepth,DepthLimit, _, _) :- 
        CurrentDepth > DepthLimit, 
        !, 
        fail.
solve(nl,_,_, O, [nl|O]):- !.
solve(write(X),_,_, O, [X|O]):- !.
solve(!, _,_,_,_):- !, ( true ; throw(cut)).
solve((A,B),CurrentDepth,DepthLimit, O0, O2) :- 
        !, 
        solve(A,CurrentDepth,DepthLimit, O0, O1),
        solve(B,CurrentDepth,DepthLimit, O1, O2).
solve((A;B),CurrentDepth,DepthLimit, O0, O2) :- 
        !, 
        (
                (solve(A,CurrentDepth,DepthLimit, O0, O2); 
                solve(B,CurrentDepth,DepthLimit, O0, O2))
        ).
solve(A,_,_, O, O) :-
        (
                predicate_property(A, built_in);
                predicate_property(A, imported_from(lists))
        ),
        !,
        call(A).
solve(Goal,CurrentDepth,DepthLimit, O0, O1) :-  
        !,        
        predicate_property(Goal, interpreted),!,        
        NewDepth is CurrentDepth+1,!,        
        clause(Goal,SubGoals),
        catch(
                (       
                        solve(SubGoals,NewDepth,DepthLimit, O0, O1)
                ),
                cut,
                fail
        ).

但是现在,solve/5对于输入定理证明者的某些问题失败了。值得注意的是,在我的定理证明者中,我没有任何谓词call/1catch/3throw/1。下面是一个示例问题。

:- dynamic test_goal/2.
:- dynamic predicate_with_small_depth/2.
:- dynamic predicate_with_large_depth/2.
:- dynamic p_1/2.
:- dynamic p_2/2.
:- dynamic p_3/2.
:- dynamic p_4/2.
:- dynamic p_5/2.

test_goal(X,Y):-
        predicate_with_small_depth(X,Y),!,
        predicate_with_large_depth(X,Y).

predicate_with_small_depth(X,Y):-
        X < Y,
        write('Small Depth Outcome 1'), nl.

predicate_with_small_depth(X,Y):-
        X > Y,
        write('Small Depth Outcome 2'), nl.

predicate_with_large_depth(X,Y):-
        p_1(X,Y).

p_1(X,Y):- p_2(X,Y).

p_2(X,Y):- p_3(X,Y).

p_3(X,Y):- p_4(X,Y).

p_4(X,Y):- p_5(X,Y).

p_5(X,Y):-    
        predicate_with_small_depth(X,Y),!,    
        write('Large Depth Outcome: '), write(X), write(' '), write(Y), nl.

如果评估了目标solve(test_goal(1,2),0,8,O1,O2),则使用修改后的元解释器的Prolog答案是:

O2 = [nl,2,' ',1,'Large Depth Outcome: '|_A] ?

但答案应该是

O2 = [nl,2,' ',1,'Large Depth Outcome: ',nl,'Small Depth Outcome 1',nl,'Small Depth Outcome 1'|O1] ?

这是我的元解释器在添加cut适应之前给出的一个。

在处理cut运算符方面,新的元解释器实现看起来正确吗?

非常感谢。


编辑

在尝试确定问题集和解决以下问题的方法时,显而易见的是:

  1.   

    TGTP包含了我的程序要解决的问题

  2. Geometric Theorem Proving,作者:佩德罗·夸雷斯玛(Pedro Quaresma),《 2012年逻辑学日》,埃武拉大学,2012年2月6日至8日

    (Gelernter的作品)最好地记录了我的程序。

    狡猾:27/99

enter image description here

和28/99

enter image description here

  

剪切对我来说是必要的,因为它允许程序停止工作   一旦找到一个解决方案,就可以解决给定目标的其他解决方案。   例如,如果我有

prove(X):-(p1(X),!);(p2(X),!);p3(X), if p1(X) is satisfiable, 
  

我不希望通过p2 / 1和p3 / 1的其他解决方案   找到了。这样可以节省大量计算。

1 个答案:

答案 0 :(得分:1)

剪切子句不正确。 cut子句应以与true子句相同的方式记录写入的数据。我想你想要

solve(!, _,_,O,O):- !, ( true ; throw(cut)).