2017-03-21 13 views
2

Bert Bos puzzle用のボードの作成に取り掛かっていますが、ボードをリストのリストとして表現しようとしています。Prolog:空リストのリストを作成

私は空リストのリストを作成する必要があります。[ [], [] , [] , [] ]ですが、入力からの空リストの正確な数が必要です。たとえば、create_board(4、X)を指定すると、X= [ [], [], [], [] ]が返されます。ここで

私は構文エラーのカップルから、これまで

generate_board(0, [[]]) :- ! 
generate_board(N, [[] | T]) :- 
    N =< 12, N >= 1, 
    N is N-1. 
    generate_board(N, T). 
+2

ニースパズル!リンクありがとう – CapelliC

答えて

0

別に持っているもので、あなたのコードの主な問題は、ラインN is N-1です。 Prologでは、変数を再割り当てすることはできません。変数は、述部を通して単一の値を持ちます。 「NはN-1である」は、それ自体が-1である値に対してのみ成功することができ、明らかに決してそうではない。それを修正

は簡単です:ちょうど換算値のために別の変数を使用します。

generate_board(0, [[]]) :- !. 
generate_board(N, [[] | T]) :- 
    N =< 12, N >= 1, 
    N2 is N-1, 
    generate_board(N2, T). 

?- generate_board(4, X). 
X = [[], [], [], [], []] 

これは結果を与えるが、それは意図したよりも、もう一つの要素です。これを自分で修正する方法を理解できますか(ヒント:基本ケースが入力0のために返すものを見てください)

5

同じ要素からなる指定された長さのリストを作成する簡単な方法です。場合、maplist2を使用することである:ここ

generate_board(Length, Board) :- 
    length(Board, Length), 
    maplist(=([]), Board). 

maplist(=([]), Board)したがって[]と各要素を統合、BoardElementため=([], Element)[] = Elementの標準形式)を呼び出します。

この概念を拡張して、2次元の空のボードを作成することができます。 (長さWidthで)要素のリストとして(長さLengthで)行のリストとしてボードを考えると、各行:ここ

generate_board(Length, Width, Board) :- 
    length(Row, Width), 
    maplist(=([]), Row),   % A row of empty lists, forming an empty row 
    length(Board, Length), 
    maplist(=(Row), Board).  % A list of empty rows 

| ?- generate_board(4,3, L). 

L = [[[],[],[]],[[],[],[]],[[],[],[]],[[],[],[]]] 

yes 
| ?- 
4

は、あなたのプログラムが(離れてから動作しなかった理由だけの理由であります,の代わりに.)。このフラグメントが失敗するため、元のプログラムも失敗します。あなたは何とか見える部分を一般化しなければなりません。

 
:- op(950,fy,*). 
*_. 

generate_board(0, [[]]) :- ! 
generate_board(N, _/*[[] | T]*/) :-  % 2nd 
    * N =< 12,        % 2nd 
    * N >= 1,        % 2nd 
    N is N-1, 
    * generate_board(N, T).     % 1st generalization 

?- generate_board(4, B). 

このメソッドは、純粋な単調なPrologプログラムで機能します。しかし、あなたは一般化を制限するカットを使いました。この場合、カット前に何かを一般化しないように注意を払う必要があります。したがって、最初の一般化は再帰的な目標です。この条項の最後の目標です。だけにして、他の一般化はカットせずに、あなたのプログラムで行わ

をとることができ、我々はさらに、あなたのプログラムを一般化している可能性:

 
generate_board(0, _/*[[]]*/). 
... 
2

シンプルなソリューション:

generate_board(N, Board) :- 
    findall([], between(1, N, _), Board). 
関連する問題