2014-11-17 2 views
3

Я хотел бы сделать генератор, который делает список из типа [a, b, c], начинается с [0,0,0], следующий - [0,0,1], [ 0,1,0], [1,0,0], [0,1,1], [1,0,1], [1,1,0], [1,1,1], [1, 1,2] и т. Д. До бесконечности.Пролог список генераторов чисел

Прошу прощения, я сказал это длинным примером. Я просто не знаю, как объяснить это на английском языке.

Если бы я был диапазон (скажем, это до 10) Я хотел бы использовать между так:

genCombo([A,B,C]):- 
     between(0,10,A), 
     between(0,10,B), 
     between(0,10,C). 

Но когда это до бесконечности, я не знаю, что я должен делать.

ответ

1

Я ограничил диапазон, чтобы получить чистый дисплей, но вы можете заменить 3 на inf. Конечно, не ставьте конъюнкцию в FindAll :) Идея это, что только один из генераторов работает до бесконечности, другие два (или что вы хотите) ограничены этим значением ...

?- findall([B,C,A], (between(0, 3, A), between(0, A, B), between(0, A, C)), L), maplist(writeln,L). 
[0,0,0] 
[0,0,1] 
[0,1,1] 
[1,0,1] 
[1,1,1] 
[0,0,2] 
[0,1,2] 
[0,2,2] 
[1,0,2] 
[1,1,2] 
[1,2,2] 
[2,0,2] 
[2,1,2] 
[2,2,2] 
[0,0,3] 
[0,1,3] 
[0,2,3] 
[0,3,3] 
... 
+0

Спасибо, это именно то решение, которое я искал. – chnging

1

between/3 принимает атом inf в качестве второго аргумента:

?- between(0, inf, X). 
X = 0 ; 
X = 1 ; 
X = 2 ; 
X = 3 ; 
X = 4 ; 
X = 5 ; 
X = 6 ; 
X = 7 ; 
X = 8 ; 
X = 9 ; 
X = 10 ; 
X = 11 ; 
Etc. 

Создание списков в запрашиваемом порядке, вероятно, лучше всего достигается с помощью ограничений ... Из верхней части моей головы, я пришел с следующей реализации, не использует ограничения:

go([A,B,C]):- 
    between(0, inf, X1), 
    succ(X1, X2), 
    member(A, [X1,X2]), 
    member(B, [X1,X2]), 
    member(C, [X1,X2]), 
    \+ (A == X2, B == X2, C == X2). 

Пример использования:

?- go(L). 
L = [0, 0, 0] ; 
L = [0, 0, 1] ; 
L = [0, 1, 0] ; 
L = [0, 1, 1] ; 
L = [1, 0, 0] ; 
L = [1, 0, 1] ; 
L = [1, 1, 0] ; 
L = [1, 1, 1] ; 
L = [1, 1, 2] ; 
+0

Да, но таким образом он получает только [0,0,1], [0,0,2], [0,0,3] и так далее, и никогда не изменяет другие 2 номера. – chnging

+0

@chnging Я добавил специальную реализацию, которая создает списки в описанном вами порядке. Имейте в виду, что новые решения должны существовать! –

1

В дальнейшем мы используем .

:- use_module(library(clpfd)). 

Сначала рассмотрим:

 
?- Zs = [_,_,_], Zs ins 0..sup, sum(Zs,#=,3), labeling([],Zs). 
    Zs = [0,0,3] 
; Zs = [0,1,2] 
; Zs = [0,2,1] 
; Zs = [0,3,0] 
; Zs = [1,0,2] 
; Zs = [1,1,1] 
; Zs = [1,2,0] 
; Zs = [2,0,1] 
; Zs = [2,1,0] 
; Zs = [3,0,0]. 

Далее обобщать sum(Zs,#=,3) и использование length(_,Sum) для справедливого перечисления ... и мы сделали!

 
?- length(_,Sum), Zs = [_,_,_], Zs ins 0..sup, sum(Zs,#=,Sum), labeling([],Zs). 
    Sum = 0, Zs = [0,0,0] 
; Sum = 1, Zs = [0,0,1] 
; Sum = 1, Zs = [0,1,0] 
; Sum = 1, Zs = [1,0,0] 
; Sum = 2, Zs = [0,0,2] 
; Sum = 2, Zs = [0,1,1] 
; Sum = 2, Zs = [0,2,0] 
; Sum = 2, Zs = [1,0,1] 
; Sum = 2, Zs = [1,1,0] 
; Sum = 2, Zs = [2,0,0] 
; Sum = 3, Zs = [0,0,3] 
; Sum = 3, Zs = [0,1,2] 
; Sum = 3, Zs = [0,2,1] 
; Sum = 3, Zs = [0,3,0] 
; Sum = 3, Zs = [1,0,2] 
; Sum = 3, Zs = [1,1,1] 
; Sum = 3, Zs = [1,2,0] 
; Sum = 3, Zs = [2,0,1] 
; Sum = 3, Zs = [2,1,0] 
; Sum = 3, Zs = [3,0,0] 
; Sum = 4, Zs = [0,0,4] 
... 
Смежные вопросы