I am working on a constraints programming problem in Prolog and I am having problems trying to define a domain for lists of list. The initial challenge of the problem is as follows:
trains([[1,2,0,1], %from station, to station, departs at, arrives at
[2,3,4,5],
[2,3,0,1],
[3,4,5,6],
[3,4,2,3],
[3,4,8,9]]).
threepath(A,D,Ps):-
Ps = [[A,B, _T0, T1], [B,C, T2, T3], [C,D, T4, _T5]],
T2 #> T1,
T4 #> T3,
trains(Ts),
tuples_in(Ps, Ts).
After that, I am expected to expand on this to accommodate for any number of trains instead of only 3. Here is my attempt at doing that:
anypath(A,D,Ps,N):-
length(Ps,N),
Ps ins Xs,
Xs = [A,B,C,D],
Xs ins 1..9. %How to define the domain for a list of length 4 inside a list of variable length.
However, I am not very sure how to define a domain for lists of list. So far, I have defined length(Ps, N) so that Ps can have any length. Then, I tried to define the variables inside of Ps so that they will be list of length 4 but failed horribly.
Additionally, I am also not sure how to define the constraints for a variable length of Ps like the 3 scenario case where T2 #> T1 and T3 #> T4. The pattern that I am seeing is the last element of the next list should be greater than the third element of the list before it but I am stuck on the syntax to represent this constraint as well.
Right now, I am trying to use recursion to somehow set the Head of Ps to a list of length 4 and to recurse through to do the same with the tails since I won't be able to know how long the list Ps will be.
I would be grateful if someone can shed some light on this.
Update on Progress 25/3/2015
I read on an example of another problem that a maplist was used to produce inner lists. An excerpt of the code is:
length_(Length, List) :- length(List, Length).
child_row(X) :- X ins 1..16 .
ww(X) :-
write(X),
write('/').
print_row(Row) :-
maplist(ww, Row),
nl.
children(Class) :-
length(Class, 4),
maplist(length_(4), Class),
maplist(child_row , Class),
From what I understand, maplist(length_(4), Class) applies the length_(4) to every element inside Class and creates inner lists of length 4 as a result. So, I tried to apply this to my problem and here is my attempt:
length_(Length, List) :- length(List, Length).
anypath(A,D,Ps,N):-
length(Ps,N),
maplist(length_(4), Ps),
%constraint(Ps),
trains(Ts),
tuples_in(Ps, Ts).
However, I get an error message saying "length/2: Type error: list' expected, found
4'" regardless of whether N is set to 3 or 4 and I don't quite understand this as well since it should work the same way as the example above and gtrace is a bit messy to detect what's wrong for me.
I am currently stuck at the moment and I will update if I figure anything out.
So, I have another question that I hope can be answered is "What is the normal practice of creating inner lists and how do you normally do it yourself?".
Thanks!
You can flatten the list with
append(Trains, FlatTrains)
and then constrain the domain of FlatTrains
FlatTrains ins 1..9