2016-12-03 2 views
1

私は、ツリーが別のツリーの逆のバージョンであるかどうかを調べる小さな関数に取り組んでいます。例えば プロローグ内のノードを等しくする?

1    1 
2 3 = 3 2 
1     1 

私のコードは次のちょうどバージョンです:

私の基礎は、以下の通りである
treeRev(leaf(Leaf1), leaf(Leaf2)) :- 
    leaf(Leaf1) is leaf(Leaf2). 

treeRev(node1(Leaf1, Node1), node1(Leaf2, Node2)) :- 
    node1(Leaf1,treeRev(Node1)) is node1(Leaf2, treeRev(Node2)). 

treeRev(node2(Leaf1, Node1, Node2), node2(Leaf2, Node3, Node4)) :- 
    node2(Leaf1, treeRev(Node1), treeRev(Node2)) is 
     node2(Leaf2, treeRev(Node4), treeRev(Node3)). 

ベースケースは、2枚の葉が等しいです、ただ真実を返します。ノードが1つの場合は、葉が等しいかどうかをチェックし、そのノードで再帰的に関数を呼び出します。

2つのノードの場合は、ツリーが等しいかどうかを確認し、2つ目のツリーからノードを反転した後に再帰関数を呼び出します。木の上で他の操作を使用している場合


私の問題は、私は

ERROR: is/2: Arithmetic: `leaf/1' is not a function 

事があるバグを得続ける、ですが、私はこのエラーを得ることはありません。これを回避する方法に関するアドバイスはありますか?唯一の制限は、=を使用できないことです。

私はまた、最も可能性の高い原因は、isの側がgoogleとstackoverflowの検索によると、同じ "タイプ"を返していないということです。私はそれを見ている方法は、私は両端にほぼ同じことがあるので、ここではそうすべきではありません。


をお読みいただきありがとうございました、そして任意のヘルプは大歓迎です:)

答えて

1

ザ・ある/ 2述語は、演算に使用されています。式の値(第2引数)を計算し、第1引数に代入します。例: X is 1+(2*Y)/2ここで、Yはすでにインスタンス化されているため、値があります(そうでない場合は式の値を計算するためにインスタンス化エラーがスローされます)。

あなたは、/ 2を使用することはできません。なぜなら、算術式を計算したくないからです(そのためにエラーが発生します)。必要なものは統一です。=を使用して、用語(リーフやノードなど)を別の用語と統一する必要があります。たとえば :あなたのパターンマッチングを使用することにより

treeRev(leaf(Leaf1), leaf(Leaf2)) :- 
    leaf(Leaf1) = leaf(Leaf2). 

treeRev(node1(Leaf1, Node1), node1(Leaf2, Node2)) :- 
    node1(Leaf1,treeRev(Node1)) = node1(Leaf2, treeRev(Node2)). 

treeRev(node2(Leaf1, Node1, Node2), node2(Leaf2, Node3, Node4)) :- 
    node2(Leaf1, treeRev(Node1), treeRev(Node2)) = 
     node2(Leaf2, treeRev(Node4), treeRev(Node3)). 

は、単に行うことができます:

treeRev(leaf(Leaf2), leaf(Leaf2)). 

treeRev(node1(Leaf2, treeRev(Node2)), node1(Leaf2, Node2)). 

treeRev(node2(Leaf2,Node1,Node2), node2(Leaf2, Node3, Node4)):- 
      treeRev(Node1,Node4),treeRev(Node2,Node3). 
+0

こんにちは、ありがとう:)しかし、私は避けるようにしようとしていることです'='を使用する必要があります。統一なしで同じ結果を得る方法はありますか?私はその限界を知っていますが、それは問題の条件です。 –

+0

もちろん、私はちょうど/ 2が失敗した理由を説明しようとしました。ですから、何らかの統一を使用する必要があります。 =/2を使用しないという制限がある場合は、パターンマッチング(これも統一ですが、=記号は使用しません)を使用して行うことができます。私は私の答えを更新します... – coder

+0

それは素晴らしい人です、あなたがそれを考えた方法は、多くの意味があります。ありがとう、私はそれを感謝します:) –

1

...その後、再帰関数を呼び出す...

Prologの述語がありません機能。 node1(Leaf1,treeRev(Node1))を書くことで、他のプログラミング言語と同様に、 "treeRev関数の呼び出し結果"を持つノードは構築されません。代わりに、Prolog述部には、「結果」に対する余分な引き数があります。通常、述語を呼び出して、そのような「結果」を変数にバインドするか、変数に統一します。

あなたは(あなたの教師の奇妙で文書化されていないツリー表現を、次のテストされていない、としない)、バイナリノードのために、このようなものが必要になります。

tree_mirrored(node(LeftTree, RightTree), node(RightMirrored, LeftMirrored)) :- 
    tree_mirrored(LeftTree, LeftMirrored), 
    tree_mirrored(RightTree, RightMirrored). 
関連する問題