限制打印prolog事实三次?

时间:2011-10-17 14:01:35

标签: prolog

假设我在数据库中有10个事实path(X)

如何将其限制为从数据库中打印前3个?

我尝试过使用递归技术,但它似乎只会与第一个技术统一起来。

所有人都很感激。

2 个答案:

答案 0 :(得分:2)

有两种可能性。两者都需要利用Prolog的额外逻辑属性。

(1)您收集列表中的所有事实,然后使用递归打印此列表的前N个项目。这种方法很清楚,但是当存在许多事实(例如数千个)并且只有少数事实被写入(例如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)您可以使用可伸缩计数器和故障驱动循环。这种方法不如第一种方法那么优雅,但是在有许多事实并且只写出很少的事实的情况下会更有效。

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

添加:按升序排列前N个“最小”事实:

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

答案 1 :(得分:0)

如果您确定,至少有3个事实,并且您不介意是否创建了所有解决方案:

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

您还可以使用以下内容:

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