Well, how about this ?
my_flatten(L, Flat) :-
flatten_(L, Flat, []).
flatten_([], R, R).
flatten_([H | T], L, R) :-
flatten_(H, L, R1),
flatten_(T, R1, R).
flatten_(X, [X | R], R).
I am sure that your first response will be: Well, that is not deterministic, only the first response is the flatten version, etc
But the book does not specify anything regarding determinism or the number of solution, they only say: if you give it [a,b,[c,d],[[1,2]],foo]
, you get [a,b,c,d,1,2,foo]
:
?- my_flatten([a,b,[c,d],[[1,2]],foo], L).
L = [a, b, c, d, 1, 2, foo] % pending choice points
I think this is what the authors were after.
This is the funniest thing I have ever read…
flatten/2
is one of the most useful procedural predicates when doing constraints programming.
Did you know that until very recently, the flatten/2
predicate was defined in the clpfd library ?
For example, when you setup the constraints for the sudoku puzzle, you will use a list of list of clpfd variables, and then when you need to do the labeling, you need a flatten version of that list.