开发者

Limit Printing of the prolog facts to THREE times?

Say I have 10 facts path(X) in the database.

Ho开发者_JS百科w do I limit it to printing the first 3 from the database?

I have tried using recursive technique but it seems that it will only unify with the first one.

All helps appreciated.


There are two possibilities. Both need to utilize extra-logical properties of Prolog.

(1) You collect all facts in a list and then print the first N items of this list using recursion. This approach is clear, but it could be inefficient when there are many facts (e.g. thousands) and only few of them will be written (e.g. 3).

print1(N) :- 
    findall(path(X), path(X), List),
    print1(List, N).

print1([], N) :- !.
print1([H|T], N) :- 
    writeln(H),
    N1 is N - 1, N1 > 0,
    print1(T, N1).

?- print1(3).

(2) You can use a retractable counter and a failure driven loop. This approach is less elegant than the first one but will be more efficient in the case there are many facts and only few of them are written.

:- dynamic count/1.
print2(N) :-
    assert(count(N)), !,
    path(X), writeln(path(X)),
    retract(count(K)),
    K1 is K - 1,
    (K1 > 0 -> assert(count(K1)); true, !), 
    fail.

?- print2(3).

Addition: Printing first N "smallest" facts in ascending order:

print_sorted(N) :-
    findall(path(X), path(X), List),
    msort(List, SortedList),
    print1(SortedList, N). 


If you are sure, that there are at least 3 facts and you don't mind if all Solutions are created:

three_results(A,B,C) :- findall(X,path(X),[A,B,C|_]).

You can also use something like:

n_results(0,A,A) :- !.
n_results(N,A,R) :- path(X), (member(X,A) -> fail; true), N1 is N - 1, n_results(N1,[X|A],R).
three_results(X) :- n_results(3,[],X).
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜