2017-02-10 11 views
3

У меня есть прологовое задание, которое требует от нас составить список всех пар чисел в диапазоне двух значений. Я могу заставить его выводить (используя одну функцию) следующее, но я не знаю, как объединить все выходы. Вот outbut вызова функции:Объединить выходы в один список в 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)] 

ответ

3

проблема заключается в том, что:

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

Будет ли первым набором N2 на номер в интервале, а затем вы попросите сгенерировать набор для данного заданного числа N2 и номер переменной N.

Однако вы можете просто определить композиционный в цели setof/3:

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 на этот предикат:

i(L,X,Y) :- 
    listof(Tup,interval_tuple(X,Y,Tup),L). 
+0

Спасибо! Я предполагал, что это было что-то простое, что мой сон лишил мозг. –

+0

Не уверен, что вы должны называть '(X, Y)' кортежем. Это («Х», «Y»), но тогда «(X, Y, Z)» не является «кортежем», как например, в Python или Haskell (потому что это '', '(X,', '(Y, Z)) ', а не'', '(X, Y, Z) '). –

+1

@Boris: но на самом деле вы не можете вызывать '[1,2]' список, это '| (1, | (2, []))'. В Прологе нет «реальных данных». Prolog является нетипизированным, поэтому он означает, что структуры данных существуют только потому, что это говорят программисты. –

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. Я также немного изменил аргументы.

+1

Используйте скорее ': - use_module (library (clpfd)).' – false

+0

@false спасибо, действительно. – lurker

 Смежные вопросы

  • Нет связанных вопросов^_^