David
David

Reputation: 377

SWIProlog conditional sum inside list and rebuild

one of my predicates gives me a list like this as output:

[m(1,2,[v(1,y),v(1,y)]),m(1,6,[v(1,y),v(5,x)]),m(1,4,[v(3,x),v(1,y)]),m(1,8,[v(3,x),v(5,x)])]

When the symbols inside the sublist with v elements are equal (like y here):

[v(1,y),v(1,y)] 

or x here:

[v(3,x),v(5,x)]

I have to sum the numbers on the left and rebuild the list like this:

[m(1,2,[v(2,y)]),m(1,6,[v(1,y),v(5,x)]),m(1,4,[v(3,x),v(1,y)]),m(1,8,[v(8,x)])]

I have a similar predicate that works on the main lists but I am not getting this one right.

This is the other predicate that is working:

simplify([], []) :- !.
simplify([X], [X]) :- !.
simplify([m(C, TD, Var), m(C2, TD, Var)| Xs], Ys) :- 
    sumxp(C, C2, K), simplify([m(K, TD, Var)|Xs], Ys), !.
simplify([X, Y|Xs], [X|Ys]) :- !, simplify([Y|Xs], Ys).

sumxp(Power1, Power2, TotalPower) :- TotalPower is Power1 + Power2.

It acts in this way:

simplify([m(2,2,[v(1,a)]),m(2,2,[v(1,a)])],R).
R = [m(4, 2, [v(1, a)])].

Upvotes: 1

Views: 119

Answers (1)

Guy Coder
Guy Coder

Reputation: 24976

The simplify_01 rule works on each item in the list, e.g. m(1,6,[v(1,y),v(5,x)])

simplify_01(m(A,B,[v(X,Var1),v(Y,Var2)]),m(A,B,[v(X,Var1),v(Y,Var2)])) :-
    Var1 \= Var2.
simplify_01(m(A,B,[v(X,Var1),v(Y,Var1)]),m(A,B,[v(Z,Var1)])) :-
    Z is X + Y.

and the maplist just applies simplify_01 to all the items in the list.

simplify(L,R) :-
    maplist(simplify_01,L,R).

when run using SWI-Prolog

simplify([m(1,2,[v(1,y),v(1,y)]),m(1,6,[v(1,y),v(5,x)]),m(1,4,[v(3,x),v(1,y)]),m(1,8,[v(3,x),v(5,x)])],R).
R = [m(1, 2, [v(2, y)]), m(1, 6, [v(1, y), v(5, x)]), m(1, 4, [v(3, x), v(1, y)]), m(1, 8, [v(8, x)])] ;
false.

Upvotes: 1

Related Questions