Recursion Prolog中的镜像二叉树

Recursion Prolog中的镜像二叉树,recursion,prolog,binary-tree,Recursion,Prolog,Binary Tree,我所拥有的 tree(nil). tree(b(Left,_,Right)) :- tree(Left), tree(Right). mirror(b(Left,Head,Right), NewTree) :- mirror(Left,NewLeft), mirror(Right,NewRight), NewTree = b(NewRight,Head,NewLeft). 我质疑的是 mirror(b(nil,a,b(nil,b,nil)), Resu

我所拥有的

tree(nil).
tree(b(Left,_,Right)) :-
    tree(Left),
    tree(Right).

mirror(b(Left,Head,Right), NewTree) :-
    mirror(Left,NewLeft),
    mirror(Right,NewRight),
    NewTree = b(NewRight,Head,NewLeft).
我质疑的是

mirror(b(nil,a,b(nil,b,nil)), Result).
预期结果

Result = b(b(nil,b,nil),a,nil).
树b(左、右、头)是镜像的第一个参数,新树是目标。镜像(Left,NewLeft)通过左侧递归,并生成目标NewLeft,与右侧相同。NewTree是树b(NewRight,Head,NewLeft)


我不知道为什么这不起作用。请有人帮忙。

根据您当前的代码

tree(nil).
tree(b(Left,_,Right)) :-
    tree(Left),
    tree(Right).

mirror(b(Left,Head,Right), NewTree) :-
    mirror(Left,NewLeft),
    mirror(Right,NewRight),
    NewTree = b(NewRight,Head,NewLeft).
你很接近

正如史蒂文在评论中指出的那样


您缺少镜像/2的基本机箱。当输入树为nil时,NewTree应该是什么

这很有帮助

在开始完整的工作谓词之前,让我们先清理一下其他事情。
树的谓词是不需要的

tree(nil).
tree(b(Left,_,Right)) :-
    tree(Left),
    tree(Right).
我不知道你是不是在向我们展示这个,告诉我们你知道一棵树是如何工作的,或者是什么,但是对于其他阅读这个谓词的人来说,答案并不需要它

只剩下

mirror(b(Left,Head,Right), NewTree) :-
    mirror(Left,NewLeft),
    mirror(Right,NewRight),
    NewTree = b(NewRight,Head,NewLeft).
使用一个类似于输入和输出的变量并具有多种用途的标准样式是,对于开始的变量,附加一个0,然后对于每次后续使用,增加附加的数字,对于结果,不附加任何内容

mirror(b(Left0,Head,Right0), NewTree) :-
    mirror(Left0,Left),
    mirror(Right0,Right),
    NewTree = b(Right,Head,Left).
下一步就是统一。这是可以重构的

mirror(b(Left0,Head,Right0), b(Right,Head,Left)) :-
    mirror(Left0,Left),
    mirror(Right0,Right).
现在回到你的问题上来

由于树是递归结构,因此可以使用递归进行处理。处理递归数据结构的谓词需要一个base子句和一个子句来执行递归。您已经有一个子句来执行递归,但只需要一个base子句

如果在查询代码上使用SWI Prolog gui跟踪器

mirror(b(nil,a,b(nil,b,nil)), Result).
你会看到

当其中一个分支仅为
nil
时,没有镜像/2规则来处理此情况

添加

mirror(nil,nil).
这会解决你的问题

?- mirror(b(nil,a,b(nil,b,nil)), Result).
Result = b(b(nil, b, nil), a, nil).
整个谓词

mirror(nil,nil).

mirror(b(Left0,Head,Right0), b(Right,Head,Left)) :-
    mirror(Left0,Left),
    mirror(Right0,Right).

您缺少
镜像/2
的基本情况。当输入树为
nil
时,NewTree应该是什么?@Steven它应该是nil吗?的确如此。所以只要为它添加一个子句,您的查询就可以了。@Steven好的,我只做了两天的Prolog,请耐心听我说。。。这是否正确
mirror(nil,NewTree):-NewTree=nil。mirror(左,头,右,R):-mirror(左,新左),mirror(右,新右),R=b(新右,头,新左)。
@PabloH这很好,但是把你的最后一句移到头中:
mirror(nil,nil)。
mirror(b(左,头,右),b(新右,头,新左)):-mirror(左,新左),mirror(右,新右)。