我正在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/1
,catch/3
或throw/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运算符方面,新的元解释器实现看起来正确吗?
非常感谢。
编辑
在尝试确定问题集和解决以下问题的方法时,显而易见的是:
TGTP包含了我的程序要解决的问题
Geometric Theorem Proving,作者:佩德罗·夸雷斯玛(Pedro Quaresma),《 2012年逻辑学日》,埃武拉大学,2012年2月6日至8日
(Gelernter的作品)最好地记录了我的程序。
狡猾:27/99
和28/99
也
剪切对我来说是必要的,因为它允许程序停止工作 一旦找到一个解决方案,就可以解决给定目标的其他解决方案。 例如,如果我有
prove(X):-(p1(X),!);(p2(X),!);p3(X), if p1(X) is satisfiable,
我不希望通过p2 / 1和p3 / 1的其他解决方案 找到了。这样可以节省大量计算。
答案 0 :(得分:1)
剪切子句不正确。 cut子句应以与true
子句相同的方式记录写入的数据。我想你想要
solve(!, _,_,O,O):- !, ( true ; throw(cut)).