学习序言:解决序言中的纵横字谜问题
Learning Prolog : solving crossword problem in prolog
我正在尝试学习 Prolog,我有一个练习,但我无法解决它。
这是我必须做的:-
https://i.stack.imgur.com/CSJqK.png
这是我试过的代码:-
word(zombifies, [z,o,m,b,i,f,i,e,s]).
word(akecabele, [a,k,e,c,a,b,e,l,e]).
word(brickwork, [b,r,i,c,k,w,o,r,k]).
word(backcheck, [b,a,c,k,c,h,e,c,k]).
word(acmrremad, [a,c,m,r,r,e,m,a,d]).
word(nhgwpfabz, [n,h,g,w,p,f,a,b,z]).
word(jellybean, [j,e,l,l,y,b,e,a,n]).
word(aerreoded, [a,e,r,r,e,o,d,e,d]).
crossword(H1,H2,H3,H4,V1,V2,V3,V4):-
word(H1, [_,H1V1,_,H1V2,_,H1V3,_,H1V4,_]),
word(H2, [_,H2V1,_,H2V2,_,H2V3,_,H2V4,_]),
word(H3, [_,H3V1,_,H3V2,_,H3V3,_,H3V4,_]),
word(H4, [_,H4V1,_,H4V2,_,H4V3,_,H4V4,_]),
word(V1, [_,H1V1,_,H2V1,_,H3V1,_,H4V1,_]),
word(V2, [_,H1V2,_,H2V2,_,H3V2,_,H4V2,_]),
word(V3, [_,H1V3,_,H2V3,_,H3V3,_,H4V3,_]),
word(V4, [_,H1V4,_,H2V4,_,H3V4,_,H4V4,_]),
H1\=V1,
H2\=V2,
H3\=V3,
H4\=V4.
但是当我 运行 这段代码总是 returns 错误。
那么我该怎么做才能将此代码正确修改为 运行?
编辑
这张图片中有这个问题的最终解决方案:-
https://i.stack.imgur.com/0QiEw.png
您的代码找不到解决方案,因为没有包含单词 aerreoded
的解决方案。但是,当单词earreoded
包含在单词集合中时,可以找到两种解决方案。
word(zombifies, [z,o,m,b,i,f,i,e,s]).
word(akecabele, [a,k,e,c,a,b,e,l,e]).
word(brickwork, [b,r,i,c,k,w,o,r,k]).
word(backcheck, [b,a,c,k,c,h,e,c,k]).
word(acmrremad, [a,c,m,r,r,e,m,a,d]).
word(nhgwpfabz, [n,h,g,w,p,f,a,b,z]).
word(jellybean, [j,e,l,l,y,b,e,a,n]).
word(aerreoded, [a,e,r,r,e,o,d,e,d]).
word(earreoded, [e,a,r,r,e,o,d,e,d]). % include this new word!
crossword(H1,H2,H3,H4,V1,V2,V3,V4):-
word(H1, [_,H1V1,_,H1V2,_,H1V3,_,H1V4,_]),
word(H2, [_,H2V1,_,H2V2,_,H2V3,_,H2V4,_]),
word(H3, [_,H3V1,_,H3V2,_,H3V3,_,H3V4,_]),
word(H4, [_,H4V1,_,H4V2,_,H4V3,_,H4V4,_]),
word(V1, [_,H1V1,_,H2V1,_,H3V1,_,H4V1,_]),
word(V2, [_,H1V2,_,H2V2,_,H3V2,_,H4V2,_]),
word(V3, [_,H1V3,_,H2V3,_,H3V3,_,H4V3,_]),
word(V4, [_,H1V4,_,H2V4,_,H3V4,_,H4V4,_]),
H1 \= V1,
H2 \= V2,
H3 \= V3,
H4 \= V4.
运行 示例:
?- crossword(H1,H2,H3,H4,V1,V2,V3,V4).
H1 = backcheck,
H2 = brickwork,
H3 = zombifies,
H4 = jellybean,
V1 = earreoded,
V2 = akecabele,
V3 = nhgwpfabz,
V4 = acmrremad ;
H1 = earreoded,
H2 = akecabele,
H3 = nhgwpfabz,
H4 = acmrremad,
V1 = backcheck,
V2 = brickwork,
V3 = zombifies,
V4 = jellybean ;
false.
如您所见,未找到包含单词 aerreoded
的解决方案。
改进版
您可以通过重新排序谓词 crossword/8
定义中的条件来使您的代码 运行 更快,以便尽早发生失败(这将减少 backtracks/inferences 需要找到答案)。
faster_crossword(H1,H2,H3,H4,V1,V2,V3,V4):-
word(H1, [_,H1V1,_,H1V2,_,H1V3,_,H1V4,_]),
word(V1, [_,H1V1,_,H2V1,_,H3V1,_,H4V1,_]),
H1 \= V1,
word(H2, [_,H2V1,_,H2V2,_,H2V3,_,H2V4,_]),
word(V2, [_,H1V2,_,H2V2,_,H3V2,_,H4V2,_]),
H2 \= V2,
word(H3, [_,H3V1,_,H3V2,_,H3V3,_,H3V4,_]),
word(V3, [_,H1V3,_,H2V3,_,H3V3,_,H4V3,_]),
H3 \= V3,
word(H4, [_,H4V1,_,H4V2,_,H4V3,_,H4V4,_]),
word(V4, [_,H1V4,_,H2V4,_,H3V4,_,H4V4,_]),
H4 \= V4.
要比较两个版本,您可以使用forall/2
(to generate all solutions) and time/1
(打印运行ning 时间统计)。
实证结果:
?- time(forall(crossword(H1,H2,H3,H4,V1,V2,V3,V4), writeln([H1,H2,H3,H4,V1,V2,V3,V4]))).
[backcheck,brickwork,zombifies,jellybean,earreoded,akecabele,nhgwpfabz,acmrremad]
[earreoded,akecabele,nhgwpfabz,acmrremad,backcheck,brickwork,zombifies,jellybean]
% 7,411 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
true.
?- time(forall(faster_crossword(H1,H2,H3,H4,V1,V2,V3,V4), writeln([H1,H2,H3,H4,V1,V2,V3,V4]))).
[backcheck,brickwork,zombifies,jellybean,earreoded,akecabele,nhgwpfabz,acmrremad]
[earreoded,akecabele,nhgwpfabz,acmrremad,backcheck,brickwork,zombifies,jellybean]
% 48 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
true.
我正在尝试学习 Prolog,我有一个练习,但我无法解决它。 这是我必须做的:-
https://i.stack.imgur.com/CSJqK.png
这是我试过的代码:-
word(zombifies, [z,o,m,b,i,f,i,e,s]).
word(akecabele, [a,k,e,c,a,b,e,l,e]).
word(brickwork, [b,r,i,c,k,w,o,r,k]).
word(backcheck, [b,a,c,k,c,h,e,c,k]).
word(acmrremad, [a,c,m,r,r,e,m,a,d]).
word(nhgwpfabz, [n,h,g,w,p,f,a,b,z]).
word(jellybean, [j,e,l,l,y,b,e,a,n]).
word(aerreoded, [a,e,r,r,e,o,d,e,d]).
crossword(H1,H2,H3,H4,V1,V2,V3,V4):-
word(H1, [_,H1V1,_,H1V2,_,H1V3,_,H1V4,_]),
word(H2, [_,H2V1,_,H2V2,_,H2V3,_,H2V4,_]),
word(H3, [_,H3V1,_,H3V2,_,H3V3,_,H3V4,_]),
word(H4, [_,H4V1,_,H4V2,_,H4V3,_,H4V4,_]),
word(V1, [_,H1V1,_,H2V1,_,H3V1,_,H4V1,_]),
word(V2, [_,H1V2,_,H2V2,_,H3V2,_,H4V2,_]),
word(V3, [_,H1V3,_,H2V3,_,H3V3,_,H4V3,_]),
word(V4, [_,H1V4,_,H2V4,_,H3V4,_,H4V4,_]),
H1\=V1,
H2\=V2,
H3\=V3,
H4\=V4.
但是当我 运行 这段代码总是 returns 错误。 那么我该怎么做才能将此代码正确修改为 运行?
编辑 这张图片中有这个问题的最终解决方案:- https://i.stack.imgur.com/0QiEw.png
您的代码找不到解决方案,因为没有包含单词 aerreoded
的解决方案。但是,当单词earreoded
包含在单词集合中时,可以找到两种解决方案。
word(zombifies, [z,o,m,b,i,f,i,e,s]).
word(akecabele, [a,k,e,c,a,b,e,l,e]).
word(brickwork, [b,r,i,c,k,w,o,r,k]).
word(backcheck, [b,a,c,k,c,h,e,c,k]).
word(acmrremad, [a,c,m,r,r,e,m,a,d]).
word(nhgwpfabz, [n,h,g,w,p,f,a,b,z]).
word(jellybean, [j,e,l,l,y,b,e,a,n]).
word(aerreoded, [a,e,r,r,e,o,d,e,d]).
word(earreoded, [e,a,r,r,e,o,d,e,d]). % include this new word!
crossword(H1,H2,H3,H4,V1,V2,V3,V4):-
word(H1, [_,H1V1,_,H1V2,_,H1V3,_,H1V4,_]),
word(H2, [_,H2V1,_,H2V2,_,H2V3,_,H2V4,_]),
word(H3, [_,H3V1,_,H3V2,_,H3V3,_,H3V4,_]),
word(H4, [_,H4V1,_,H4V2,_,H4V3,_,H4V4,_]),
word(V1, [_,H1V1,_,H2V1,_,H3V1,_,H4V1,_]),
word(V2, [_,H1V2,_,H2V2,_,H3V2,_,H4V2,_]),
word(V3, [_,H1V3,_,H2V3,_,H3V3,_,H4V3,_]),
word(V4, [_,H1V4,_,H2V4,_,H3V4,_,H4V4,_]),
H1 \= V1,
H2 \= V2,
H3 \= V3,
H4 \= V4.
运行 示例:
?- crossword(H1,H2,H3,H4,V1,V2,V3,V4).
H1 = backcheck,
H2 = brickwork,
H3 = zombifies,
H4 = jellybean,
V1 = earreoded,
V2 = akecabele,
V3 = nhgwpfabz,
V4 = acmrremad ;
H1 = earreoded,
H2 = akecabele,
H3 = nhgwpfabz,
H4 = acmrremad,
V1 = backcheck,
V2 = brickwork,
V3 = zombifies,
V4 = jellybean ;
false.
如您所见,未找到包含单词 aerreoded
的解决方案。
改进版
您可以通过重新排序谓词 crossword/8
定义中的条件来使您的代码 运行 更快,以便尽早发生失败(这将减少 backtracks/inferences 需要找到答案)。
faster_crossword(H1,H2,H3,H4,V1,V2,V3,V4):-
word(H1, [_,H1V1,_,H1V2,_,H1V3,_,H1V4,_]),
word(V1, [_,H1V1,_,H2V1,_,H3V1,_,H4V1,_]),
H1 \= V1,
word(H2, [_,H2V1,_,H2V2,_,H2V3,_,H2V4,_]),
word(V2, [_,H1V2,_,H2V2,_,H3V2,_,H4V2,_]),
H2 \= V2,
word(H3, [_,H3V1,_,H3V2,_,H3V3,_,H3V4,_]),
word(V3, [_,H1V3,_,H2V3,_,H3V3,_,H4V3,_]),
H3 \= V3,
word(H4, [_,H4V1,_,H4V2,_,H4V3,_,H4V4,_]),
word(V4, [_,H1V4,_,H2V4,_,H3V4,_,H4V4,_]),
H4 \= V4.
要比较两个版本,您可以使用forall/2
(to generate all solutions) and time/1
(打印运行ning 时间统计)。
实证结果:
?- time(forall(crossword(H1,H2,H3,H4,V1,V2,V3,V4), writeln([H1,H2,H3,H4,V1,V2,V3,V4]))).
[backcheck,brickwork,zombifies,jellybean,earreoded,akecabele,nhgwpfabz,acmrremad]
[earreoded,akecabele,nhgwpfabz,acmrremad,backcheck,brickwork,zombifies,jellybean]
% 7,411 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
true.
?- time(forall(faster_crossword(H1,H2,H3,H4,V1,V2,V3,V4), writeln([H1,H2,H3,H4,V1,V2,V3,V4]))).
[backcheck,brickwork,zombifies,jellybean,earreoded,akecabele,nhgwpfabz,acmrremad]
[earreoded,akecabele,nhgwpfabz,acmrremad,backcheck,brickwork,zombifies,jellybean]
% 48 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
true.