2016-11-15 7 views
0

私はプロローグを初めて使っています。私は完全に動作するマジックスクエアプログラムを作成しようとしていますが、真実を言うにはどうすればいいのか分かりません。それは間違っている。私は自分のコードを共有しています。誰かが私を助けてくれることを願っています。今は数字が良いときには本当ですが、そうでないときはスタックエラーのようになります...(ここでは、チェック) ご注意いただきありがとうございます!プログラミング1でマジックスクエアNxN

:- 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

マジックスクエアを生成しようとしていますか、入力されたスクエアがマジックであるかどうかを確認していますか? – bendl

+0

あなたのマジックスクエアのルールは何ですか?あなたのコードを見ると、私はそれらを推測することができますが、明示的に書き留めても害はありません。 –

+2

別のこと:これは質問をする悪い方法です。あなたが実際に特定の問題を指摘すれば、可能な限り小さなコードで、あなたが解決しようとした方法を説明し、なぜそうすることができないのかを説明する方がずっと良いでしょう。現時点では、それは "コードレビュー"の問題であり、これはStackoverflowに属しません。 –

答えて

2

しばしばこの世界 /プログラムの無数のトピック間の相互接続が簡単にきれいに分割することはできませんので、

すべてが深く... intertwingledされていることを前提としています。 1

しかし、Prologでは時には物事をもっときれいに分けることができます。特に、に集中する場合は、単一のプロパティが非終了のようになります。それで、サイズ1の魔方陣を考えてみましょう—本当に魔法です!そうであるようにを:

 
?- 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を追加することを改善する必要があります。

さて、all_different/1の前でfalseでプログラムを考えると、私が手:推論の非常に多くのように見えること

?- time(magicSq(List, 3)). 
% 8,571,007 inferences 

!実際に、あなたがやっていることは、すべての可能な構成を最初に列挙することです。したがって、あなたは制約プログラミングの力を使用しません。これに関するチュートリアルをご覧ください。 Start here

ただし、ここで問題は解決しません。これ以上のことはありますが、残りのプログラムは全く理解しにくいです。完全に無関係な場所で!を使用しているためです。

関連する問題