Prologue list of number generators

I would like to create a generator that creates a list from type [a, b, c] starting at [0,0,0], the next one is [0,0,1], [0,1,0], [1,0 , 0], [0,1,1], [1,0,1], [1,1,0], [1,1,1], [1,1,2] and so on to infinity.

I'm sorry I said this with a long example. I just don't know how to explain this in English.

If I had a range (say up to 10), I would use the following:

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

      

But when he goes on forever, I don't know what to do.

+3


source to share


3 answers


I have limited the range to get a clean display, but you can replace 3 with inf. Of course, don't put conjunction in findall :) The idea is that only one of the generators runs indefinitely, the other two (or whatever you want) are limited to this value ...



?- 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]
...

      

+1


source


between/3

takes an atom as its second argument 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.

      

Creating lists in the requested order is probably best achieved with constraints ... From the top of my chapter, I provide the following implementation, which does not use constraints:



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).

      

Usage example:

?- 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] ;

      

+1


source


In the future, we use ...

:- use_module(library(clpfd)).

      

Consider first:

? - 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].

Next, generalize sum(Zs,#=,3)

and use length(_,Sum)

for a fair listing ... and we've done

? - 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]
...
+1


source







All Articles