我有一个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)]
答案 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
。我也对这些论点进行了重新排序。