简体   繁体   中英

Prolog - add to each lists element

I'm learning swi Prolog and I wanted to create predicate that adds +2 for each element.

So I wrote something like this:

addUp([],_).
addUp([H|T],R):-addUp(T,R),is_list(R)->append([H+2],R,R);R=[H+2|[]].

addUp([1,2],X).

But it always returns false. Why?

First an advice: learn to use maplist /3: with that you will write

addUp(Xs, Ys) :- maplist(addUp2, Xs, Ys).
addUp2(X, Y) :- Y is X + 2.

or better, a more reusable snippet...

addUp(Xs, Ys) :- maplist(addUp(2), Xs, Ys).
addUp(N, X, Y) :- Y is X + N.

Anyway, arithmetic in Prolog must be evaluated 'explicitly', and your code must be simplified a lot to work

addUp([], []).
addUp([H|T], [H1|T1]) :- H1 is H+2, addUp(T, T1).

But it always returns false. Why?

Your definition does not always fail:

?- addUp([1],X).
X = [1+2].

So sometimes it succeeds. And it seems that this case is more or less what you wanted. Where else does it succeed? In other programming languages you would have to guess or, heaven forbid, read the program. In Prolog, there is no need for this. Simply find a good query. A good candidate is the most general query :

?- addUp(Xs,Ys).
Xs = [] ...

So your definition succeeds for Xs equal to [] , and Ys equal to ... well, equal to anything . Therefore, this answer is too general.

Another goal catches my eye: is_list(R)->append([H+2],R,R) . Let's imagine, when this will be true. For R = [] not, nor for R = [_] . In fact, there is no length, where this will be true.

Now , we can start fixing your program. See chac/CapelliC's suggestion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM