我是Prolog的新手,我正在努力编写完全正常的魔术方案,但说实话我真的不知道该怎么办,我已经开始但我觉得我做错了。我正在分享我的代码,我希望有人会帮助我,现在当数字很好时我就会变成现实,但是当它们不是我时,我就会发现堆栈错误...(这里只是检查我知道的有关斜行的行和列校验) 谢谢你的关注!
:- use_module(library(clpfd)).
:- use_module(library(lists)).
magicSq(List, N) :-
Number is N * N,
belongs(Number ,List), % check if numbers are correct.
all_different(List), % check if numbers not occur.
Suma is N*(N*N + 1)/2,
checkC(List,N,N,Suma), % check column
checkR(List,1,N,Suma). % check row
belongs(0, _).
belongs(N, List) :- member(N,List) , Index is N - 1 , belongs(Index, List).
consecutiveSum(_, 0 , _,0).
consecutiveSum(List, HowMuch , From,Sum):-
Index is HowMuch - 1,
From1 is From +1,
nth1(From, List,Element),
consecutiveSum(List,Index,From1,Z),
Sum is Z + Element,!.
sumObliCol(0,_, [], _,_). % sums by columns or obliquely
sumObliCol(X,Number, [H|T], Ind, Residue) :-
Index is Ind + 1,
Y is mod(Index,Number),
Y =:= Residue,
sumObliCol(Z,Number, T, Index,Residue),
X is Z + H, !.
sumObliCol(X,Number, [_|T], Ind,Residue) :-
Index is Ind + 1,
sumObliCol(X,Number, T, Index,Residue).
checkC(_,0,_,_). % check column
checkC(List,N, Number,Answ):-
N1 is N-1,
checkC(List,N1, Number,Answ),
sumObliCol(Ats,Number,List,0,N1),Ats is Answ,!.
checkR(_,N,Number,_):- N>(Number*Number). % check row
checkR(List,N,Number,Answ):-
consecutiveSum(List,Number,N,Sum), Sum is Answ,
N1 is N + Number,
checkR(List,N1, Number,Answ),!.
答案 0 :(得分:3)
在编程中,人们常常认为
一切都在深深地交织在一起......因为这个
world/ program的无数主题之间的交叉关系根本无法整齐划分。1
但是在Prolog中,有时候,我们可以更加整洁地划分事物。特别是,如果你专注于单一属性,如非终止。因此,让我们考虑一下大小的魔术方块 - 确实非常神奇!像这样使用failure-slice:
?- magicSq(Xs,1), false. magicSq(List, N) :- Number is N * N, belongs(Number ,List), false,all_different(List),Suma is N*(N*N + 1)/2,checkC(List,N,N,Suma),checkR(List,1,N,Suma).belongs(0, _) :- false. belongs(N1, List) :- member(N1,List), false,N2 is N1 - 1,belongs(N2, List).
您需要了解的全部内容!显然,List
不受约束,因此目标member(N1, List)
无法终止。这很容易修复,添加目标length(List, Number)
。然而,该计划并没有终止,而是在另一个领域:
?- magicSq(Xs,1), false. magicSq(List, N) :- Number is N * N, length(List, Number), belongs(Number ,List), false,all_different(List),Suma is N*(N*N + 1)/2,checkC(List,N,N,Suma),checkR(List,1,N,Suma).belongs(0, _) :- false. belongs(N1, List) :- member(N1,List), N2 is N1 - 1, belongs(N2, List), false.
现在这不会终止,因为N1
也可能是否定的。我们需要改进添加N1 > 0
。
现在,考虑false
前面有all_different/1
的程序,我得到:
?- time(magicSq(List, 3)).
% 8,571,007 inferences
这看起来像是一个非常多的推论!实际上,您所做的是首先枚举所有可能的配置。因此,您不使用约束编程的权力。请仔细阅读相关教程。 Start here
然而,问题不止于此!还有更多内容,但剩下的程序很难理解,因为你在完全不相关的地方使用!
。