# Could not solve the problem with recursion in replacing arguments in math formula.

14 views

### Andrei Kalachev

Sep 7, 2017, 7:34:51 PM9/7/17
to SWI-Prolog
Good morning!
I have some problems with recursion in replacing arguments in math formula.

I wrote the function which replacing arguments in math formula.

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

In 1 case it's work correctly, when:
% Initial formula: (x*y/5-z)+x*y*w
% Find: x*y
% Replace: x-a*y+1

% prepare formula in prefix view: +/*xy -5z **xyw
% Find in prefix view: *xy
% Replace in prefix view: *-xa+y1

%Correctly work example
replace1(Result) :-
replace(
f1(+(/(*(x, y), -(5, z)), *(*(x, y), z))),
*(x, y),
*(-(x, a), +(y, 1)),
Result).

% Result after replacing:
?- replace1(Result).
Result = f1((x-a)*(y+1)/(5-z)+(x-a)*(y+1)*z).

In 2 case it's doesn't work and I can't solve the problem, already few days...
% Initial formula: ((x->z)->((y->z)->(x\/y->z))->(x\/y->z))
% Find: A->B
% Replace: not(A\/B)
% Comment: Logical De Morgan rule. Implication theorem.

%prepared formula in prefix view: ( ->->->xz ->->yz->\/xyz ->\/xyz )
% Find in prefix view: ->(A, B)
% Replace in prefix view: not(\/(A, B))

%Don't work example 1):
replace3(Result) :-
replace(
f3( ->(->(->(x, z), ->(->(y, z), ->(\/(x, y), z))), ->(\/(x, y), z) )),
->(A,B),
not(\/(A,B)),
Result
).

% Result after replacing:
?- replace3(R).
R = f3(not(((x->z)->(y->z)->x\/y->z)\/(x\/y->z))).

%Tried another way, but not successful reach the goal:
replace3(Result) :-
replace(
f3( ->(->(->(x, z), ->(->(y, z), ->(\/(x, y), z))), ->(\/(x, y), z) )),
->(A,B),
not(\/(A,B)),
Result1
),
replace(
Result1,
->(A,B),
not(\/(A,B)),
Result
).

% Result after replacing:
?- replace3(R).
R = f3(not(((x->z)->(y->z)->x\/y->z)\/(x\/y->z))).

But if insert manually previous result to new call then will one more replacing.

%manual insert of previous result from replace3 to replace4
replace4(Result) :-
replace(
f3(not(((x->z)->(y->z)->x\/y->z)\/(x\/y->z))),
->(A,B),
not(\/(A,B)),
Result
).

% Result after replacing:
?- replace4(R).
R = f3(not(not((x->z)\/((y->z)->x\/y->z))\/(x\/y->z))).

I apology for mistakes, but I tried to explain as completely as I can.
Could someone give me advice what do wrong?
Thanks very much for your help!

### Jan Wielemaker

Sep 8, 2017, 5:26:17 AM9/8/17
to Andrei Kalachev, SWI-Prolog
On 09/08/2017 01:34 AM, Andrei Kalachev wrote:
> Good morning!
> I have some problems with recursion in replacing arguments in math formula.
>
> I wrote the function which replacing arguments in math formula.

It seems there are two problems. One is that after you make the first
replacement, your Find and Replacement are instantiated and may not
match further occurrences. Second, if your first rule matches you
replace the terms, but not their arguments.

Then, by swapping the arguments, making Find,Replacement the first two,
you can use maplist and avoid a lot of typing. This is what I think was

replace(Find,Replacement,Term,With) :-
\+ Find \= Term,
!,
copy_term(Find+Replacement, Term+With0),
replace_args(Find,Replacement,With0,With).
replace(Find,Replacement,Term,Result) :-
replace_args(Find,Replacement,Term,Result).

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

Enjoy at https://swish.swi-prolog.org/p/lQOCbxwU.swinb

Cheers --- Jan
> --
> You received this message because you are subscribed to the Google
> Groups "SWI-Prolog" group.
> To unsubscribe from this group and stop receiving emails from it, send