将输出合并到Prolog中的一个列表中

时间:2017-02-10 19:13:35

标签: merge prolog

我有一个prolog任务,要求我们列出两个数量范围内的所有数字对。我可以让它输出(使用一个函数)以下,但我不知道如何合并所有输出。这是调用函数的结果:

?- i(L,5,7).
L = [(5, 5),  (5, 6),  (5, 7)] ;
L = [(6, 5),  (6, 6),  (6, 7)] ;
L = [(7, 5),  (7, 6),  (7, 7)] ;

这是代码(间隔方法是教授定义的,不允许修改):

interval(X,L,H) :-
    number(X),
    number(L),
    number(H),
    !,
    X>=L,
    X=<H.

interval(X,X,H) :-
    number(X),
    number(H),
    X=<H.

interval(X,L,H) :-
    number(L),
    number(H),
    L<H,
    L1 is L+1,

    interval(X,L1,H).

i(L,X,Y):-
    interval(N2,X,Y),
    setof((N2,N),interval(N,X,Y),L).

我正在寻找输出:

L = [ (5, 5), (5, 6), (5, 7), (6, 5), (6, 6), (6, 7), (7, 5), (7, 6), (7, 7)]

2 个答案:

答案 0 :(得分:3)

问题在于:

i(L,X,Y):-
    interval(N2,X,Y),
    setof((N2,N),interval(N,X,Y),L).

首先将N2 设置为区间中的数字,然后您要求为该给定数字N2和变量编号{{1}生成一组}。

然而,您可以在N

的目标中定义合成
setof/3

然而,或许更优雅的方式(可能更多 Prolog )是定义i(L,X,Y) :- setof((N2,N),(interval(N2,X,Y),interval(N,X,Y)),L).谓词:

interval_tuple/3

然后在该谓词上调用interval_tuple(X,Y,(N,N2)) :- interval(N,X,Y), interval(N2,X,Y). setof/3

listof/3

答案 1 :(得分:2)

你可以用CLP(FD)简洁地完成这个:

:- use_module(library(clpfd)]).

interval(Left, Right, (X,Y)) :-   % Definition of one interval
    [X, Y] ins Left .. Right,
    label([X, Y]).

intervals(Left, Right, IntervalList) :-
    Left #=< Right,
    label([Left, Right]),
    findall(Interval, interval(Left, Right, Interval), IntervalList). % Find all intervals

我使用更具描述性的名称intervals/3,而不仅仅是i/3。我也对这些论点进行了重新排序。