2017-05-23 15 views
0

私はtileという4つのパラメータを使用する関数を持っています。 E, S, WN:私はID与えられ、それは最初の4つのパラメータを返すgetter関数を希望Prolog - シンプルな関数を作成する

tile(?E, ?S, ?W, ?N, ?ID) 

:次のように動作するように設計されています。 私はのようなものを試してみました:

coordonates(tile(E,S,W,N,L), (E,S,W,N)). 

しかし、それは実際の値を返しません、だけtrue。 端末にtile(E, S, W, N, #1)と入力すると、望みの結果が得られますが、正確に何が返されたのかわかりません(リストが多分?)。

+3

:-)はるかに短くすることができませんでした。同じことがCoordst(E,S,W,N)のために行きます* 5 *引数。 *ターミナルに 'tile(E、S、W、N、#1)'と入力すると、望みの結果が得られますが、返されるものは正確にはわかりません。 * predicates *(関数ではありません)は値を返しません。彼らは成功するか失敗するだけです。 「真の」応答はそれが成功したことを意味します。 – lurker

+0

@lurker "真の応答が成功したことを意味する" ... *偽*応答はどういう意味ですか?どうも。 – Kintalken

+1

A * false *応答はそれ以上解決策を見つけることができなかったことを意味します。 1つまたは複数の解を見つけた後に* false *または* no *応答が発生する可能性がありますが、残りの選択肢点があり、解が見つからない場合は、* false *または* no *応答を得ることができます。言い換えれば、述語を呼び出すことができ、それは何の解決策もなしに失敗するか、または1つまたは複数の解決策を成功裏に生成し、最終的にはそれ以上の探索を失敗する可能性があります。これは、Prologの動作と他のプログラミング言語の基本的な違いです。 – lurker

答えて

3

のは、次のように見えるtileを説明私たちの事実を仮定してみましょう:

我々は有限数を持っている。この中
tile(p1,p2,p3,p4,id1). 
tile(q1,q2,q3,q4,id2). 
tile(r1,r2,r3,r4,id3). 

事実のそれはtileのための最も一般的なクエリで確認することができます。

?- tile(E,S,W,N,I). 
E = p1, 
S = p2, 
W = p3, 
N = p4, 
I = id1 ;    % <---- user input ; to continue 
E = q1, 
S = q2, 
W = q3, 
N = q4, 
I = id2 ;    % <---- user input ; to continue 
E = r1, 
S = r2, 
W = r3, 
N = r4, 
I = id3.    % <---- toplevel outputs . -- we're done 

次のように理論​​的には、我々はcoordonatesを定義することができます。

次のように id2を照会することができ
coordonates(id1, t(p1, p2, p3, p4)). 
coordonates(id2, t(q1, q2, q3, q4)). 
coordonates(id3, t(r1, r2, r3, r4)). 

?- coordonates(id2,X). 
X = t(q1, q2, q3, q4). 

ファンクタtを使用して解をグループ化し、述語ではないことを明確にしましたtile以前に定義した。この定義にはすでに多くの繰り返しがありますが、それはヒントであり、私たちはより良いことができます。私たちが探しているのは、tileの回答があれば、coordonatesと書くことができます。論理的に言えば、これは、goal1∧...∧goalN→headという形式の意味として書かれています。 「ゴール1からゴールNまでが真であることを知っていると仮定すると、頭が真実であることもわかります」プロローグでは、これは逆方向に書かれている:

head :- 
    goal1, 
    % ... 
    goalN. 

は、私たちの仕事に戻りましょう:私たちは、タイルについて何かを知っているし、我々は、投影がどのように見えるかを説明したいと思います。これは、次のように我々のコードが見える、意味:

coordonates(...) :- 
    % ... 
    tile(E,S,W,N,I). 

tile(E,S,W,N,I)は、私たちが書くことができる最も一般的な形式である(上記の私たちのクエリを参照)、私はidを持つESWNを座標に任意のタイルを持っていると仮定」と読むことができます"今度は、coordonatesのようにする必要があります。 idに4つの他の要素を関連付けるので、2つの引数があることがわかります。それらに名前をつけることができます、IdCoordsを言う:

coordonates(Id, Coords) :- 
    % ... 
    tile(E,S,W,N,I). 

は、今、私たちはIDのみとCOORDSとNとI、E、S、Eに関連する方法を見つける必要があります。1つは簡単です:IdはちょうどIです。もう1つはあまりにも難しくないので、座標を1つの項にグループ化するだけです。我々は、任意のものを選ぶが、すでに上記tを取ることにしたので、我々はそれに固執することができます。

coordonates(Id, Coords) :- 
    Id = I, 
    Coords = t(E,S,W,N), 
    tile(E,S,W,N,I). 

これはすでに我々が期待通りに動作します

?- coordonates(X,Y). 
X = id1, 
Y = t(p1, p2, p3, p4) ; 
X = id2, 
Y = t(q1, q2, q3, q4) ; 
X = id3, 
Y = t(r1, r2, r3, r4). 

今、私たちは1つの観察を行うことができます。 2つの項が等しい場合、もう一方の項の代わりに1つを使用できます。したがって、Id = Iを書く代わりに、Idを再利用することができます。私は4つのパラメータを使用する機能を持っている* * ...あなたが実際に持っている*述語*を持っている

coordonates(I, t(E,S,W,N)) :- 
    tile(E,S,W,N,I). 

それは

0

'E、S、W、N'を宣言して、プロローグでクエリを入力するときにこれらのパラメータを統一できるようにする必要があります。 (最も基本的な場合)のようなもの:

tile(['cordE1','cordS1','cordW1','cordN1'],1). 
tile(['cordE2','cordS2','cordW2','cordN2'],2). 
tile(['cordE3','cordS3','cordW3','cordN3'],3). 

問合せ:

?- tile(C,2). 
C = [cordE2, cordS2, cordW2, cordN2]. 

?- tile(C,1). 
C = [cordE1, cordS1, cordW1, cordN1]. 

?- tile(C,3). 
C = [cordE3, cordS3, cordW3, cordN3]. 
関連する問題