Automatic results shown in Prolog?

How can I make the SWI-Prolog interpreter automatically execute a semicolon? I have a lot of results (about 300) due to backtracking, and I don't want to click on the semicolon for all of them.

I DO NOT want a list of all the solutions, I just want not to press the semicolon or the space bar so that I can leave the program for printing inverse solutions in the background.

+6
source share
4 answers

You can manually emit solutions (using, for example, write/1 or format/2 ), and force them back with false to see all the solutions. For instance:

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

In addition, for example, in SWI-Prolog, you can simply press SPACE instead ; for further solutions.

+3
source

@repeat Not sure if this meets your criteria, but could you please develop a meta-interpreter? I'm not sure if there is a way to load mi so that all top-level requests go through it?

So something like:

 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). 

Inquiries

 ?- 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(...)))))] ... 

Just showing the main idea .. this only works for 1 arg predicates ..

+3
source

This is another way that I find quite enjoyable:

 :- 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). 

IN:

  ?- 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]]. 

The advantage is that you can simply add how many responses you want at the end of the query. Then you get lists of this length as answers, so they are not just written to the console, but can be used for further requests.

+3
source

A possible solution using the nasty globals predicates found on some Prolog systems with different names, illustrated here for 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. 

Usage example:

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

If you want to stop interacting with the user after each group of decisions, replace the second sentence of the chunks/0 predicate with:

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

With this change you will receive:

 ?- 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. 
+2
source

All Articles