这个prolog纵横字谜解算器是如何工作的?
我正在尝试编写一个纵横字谜解算器。我有这段代码,但我无法理解其中的某些部分:这个prolog纵横字谜解算器是如何工作的?,prolog,crossword,Prolog,Crossword,我正在尝试编写一个纵横字谜解算器。我有这段代码,但我无法理解其中的某些部分: size(5). black(1,3). black(2,3). black(3,2). black(4,3). black(5,1). black(5,5). words([do,ore,ma,lis,ur,as,po, so,pirus, oker,al,adam, ik]) . :- use_module(library(lists),[nth1/3, select/3]). crossword(Puzzl
size(5).
black(1,3).
black(2,3).
black(3,2).
black(4,3).
black(5,1).
black(5,5).
words([do,ore,ma,lis,ur,as,po, so,pirus, oker,al,adam, ik]) .
:- use_module(library(lists),[nth1/3, select/3]).
crossword(Puzzle) :-
words(WordList),
word2chars(WordList,CharsList),
make_empty_words(EmptyWords) ,
fill_in(CharsList,EmptyWords),
word2chars(Puzzle,EmptyWords).
word2chars([],[]).
word2chars([Word|RestWords] ,[Chars|RestChars] ) :-
atom_chars(Word,Chars),
word2chars(RestWords,RestChars).
fill_in([],[]).
fill_in([Word|RestWords],Puzzle) :-
select(Word,Puzzle,RestPuzzle),
fill_in(RestWords,RestPuzzle).
make_empty_words(EmptyWords) :-
size(Size),
make_puzzle(Size,Puzzle),
findall(black(I,J),black(I,J),Blacks) ,
fillblacks(Blacks,Puzzle),
empty_words(Puzzle,EmptyWords).
make_puzzle(Size,Puzzle) :-
length(Puzzle,Size),
make_lines(Puzzle,Size).
make_lines([],_).
make_lines([L|Ls],Size) :-
length(L,Size),
make_lines(Ls,Size).
fillblacks([],_).
fillblacks([black(I,J)|Blacks],Puzzle) :-
nth1(I,Puzzle,LineI),
nth1(J,LineI,black),
fillblacks(Blacks,Puzzle).
empty_words(Puzzle,EmptyWords) :-
empty_words(Puzzle,EmptyWords,TailEmptyWords),
size(Size),
transpose(Size,Puzzle,[],TransposedPuzzle),
empty_words(TransposedPuzzle,TailEmptyWords,[] ).
empty_words([],Es,Es).
empty_words([L|Ls],Es,EsTail) :-
empty_words_on_one_line(L,Es,Es1) ,
empty_words(Ls,Es1,EsTail).
empty_words_on_one_line([], Tail, Tail).
empty_words_on_one_line([V1,V2|L],[[V1,V2|Vars]|R],Tail) :-
var(V1), var(V2), !,
more_empty(L,RestL,Vars),
empty_words_on_one_line(RestL,R,Tail) .
empty_words_on_one_line([_| RestL],R, Tail) :-
empty_words_on_one_line(RestL,R,Tail) .
more_empty([],[],[]).
more_empty([V|R],RestL,Vars) :-
( var(V) ->
Vars = [V|RestVars],
more_empty(R,RestL,RestVars)
;
RestL = R,
Vars = []
).
transpose(N,Puzzle,Acc,TransposedPuzzle) :-
( N == 0 ->
TransposedPuzzle = Acc
;
nth_elements(N,Puzzle,OneVert),
M is N - 1,
transpose(M,Puzzle,[OneVert|Acc], TransposedPuzzle)
).
nth_elements(_,[],[]).
nth_elements(N,[X|R],[NthX| S]) :-
nth1(N,X,NthX),
nth_elements(N,R,S).
此代码用于解决如下纵横字谜:
什么是符号代码>->
用于什么
我的主要问题是理解规则,转置和多空。
任何帮助我理解代码的解释都将不胜感激。这些是Prolog的if-then-else控制结构
语法如下:
条件->然后声明/减速;其他的
声明/豁免
->
和
是Prolog的控制流,就像其他语言中的if-then-else语句一样。因此:
transpose(N,Puzzle,Acc,TransposedPuzzle) :-
( N == 0 ->
TransposedPuzzle = Acc
;
nth_elements(N,Puzzle,OneVert),
M is N - 1,
transpose(M,Puzzle,[OneVert|Acc], TransposedPuzzle)
).
转换为伪代码:
def transpose(N, Puzzle, Acc)
if N == 0
return Acc
else
OneVert = nth_elements(N, Puzzle)
transpose(N-1, Puzzle, [OneVert, Acc])
或:
这会让你知道它的作用。我建议你自己将more\u empty
函数翻译成psuedocode(或者在头脑中一步一步地进行),然后试着从那里解决它。除了Josh和Avi Tshuva的正确答案,他们说a->b;c
就像“如果a那么b就等于c”,我想解释一下->
和代码>是可以单独使用的单个运算符
代码>是逻辑析取,即逻辑“或”。Sox;y
表示“x或y”。这使得条件语句有点混乱,因为a->b;c
读起来像“a意味着b或c”,这显然不是它的意思!即使像“(a意味着b)或“c”这样插入,也会从条件语句中得到不同的含义,因为在这种错误的解释中,即使(a意味着b)成功,也会尝试使用c
区别在于->
有一些“非逻辑”语义。发件人:
:条件->:操作If-then和If-then-Else。->/2
构造提交在其左侧所做的选择,销毁在子句内部创建的选择点(通过;/2
),或通过此子句调用的目标。不像/0时,谓词的选择点作为一个整体(由于多个子句)不会被销毁。组合/2
和->/2
的定义如下:
如果->那么_其他:-如果!,那么。
如果->\u则;其他:-!,其他的
如果->然后:-如果!,那么。
请注意,(If->Then)
充当(If->Then;fail)
,使构造在条件失败时失败。这种不寻常的语义是ISO和所有事实上的Prolog标准的一部分
(请注意,在上面的引文中,如果
,那么
等都是变量!)
所以要当心任何带有隐含含义的东西 它不是重复的,它只是有相同的代码,但有不同的问题问它!在这个例子中,有人问了一个关于如何修改代码以获得某种结果的问题,但这个问题是关于代码的某些部分很难理解!格式错误?!我从一本名为《第一次10个PROLOG编程竞赛》的书中获得了这段代码,你如何判断这样的代码?这是序言,很难理解,但它的格式没有问题。我对代码还有一些其他问题,所以我发布了一个不同的问题。那么问题出在哪里呢?书中的缩进是无可挑剔的。您在转置/4
中添加了额外的混乱行和错误缩进,以及更多内容代码>,以及->
,请参见,例如。你是否试图在不学习语言语法基础的情况下解决Prolog竞赛问题?抛开那么多代码,问“dis如何工作”从来都不是一个好的提问方式。还有:你把身份搞乱了。另外:你的问题是关于(条件->行动;其他)的吗?还是关于转置?还是关于统一?Prolog不是我的强项语言之一,所以如果我犯了任何错误,请道歉。
def transpose(N, Puzzle, Acc)
while N > 0
OneVert = nth_elements(N, Puzzle)
Acc = [OneVert, Acc]
N = N - 1
return Acc