3

I have a term which may or may not contain the atom 'this'. The term may also contain variables. I need to replace 'this' with a variable I. How can I do this? I tried to do something like this:

term_to_atom((f(a), g(this, b), ...), A),

tokenize_atom(A, L),

replace(this, I, L, L2)

It seemed to work. The problem is, I need to go back to the original term and I can't do it...

chameleon
  • 41
  • 5

2 Answers2

0

SWI-Prolog has atomic_list_concat/2 and atom_to_term/2 which should help you go back to the original term.

main :-
    term_to_atom((f(a), g(this, b)), A),
    tokenize_atom(A, L),
    replace(this, 'I', L, L2),
    atomic_list_concat(L2, A2),
    atom_to_term(A2, T, []),
    writeln(T).

?- main.
f(a),g(_G69,b)
true .
mndrix
  • 3,131
  • 1
  • 30
  • 23
  • atomic_list_concat doesn't work. I think it's because the term may also contain variables and atomic_list_concat needs a list of atoms. – chameleon Sep 28 '12 at 14:30
  • You probably want `replace(this, 'I', L, L2)` so that your list of atoms contains the atom 'I'. Then `atomic_list_concat` should work. I've updated my answer to show a complete example. – mndrix Sep 28 '12 at 18:37
  • it works, but when I assert the term as the body of a rule, it sets the variables as _, and I need it to keep the name. – chameleon Sep 28 '12 at 19:24
0

Take a look at this predicate (replace/4):

replace(Term,Term,With,With) :-
    !.
replace(Term,Find,Replacement,Result) :-
    Term =.. [Functor|Args],
    replace_args(Args,Find,Replacement,ReplacedArgs),
    Result =.. [Functor|ReplacedArgs].

replace_args([],_,_,[]).
replace_args([Arg|Rest],Find,Replacement,[ReplacedArg|ReplacedRest]) :-
    replace(Arg,Find,Replacement,ReplacedArg),
    replace_args(Rest,Find,Replacement,ReplacedRest).

An example of what you need:

| ?- replace(f(1,23,h(5,this)),this,Var,Result).                                                                                           

Result = f(1,23,h(5,Var))                                                                                                                  

yes
zebollo
  • 11