Prolog:显示水平世界
Prolog: displaying leveled world
所以我的目标是根据这些事实展示世界的现状(而不是硬编码):
on(a,table).
on(b,table).
on(c,table).
on(d,table).
on(e,table).
on(f,table).
on(g,table).
on(h,b).
on(i,h).
on(j,i).
on(k,c).
on(l,k).
on(m,f).
on(n,m).
left(a,b).
left(b,c).
left(c,d).
left(d,e).
left(e,f).
left(f,g).
打印后应该与此类似。
J
i L N
h k m
a b c D E f g
___________________________________
Table
我试过使用与此类似的 bagof() 来抓取每个级别,但是如果超过 2 个级别,这会变得乏味,我确信有更好的方法来做到这一点,我只是想不出。
bagof(X,(on(X,table)),Bottom),
bagof(D,Z^(on(D,Z),on(Z,table)),Level01),
非常感谢任何帮助,谢谢。
将 'logical' 布局与实际 IO 问题分开可能会有所帮助(但请注意,未使用 left/2 约束):
coords(Cs) :-
findall(E, on(E,table), Base),
findall(placed(E,1,C), nth1(C,Base,E), OnTable),
rows(OnTable, [], Cs).
rows([], Rs, Rs).
rows(Row, Rows, Full) :-
findall(placed(F,R1,C), (member(placed(E,R,C), Row), on(F,E), R1 is R+1), ThisRow),
rows(ThisRow, [Row|Rows], Full).
现在我们得到
?- coords(X),maplist(writeln,X).
[placed(j,4,2)]
[placed(i,3,2),placed(l,3,3),placed(n,3,6)]
[placed(h,2,2),placed(k,2,3),placed(m,2,6)]
[placed(a,1,1),placed(b,1,2),placed(c,1,3),placed(d,1,4),placed(e,1,5),placed(f,1,6),placed(g,1,7)]
X = [[placed(j, 4, 2)], [placed(i, 3, 2), placed(l, 3, 3), placed(n, 3, 6)], [placed(h, 2, 2), placed(k, 2, 3), placed(m, 2, 6)], [placed(a, 1, 1), placed(b, 1, 2), placed(c, 1, 3), placed(d, 1, 4), placed(..., ..., ...)|...]]
.
[placed(a,0,1),placed(b,0,2),placed(c,0,3),placed(d,0,4),placed(e,0,5),placed(f,0,6),placed(g,0,7)]
所以,而不是 writeln/1,应该足以打印带有空格的行来填充跳过的列。
其实placed(Label,Row,Col)
中的Row可以是隐式的,代码会更简单...看看你能不能做到这一点'optimization'。
所以我的目标是根据这些事实展示世界的现状(而不是硬编码):
on(a,table).
on(b,table).
on(c,table).
on(d,table).
on(e,table).
on(f,table).
on(g,table).
on(h,b).
on(i,h).
on(j,i).
on(k,c).
on(l,k).
on(m,f).
on(n,m).
left(a,b).
left(b,c).
left(c,d).
left(d,e).
left(e,f).
left(f,g).
打印后应该与此类似。
J
i L N
h k m
a b c D E f g
___________________________________
Table
我试过使用与此类似的 bagof() 来抓取每个级别,但是如果超过 2 个级别,这会变得乏味,我确信有更好的方法来做到这一点,我只是想不出。
bagof(X,(on(X,table)),Bottom),
bagof(D,Z^(on(D,Z),on(Z,table)),Level01),
非常感谢任何帮助,谢谢。
将 'logical' 布局与实际 IO 问题分开可能会有所帮助(但请注意,未使用 left/2 约束):
coords(Cs) :-
findall(E, on(E,table), Base),
findall(placed(E,1,C), nth1(C,Base,E), OnTable),
rows(OnTable, [], Cs).
rows([], Rs, Rs).
rows(Row, Rows, Full) :-
findall(placed(F,R1,C), (member(placed(E,R,C), Row), on(F,E), R1 is R+1), ThisRow),
rows(ThisRow, [Row|Rows], Full).
现在我们得到
?- coords(X),maplist(writeln,X).
[placed(j,4,2)]
[placed(i,3,2),placed(l,3,3),placed(n,3,6)]
[placed(h,2,2),placed(k,2,3),placed(m,2,6)]
[placed(a,1,1),placed(b,1,2),placed(c,1,3),placed(d,1,4),placed(e,1,5),placed(f,1,6),placed(g,1,7)]
X = [[placed(j, 4, 2)], [placed(i, 3, 2), placed(l, 3, 3), placed(n, 3, 6)], [placed(h, 2, 2), placed(k, 2, 3), placed(m, 2, 6)], [placed(a, 1, 1), placed(b, 1, 2), placed(c, 1, 3), placed(d, 1, 4), placed(..., ..., ...)|...]]
.
[placed(a,0,1),placed(b,0,2),placed(c,0,3),placed(d,0,4),placed(e,0,5),placed(f,0,6),placed(g,0,7)]
所以,而不是 writeln/1,应该足以打印带有空格的行来填充跳过的列。
其实placed(Label,Row,Col)
中的Row可以是隐式的,代码会更简单...看看你能不能做到这一点'optimization'。