这个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”,我想解释一下
->
是可以单独使用的单个运算符

是逻辑析取,即逻辑“或”。So
x;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