Prolog: Replace an atom by other atom in compound terms

旧时模样 提交于 2019-12-13 00:03:51

问题


I am trying to write a simple prolog program which should replace an atom by another atom. The program can take complex functor as an input and would replace all the atoms by another atoms.

e.g. In the below term, I want to replace atom a by ax only where I encounter a leaf (i.e. not a functor name).

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

which should produce output,

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

In the above output, replaced a with ax everywhere except the functor name. In a way all the leaves are replaced. But not internal nodes.

I have tried following,

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),!.

Problem 1. I receive shallow output for the same input

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

Problem 2. My predicate would fail when arity of the functor changes. For example,

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

I realize my approach might not be the best one. Can someone please help me either fix the issues or suggest a new approach.

Thanks.


回答1:


can be done more generally in simpler way

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).

similarly, your code should be simplified a lot

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].

now

?- 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)) 


来源:https://stackoverflow.com/questions/20021844/prolog-replace-an-atom-by-other-atom-in-compound-terms

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!