自动结果显示?

时间:2014-01-23 16:03:25

标签: prolog backtracking prolog-toplevel

如何让SWI-Prolog解释器自动执行分号? 由于回溯,我有很多结果(大约300个),我不想为所有这些都推分号。

我不想要所有解决方案的列表,我只想不推分号或空格,这样我就可以让程序在背景上打印回溯的解决方案。

4 个答案:

答案 0 :(得分:3)

您可以手动发出解决方案(例如使用write/1format/2),并强制使用false进行回溯以查看所有解决方案。例如:

?- solution(S), writeln(S), false.

此外,例如在SWI-Prolog中,您只需按SPACE而不是;进行进一步的解决方案。

答案 1 :(得分:3)

@repeat不确定这是否符合您的标准,但您不能开发元解释器吗?我不确定是否有办法加载mi以便所有顶级查询都通过它?

类似于:

mi1(true).
mi1((A,B)) :-
 mi1(A),
 mi1(B).
mi1(Goal) :-
 Goal \= true,
 Goal \= (_,_),
 Goal =..List,
 maplist(newvar,List,NewList),
 Goal2 =..NewList,
 clause(Goal2, Body),
 List=[_,T],!,
 findnsols(5,I,(Goal =..[_,I],Goal),T),
 mi1(Body).

newvar(V,V2):-
 var(V).
newvar(V,V):-
 nonvar(V).

%test predicates.
natnum1(0).
natnum1(s(X)) :-
 natnum1(X).

 w(w1).
 w(w2).
 w(w3).
 w(w4).
 w(w5).
 w(w6).
 w(w7).
 w(w8).

查询:

?- mi1(w(X)).
X = [w1, w2, w3, w4, w5] ;
X = [w6, w7, w8] ;
false.

?- mi1(natnum1(X)).
X = [0, s(0), s(s(0)), s(s(s(0))), s(s(s(s(0))))] ;
X = [s(s(s(s(s(0))))), s(s(s(s(s(s(0)))))), s(s(s(s(s(s(s(...))))))), s(s(s(s(s(s(...)))))), s(s(s(s(s(...)))))] ;
X = [s(s(s(s(s(s(s(s(s(...))))))))), s(s(s(s(s(s(s(s(...)))))))), s(s(s(s(s(s(s(...))))))), s(s(s(s(s(s(...)))))), s(s(s(s(s(...)))))] ;
X = [s(s(s(s(s(s(s(s(s(...))))))))), s(s(s(s(s(s(s(s(...)))))))), s(s(s(s(s(s(s(...))))))), s(s(s(s(s(s(...)))))), s(s(s(s(s(...)))))] 
...

只显示基本想法..这仅适用于1个arg谓词..

答案 2 :(得分:3)

这是另一种我认为非常好的方式:

:- op(1200, xfx, all).
:- op(1200, xfx, s5).
:- op(1200, xfx, s10).

all(F,X):-
 F =.. [_|T],
 findall(T, F,X).

s5(F,X):-
 F =.. [_|T],
 findnsols(5,T,F,X).

s10(F,X):-
 F =.. [_|T],
 findnsols(10,T,F,X).

p(1).
p(2).
p(3).
p(4).
p(5).
p(6).
p(7).

nat(0).
nat(s(X)) :- nat(X).
nat_nat_sum(0,X,X).
nat_nat_sum(s(X),Y,s(Z)) :- nat_nat_sum(X,Y,Z).

问:

 ?- nat(X),nat(Y),nat_nat_sum(X,Y,Z) s5 Sols.
 Sols = [[nat(0),  (nat(0), nat_nat_sum(0, 0, 0))], [nat(0),  (nat(s(0)), nat_nat_sum(0, s(0), s(0)))], [nat(0),  (nat(s(s(0))), nat_nat_sum(0, s(s(0)), s(s(0))))], [nat(0),  (nat(s(s(...))), nat_nat_sum(0, s(s(...)), s(s(...))))], [nat(0),  (nat(s(...)), nat_nat_sum(0, s(...), s(...)))]] ;
 Sols = [[nat(0),  (nat(s(s(s(s(s(...)))))), nat_nat_sum(0, s(s(s(s(s(...))))), s(s(s(s(s(...)))))))], [nat(0),  (nat(s(s(s(s(...))))), nat_nat_sum(0, s(s(s(s(...)))), s(s(s(s(...))))))], [nat(0),  (nat(s(s(s(...)))), nat_nat_sum(0, s(s(s(...))), s(s(s(...)))))], [nat(0),  (nat(s(s(...))), nat_nat_sum(0, s(s(...)), s(s(...))))], [nat(0),  (nat(s(...)), nat_nat_sum(0, s(...), s(...)))]] ;
Sols = [[nat(0),  (nat(s(s(s(s(s(...)))))), nat_nat_sum(0, s(s(s(s(s(...))))), s(s(s(s(s(...)))))))], [nat(0),  (nat(s(s(s(s(...))))), nat_nat_sum(0, s(s(s(s(...)))), s(s(s(s(...))))))], [nat(0),  (nat(s(s(s(...)))), nat_nat_sum(0, s(s(s(...))), s(s(s(...)))))], [nat(0),  (nat(s(s(...))), nat_nat_sum(0, s(s(...)), s(s(...))))], [nat(0),  (nat(s(...)), nat_nat_sum(0, s(...), s(...)))]] .

 ?- p(X) s5 Sols.
 Sols = [[1], [2], [3], [4], [5]] ;
 Sols = [[6], [7]].

优点是您可以在查询结束时添加所需的答案数。然后,您将获得该长度的列表作为答案,因此它们不仅可以写入控制台,还可以用于进一步查询。

答案 3 :(得分:2)

一种可能的解决方案,使用在一些名称不同的Prolog系统上找到的令人讨厌的全局谓词,这里为SWI-Prolog说明。

chunks_of_size(Size, Goal) :-
    Size1 is Size + 1,
    nb_setval('$chunk_size', Size1),
    nb_setval('$chunk_count', Size),
    call((Goal,chunks)).

chunks :-
    nb_getval('$chunk_count', N),
    N > 0,
    M is N - 1,
    nb_setval('$chunk_count', M),
    nl,
    fail.
chunks :-
    nb_getval('$chunk_count', 0),
    nb_getval('$chunk_size', Size),
    nb_setval('$chunk_count', Size),
    write('-----'),
    chunks.

用法示例:

?- chunks_of_size(3, (between(1, 12, N), write(N))).
1
2
3
-----
4
5
6
-----
7
8
9
-----
10
11
12
-----
false.

如果您想在每组解决方案后停止进行用户交互,请将chunks/0谓词的第二个句子替换为:

chunks :-
    nb_getval('$chunk_count', 0),
    nb_getval('$chunk_size', Size),
    nb_setval('$chunk_count', Size),
    (   write('-----')
    ;   chunks
    ).

通过此更改,您现在可以获得:

?- chunks_of_size(3, (between(1, 12, N), write(N))).
1
2
3
-----
N = 3 ;

4
5
6
-----
N = 6 ;

7
8
9
-----
N = 9 ;

10
11
12
-----
N = 12 ;

false.