Recursion 在prolog中等值节点?

Recursion 在prolog中等值节点?,recursion,tree,prolog,Recursion,Tree,Prolog,我正在研究一个小函数,它检查一棵树是否只是另一棵树的反转版本 比如说, 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,t

我正在研究一个小函数,它检查一棵树是否只是另一棵树的反转版本

比如说,

  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)).
我的依据如下:

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)).
基本情况是两个叶子相等,这只返回true。如果它有一个节点,则检查叶是否相等,并在该节点上递归调用该函数

如果是两个节点,请检查树是否相等,然后在从第二棵树翻转节点后调用递归函数


我的问题是,我一直在犯错误

ERROR: is/2: Arithmetic: `leaf/1' is not a function
问题是,当在树上使用其他操作时,我没有得到这个错误。有没有关于如何避免这种情况的建议?唯一的限制是我不能使用
=

根据google和stackoverflow上的搜索,我还认为最有可能的原因是
的两侧不返回相同的“类型”。但我的看法是,这里不应该是这样,因为我两端的东西几乎完全一样



感谢阅读,非常感谢您的帮助:)

is/2谓词用于算术。它计算表达式(第二个参数)的值并将其分配给变量第一个参数。例如:
X是1+(2*Y)/2
其中Y已经实例化,因此它有一个值(为了计算表达式的值,否则它会抛出实例化错误)

在您的情况下,您不能使用is/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).
。。。然后调用递归函数

Prolog谓词不是函数。编写
node1(Leaf1,treeRev(node1))
不会像在其他编程语言中那样,构建具有“调用
treeRev
函数的结果”的节点。相反,Prolog谓词为“result”提供了额外的参数。您通常调用谓词并将这些“结果”绑定到一个变量或用一个术语统一它

对于二进制节点,您将需要类似的内容(未经测试,且不遵循老师奇怪且未记录的树表示):


嗨,谢谢:)但我想避免的是需要使用“=”。没有统一,有没有办法得到同样的结果?我知道这是一个很大的限制,但这就是问题的条件。当然,我只是试着解释is/2失败的原因。所以你需要使用某种统一。如果您有不使用=/2的限制,那么可以通过使用模式匹配(这也是统一,但不使用=symbol)来实现。我会更新我的答案…太棒了,伙计,你的想法很有道理。非常感谢,我很感激:)