我正在尝试编写填字游戏解算器我已经有了这段代码,但我无法理解它的某些部分:
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).
此代码用于解决这样的填字游戏:
符号;
->
用于什么?
我的主要问题是理解规则,转置和 more_empty 。 任何解释,以帮助我理解代码将不胜感激。
答案 0 :(得分:2)
->
和;
是Prolog的控制流程,如 if - 然后 - 其他声明在其他语言。所以:
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])
或:
def transpose(N, Puzzle, Acc)
while N > 0
OneVert = nth_elements(N, Puzzle)
Acc = [OneVert, Acc]
N = N - 1
return Acc
这应该会让你知道它的作用。我建议你自己将more_empty
函数翻译成psuedocode(或者只是在脑海中逐步完成),然后尝试从那里开始。
答案 1 :(得分:1)
这些是Prolog的if-then-else控制结构。
语法如下:
条件 - >陈述/减速;其他 语句/ declerations
答案 2 :(得分:1)
除了Josh和Avi Tshuva的正确答案之外,a -> b ; c
就像“如果是另外一个c”,我想解释->
和;
是可以单独使用的各个操作员。
;
是逻辑 disjunction ,即。逻辑“或”。所以x; y
表示“x或y”。这使条件语句有点混乱,因为a -> b ; c
读起来像“a暗示b或c”,这显然不意味着什么!即使你将它括起来,如“(a暗示b)或c”,你也会从条件陈述中得到不同的含义,因为在这种不正确的解释中,即使(a暗示b)成功,也总会尝试c。
不同之处在于->
具有一些“非逻辑”语义。来自SWI-Prolog docs:
:条件 - > :动作
If-then和If-Then-Else。->/2
构造提交在其左侧做出的选择,破坏在子句内创建的选择点(通过;/2
),或者通过该子句调用的目标。与!/0
不同,谓词作为一个整体的选择点(由于多个子句)不会被破坏。合并;/2
和->/2
的行为就像定义为:
If -> Then; _Else :- If, !, Then. If -> _Then; Else :- !, Else. If -> Then :- If, !, Then.
请注意(If -> Then)
充当(If -> Then ; fail)
,如果条件失败,则构造失败。这种不同寻常的语义是ISO和所有事实上的Prolog标准的一部分。
(请注意,在上面的引文中,If
,Then
等是变量!)
请注意隐含cut的任何内容!