Prolog CLPFD 试图为列表的列表定义域
Prolog CLPFD trying to define domain for lists of list
我正在处理 Prolog 中的约束编程问题,并且在尝试为列表的列表定义域时遇到问题。问题初始挑战如下:
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).
在那之后,我将对此进行扩展以容纳任意数量的火车,而不是仅容纳 3 列。这是我尝试这样做的尝试:
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.
但是,我不太确定如何为列表的列表定义域。到目前为止,我已经定义了 length(Ps, N) 以便 Ps 可以有任何长度。然后,我尝试在 Ps 中定义变量,以便它们成为长度为 4 的列表,但失败得很惨。
此外,我也不确定如何为 Ps 的可变长度定义约束,例如 T2 #> T1 和 T3 #> T4 的 3 种情况。我看到的模式是下一个列表的最后一个元素应该大于它之前列表的第三个元素,但我也坚持表示这个约束的语法。
现在,我正在尝试使用递归以某种方式将 Ps 的头部设置为长度为 4 的列表并递归以对尾部执行相同的操作,因为我将无法知道列表 Ps 有多长。
如果有人能对此有所说明,我将不胜感激。
进度更新 25/3/2015
我阅读了另一个问题的示例,即使用映射表生成内部列表。代码摘录是:
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),
据我了解,maplist(length_(4), Class) 将 length_(4) 应用于 Class 内的每个元素,并因此创建长度为 4 的内部列表。因此,我尝试将其应用于我的问题,这是我的尝试:
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).
但是,无论 N 设置为 3 还是 4,我都会收到一条错误消息 "length/2: Type error: list' expected, found
4'" 并且我不太理解这一点,因为它应该与上面的示例一样工作并且gtrace 有点乱,无法检测出我的问题。
我现在卡住了,如果有什么发现我会更新的。
那么,我还有一个问题希望得到解答,那就是 "What is the normal practice of creating inner lists and how do you normally do it yourself?"。
谢谢!
您可以使用
展平列表
append(Trains, FlatTrains)
然后约束FlatTrains的域
FlatTrains ins 1..9
我正在处理 Prolog 中的约束编程问题,并且在尝试为列表的列表定义域时遇到问题。问题初始挑战如下:
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).
在那之后,我将对此进行扩展以容纳任意数量的火车,而不是仅容纳 3 列。这是我尝试这样做的尝试:
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.
但是,我不太确定如何为列表的列表定义域。到目前为止,我已经定义了 length(Ps, N) 以便 Ps 可以有任何长度。然后,我尝试在 Ps 中定义变量,以便它们成为长度为 4 的列表,但失败得很惨。
此外,我也不确定如何为 Ps 的可变长度定义约束,例如 T2 #> T1 和 T3 #> T4 的 3 种情况。我看到的模式是下一个列表的最后一个元素应该大于它之前列表的第三个元素,但我也坚持表示这个约束的语法。
现在,我正在尝试使用递归以某种方式将 Ps 的头部设置为长度为 4 的列表并递归以对尾部执行相同的操作,因为我将无法知道列表 Ps 有多长。
如果有人能对此有所说明,我将不胜感激。
进度更新 25/3/2015
我阅读了另一个问题的示例,即使用映射表生成内部列表。代码摘录是:
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),
据我了解,maplist(length_(4), Class) 将 length_(4) 应用于 Class 内的每个元素,并因此创建长度为 4 的内部列表。因此,我尝试将其应用于我的问题,这是我的尝试:
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).
但是,无论 N 设置为 3 还是 4,我都会收到一条错误消息 "length/2: Type error: list' expected, found
4'" 并且我不太理解这一点,因为它应该与上面的示例一样工作并且gtrace 有点乱,无法检测出我的问题。
我现在卡住了,如果有什么发现我会更新的。
那么,我还有一个问题希望得到解答,那就是 "What is the normal practice of creating inner lists and how do you normally do it yourself?"。
谢谢!
您可以使用
展平列表append(Trains, FlatTrains)
然后约束FlatTrains的域
FlatTrains ins 1..9