Prolog:用复合词中的其他原子替换原子

时间:2013-11-16 18:02:59

标签: prolog traversal functor

我正在尝试编写一个简单的prolog程序,它应该用另一个原子替换原子。该程序可以将复杂的函子作为输入,并用另一个原子替换所有原子。

e.g。在下面的术语中,我想在我遇到叶子的地方(即不是函子名称)用ax替换原子a。

replace(put(a,table,aside(a(dont,replace),a)),X).

应该产生输出,

X = put(ax,table,aside(a(dont,replace),ax));
false.

在上面的输出中,除了函子名称之外,用ax替换了a。在某种程度上,所有的叶子都被替换了。但不是内部节点。

我试过了,

replace([],[]).
replace([H | T], [H1 | T1]):-
        (
        atom(H), (H == a)  %If it's an atom and equal to a, then replace H1 with ax.
        -> H1 = ax, replace(T, T1)  %and recursively follow the same for T.
        ; H1 = H, T1 = T, replace(T, T1)  %else keep things as it is and recurse.
        ).
replace(L, R):-
        functor(L, F1, A1),    %if it's a functor then don't do anything, just follow
        functor(R, F1, A1),    %for the args of the functor.
        L =.. [F1 | Args1],
        R =.. [F1 | Args2],

        replace(Args1, Args2),!.

问题1.我收到相同输入的浅输出

replace(put(a,table,aside(ad,a,toe)),X).
X = put(ax,table,aside(ad,a,toe)).

问题2.当算子的arity改变时,我的谓词会失败。例如,

replace(put(a,table,aside(a(dont,replace),a)),X).
Undefined predicate: substit/2

我意识到我的方法可能不是最好的方法。 有人可以帮我解决问题或提出新方法。

感谢。

1 个答案:

答案 0 :(得分:2)

可以更简单的方式完成

replace(X,Y,X,Y) :- !.
replace(X,Y,S,R) :-
    S =.. [F|As], maplist(replace(X,Y),As,Rs), R =.. [F|Rs], !.
replace(_,_,U,U).

同样,您的代码应该简化很多

replace([],[]).
replace([H | T], [H1 | T1]):-
        (  H == a   
        -> H1 = ax  
        ;  replace(H, H1) 
        ),
    replace(T, T1).
replace(L, R):-
        L =.. [F1 | Args1],
        replace(Args1, Args2),
        R =.. [F1 | Args2].

现在

?- replace(put(a,table,aside(a(dont,replace),a)),X).
X = put(ax, table, aside(a(dont, replace), ax)) 

?- replace(put(a,table,aside(a(dont,replace),a)),X).
X = put(ax, table, aside(a(dont, replace), ax))