Reputation: 1
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
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
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