按字典顺序创建值0到n-1的列表

时间:2015-07-19 22:53:44

标签: list prolog

我用Result编写一个程序是一对以字典顺序在0和N-1之间的值[X,Y]

我现在有这个:

pairs(N,R) :-
   pairsHelp(N,R,0,0).

pairsHelp(N,[],N,N) :- !.
pairsHelp(N,[],N,0) :- !.
pairsHelp(N,[[X,Y]|List],X,Y) :-
    Y is N-1,
    X < N,
    X1 is X + 1,
    pairsHelp(N,List,X1,0).
pairsHelp(N,[[X,Y]|List],X,Y) :-
    Y < N,
    Y1 is Y + 1,
    pairsHelp(N,List,X,Y1).

我得到了我想要的第一次迭代,但是Prolog继续前进,然后给了我第二个答案。

?-pairs(2,R).
R = [[0,0],[0,1],[1,0],[1,1]] ;
false.

我不想要第二个答案(错误),只是第一个答案。我希望它在找到答案后停止。有什么想法吗?

2 个答案:

答案 0 :(得分:4)

请记住,有一个很多更简单的方式来获得你想要的东西。如果确实X和Y都应该是整数,请使用between/3枚举整数(&#34; lexicographical&#34;这里与自然数的顺序相同:0,1,2,... 。如果第三个参数是一个变量,这是between/3枚举可能解决方案的顺序:

pairs(N, R) :-
    succ(N0, N),
    bagof(P, pair(N0, P), R).

pair(N0, X-Y) :-
    between(0, N0, X),
    between(0, N0, Y).

然后:

?- pairs(2, R).
R = [0-0, 0-1, 1-0, 1-1].

?- pairs(3, R).
R = [0-0, 0-1, 0-2, 1-0, 1-1, 1-2, 2-0, 2-1, ... - ...].

我使用传统的Prolog方式来表示一对,X-Y(以规范形式:-(X, Y))而不是[X,Y](规范形式:.(X, .(Y, [])))。< / p>

这个程序的好处是你可以轻松地重写它以使用另一个&#34;字母表&#34;你所选择的。

?- between(0, Upper, X).

在语义上等同于:

x(0).
x(1).
% ...
x(Upper).

?- x(X).

例如,如果我们的字母表包含bac(按此顺序排列!):

foo(b).
foo(a).
foo(c).

foo_pairs(Ps) :-
    bagof(X-Y, ( foo(X), foo(Y) ), Ps).

然后:

?- foo_pairs(R).
R = [b-b, b-a, b-c, a-b, a-a, a-c, c-b, c-a, ... - ...].

foo/1子句的顺序定义了您的字母顺序。联合foo(X), foo(Y)以及对中X-Y的顺序定义了列表中对的顺序。尝试编写例如bagof(X-Y, ( foo(Y), foo(X) ), Ps)以查看Ps中对的顺序。

答案 1 :(得分:2)

lambda结合使用!

?- use_module(library(lambda)).

结合 init0/3xproduct//2(“交叉产品”)只写:

?- init0(=,3,Xs), phrase(xproduct(\X^Y^phrase([X-Y]),Xs),Pss).
Xs = [0,1,2], Pss = [0-0,0-1,0-2,1-0,1-1,1-2,2-0,2-1,2-2].

一点更通用的东西怎么样?那么N的其他值呢?

?- init0(=,N,Xs), phrase(xproduct(\X^Y^phrase([X-Y]),Xs),Pss).
  N = 0, Xs = [],          Pss = []
; N = 1, Xs = [0],         Pss = [0-0]
; N = 2, Xs = [0,1],       Pss = [0-0,0-1,
                                  1-0,1-1]
; N = 3, Xs = [0,1,2],     Pss = [0-0,0-1,0-2,
                                  1-0,1-1,1-2,
                                  2-0,2-1,2-2]
; N = 4, Xs = [0,1,2,3],   Pss = [0-0,0-1,0-2,0-3,
                                  1-0,1-1,1-2,1-3,
                                  2-0,2-1,2-2,2-3,
                                  3-0,3-1,3-2,3-3] 
; N = 5, Xs = [0,1,2,3,4], Pss = [0-0,0-1,0-2,0-3,0-4,
                                  1-0,1-1,1-2,1-3,1-4,
                                  2-0,2-1,2-2,2-3,2-4,
                                  3-0,3-1,3-2,3-3,3-4,
                                  4-0,4-1,4-2,4-3,4-4]
...

它也适用于其他术语吗?订单怎么样?考虑his answer中使用的案例@Boris:

?- phrase(xproduct(\X^Y^phrase([X-Y]),[b,a,c]),Pss).
Pss = [b-b,b-a,b-c,a-b,a-a,a-c,c-b,c-a,c-c].  % succeeds deterministically