Replace 如何用Prolog替换二叉树中出现的每一个值

Replace 如何用Prolog替换二叉树中出现的每一个值,replace,tree,prolog,Replace,Tree,Prolog,我的代码有问题,我不明白为什么它不适合我。它在第一次出现时停止,只替换一次出现。任务是将二叉树中出现的每一个值替换为另一个值,如下面的示例所示 这是一个示例树: testTreeReplace(t2, tree(a,tree(1,tree(a,tree(6,-,-),tree(9,-,-)),-),tree(8,-,tree(a,tree(20,-,-),tree(3,-,-))))). 这就是我使用的代码: replace(X,Y,TreeIn,TreeOut) :- testTre

我的代码有问题,我不明白为什么它不适合我。它在第一次出现时停止,只替换一次出现。任务是将二叉树中出现的每一个值替换为另一个值,如下面的示例所示

这是一个示例树:

testTreeReplace(t2, tree(a,tree(1,tree(a,tree(6,-,-),tree(9,-,-)),-),tree(8,-,tree(a,tree(20,-,-),tree(3,-,-))))).
这就是我使用的代码:

replace(X,Y,TreeIn,TreeOut) :-
    testTreeReplace(TreeIn,T),
    replaceH(X,Y,T,TreeOut).

replaceH(X,Y,tree(X,L,R),tree(Y,L,R)).

replaceH(X,Y,tree(A,L,R),tree(A,L,New)) :-
    replaceH(X,Y,R,New).

replaceH(X,Y,tree(A,L,R),tree(A,New,R)) :-
    replaceH(X,Y,L,New).
输出为:

?- replace(a,b,t2,Res).
Res = tree(b, tree(1, tree(a, tree(6, -, -), tree(9, -, -)), -), tree(8, -, tree(a, tree(20, -, -), tree(3, -, -)))) ;
Res = tree(a, tree(1, tree(a, tree(6, -, -), tree(9, -, -)), -), tree(8, -, tree(b, tree(20, -, -), tree(3, -, -)))) ;
Res = tree(a, tree(1, tree(b, tree(6, -, -), tree(9, -, -)), -), tree(8, -, tree(a, tree(20, -, -), tree(3, -, -)))) ;
false.
但应该是这样

Res = tree(b, tree(1, tree(b, tree(6, -, -), tree(9, -, -)), -), tree(8, -, tree(b, tree(20, -, -), tree(3, -, -)))).
(所有a都应该是b)


此外,我不想使用额外的图书馆。提前感谢您

您不应该在递归中进行分支,因为这意味着在其中一个答案中,您将只替换元素(如果匹配),在另一个答案中,您将在左子树中递归,在右子树中的另一个答案中递归

因此,我们可以首先做一个谓词,检查
Z
是否等于
X
,如果是

replaceValue(X, Y, Z, R) :-
    (  X == Z
    -> R = Y
    ;  R = Z
    ).
因此,这给了我们:

?- replaceTree(a, b, tree(a, tree(1, tree(a, tree(6, -, -), tree(9, -, -)), -), tree(8, -, tree(a, tree(20, -, -), tree(3, -, -)))), T).
T = tree(b, tree(1, tree(b, tree(6, -, -), tree(9, -, -)), -), tree(8, -, tree(b, tree(20, -, -), tree(3, -, -)))) ;
false.

您不应该在递归中进行分支,因为这意味着在其中一个答案中,您将只替换元素(如果它匹配),在另一个答案中,您将在左子树上递归,在右子树的另一个答案中递归

因此,我们可以首先做一个谓词,检查
Z
是否等于
X
,如果是

replaceValue(X, Y, Z, R) :-
    (  X == Z
    -> R = Y
    ;  R = Z
    ).
因此,这给了我们:

?- replaceTree(a, b, tree(a, tree(1, tree(a, tree(6, -, -), tree(9, -, -)), -), tree(8, -, tree(a, tree(20, -, -), tree(3, -, -)))), T).
T = tree(b, tree(1, tree(b, tree(6, -, -), tree(9, -, -)), -), tree(8, -, tree(b, tree(20, -, -), tree(3, -, -)))) ;
false.

在你的谓词中你分支:在一个分支中你替换左子树,在另一个分支中你替换右子树(在顶部,你只替换元素本身)。你有没有想法改变我的代码,这样整个事情就可以进行了?在你的谓词中你分支:在一个分支中你替换左子树,在另一个分支中替换右子树(在顶部,您只替换元素本身)。您有没有想法更改我的代码,这样整个过程就可以运行了?我认为很难在这里选择合适的等式-一方面,我想我们经常会搜索特定的事件(如您实现的)但它会排除一些有趣的应用程序,比如将所有物品从厨房移到壁橱(即,将
loc(X,厨房)
替换为
loc(X,壁橱)
)。我认为很难在这里选择一个适当的等式——一方面,我会想象我们通常真的很想搜索某个特定事件(如您实现的)但它将排除一些有趣的应用程序,如将所有物品从厨房移到壁橱(即,将
loc(X,厨房)
替换为
loc(X,壁橱)
)。