如何使 SWI-Prolog 解释器自动执行分号?由于回溯,我有很多结果(大约 300 个),我不想为所有结果添加分号。
我不想要所有解决方案的列表,我只想不按分号或空格,这样我就可以让程序在后台打印回溯的解决方案。
如何使 SWI-Prolog 解释器自动执行分号?由于回溯,我有很多结果(大约 300 个),我不想为所有结果添加分号。
我不想要所有解决方案的列表,我只想不按分号或空格,这样我就可以让程序在后台打印回溯的解决方案。
您可以手动发出解决方案(例如使用write/1
或format/2
),并强制回溯false
以查看所有解决方案。例如:
?- solution(S), writeln(S), false.
此外,例如在 SWI-Prolog 中,您可以简单地按 SPACE 而不是;
进一步的解决方案。
这是我认为非常好的另一种方式:
:- 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]].
优点是您可以在查询末尾添加您想要的答案数量。然后,您将获得该长度的列表作为答案,因此它们不仅被写入控制台,还可以用于进一步查询。
@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 谓词..
一种可能的解决方案,使用在一些具有不同名称的 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.