Heide
Heide

Reputation: 1

Prolog: update element of list

I have a list of new elements in the format 'sn(N, C, P)', an OldList, and a NewList. I am trying write update(NewElements, OldList, NewList) that every sn(N, _, _) in OLDLIST, update it if the new C is less than the old one.

Here is an example:

update( [sn(b,5,b),sn(a,1,a)] , [sn(a,2,a),sn(b,4,b)] , [sn(a,1,a),sn(b,4,b)]).

-| true.

I have tried these code but it only works when there is only one new element:

same(X,X).

update_helper(_, [ ], [ ]).
update_helper(sn(N1,C1,P1), [sn(N2,C2,P2)|T1], [sn(N3,C3,P3)|T2]) :-
    \+N1 == N2,
    same(sn(N2,C2,P2),sn(N3,C3,P3)),
    update_helper(sn(N1,C1,P1), T1, T2).

update_helper(sn(N1,C1,P1), [sn(N2,C2,P2)|T1], [sn(N3,C3,P3)|T2]) :-
    N1 == N2,
    C1 < C2,
    same(sn(N1,C1,P1),sn(N3,C3,P3)),
    update_helper(sn(N1,C1,P1), T1, T2).

update_helper(sn(N1,C1,P1), [sn(N2,C2,P2)|T1], [sn(N3,C3,P3)|T2]) :-
    N1 == N2,
    C1 >= C2,
    same(sn(N2,C2,P2),sn(N3,C3,P3)),
    update_helper(sn(N1,C1,P1), T1, T2).

update([ ], _, _).
update([H|T], Old, New) :-
    update(T, Old, New),
    update_helper(H, Old, New).

Upvotes: 0

Views: 50

Answers (2)

slago
slago

Reputation: 5519

Another possible solution, using maplist/3:

update(NewElements, Old, New) :-
    maplist(updated(NewElements), Old, New).

updated(NewElements, sn(N2,C2,P2), Updated) :-
    (   ( member(sn(N1,C1,P1), NewElements),
          N1 = N2,
          C1 < C2 )
    ->  Updated = sn(N1,C1,P1)
    ;   Updated = sn(N2,C2,P2) ).

Running example:

?- update([sn(b,5,b), sn(a,1,a)], [sn(a,2,a), sn(b,4,b)], L).
L = [sn(a, 1, a), sn(b, 4, b)].

Upvotes: 1

slago
slago

Reputation: 5519

I think you can do something like this:

update([], Old, Old).
update([X|Xs], Old, New) :- 
    update_helper(X, Old, Lst),  % Old is updated as Lst
    update(Xs, Lst, New).        % Lst is updated as New

update_helper(_, [], []).
update_helper(sn(N,C1,P1), [sn(N,C2,_)|Old], [sn(N,C1,P1)|Old]) :- 
    C1<C2.
update_helper(sn(N1,C1,_), [sn(N2,C2,P2)|Old], [sn(N2,C2,P2)|New]) :-
    once(N1 \= N2 ; C1 >= C2), 
    update_helper(sn(N2,C2,P2), Old, New).

Running example:

?- update([sn(b,5,b), sn(a,1,a)], [sn(a,2,a), sn(b,4,b)], L).
L = [sn(a,1,a), sn(b,4,b)].

Upvotes: 1

Related Questions