SWI-Prolog: Sum-List - list

I'm starting with Prolog, and i'm a bit confused...
I have a simple program:
sum(0, []).
sum(Total, [Head|Tail]) :- sum(Sum, Tail), Total is Head + Sum.
When i debug, i can see that Prolog first splits the list with Head and Tail, so the result is 0 + empty list, and AFTER THAT it starts to sum the numbers and adds it again to the list.
Can someone explain why it doesn't come to Total is Head + Sum.
first and then splits the list to Head and Tail again?
EDIT: Here is the trace:
[trace] ?- sum(X, [1,2,3]).
Call: (6) sum(_G345, [1, 2, 3]) ? creep
Call: (7) sum(_G424, [2, 3]) ? creep
Call: (8) sum(_G424, [3]) ? creep
Call: (9) sum(_G424, []) ? creep
Exit: (9) sum(0, []) ? creep
Call: (9) _G430 is 3+0 ? creep
Exit: (9) 3 is 3+0 ? creep
Exit: (8) sum(3, [3]) ? creep
Call: (8) _G433 is 2+3 ? creep
xit: (8) 5 is 2+3 ? creep
Exit: (7) sum(5, [2, 3]) ? creep
Call: (7) _G345 is 1+5 ? creep
Exit: (7) 6 is 1+5 ? creep
Exit: (6) sum(6, [1, 2, 3]) ? creep
X = 6.

Your definition puts addition on the stack. The optimization that avoids putting away the addition would be a special case of a general technique known as tail recursion.
The following definition can use tail recursion:
sum(X,L):-sum(0,L,X).
sum(X,[],X).
sum(N, [Head|Tail],Y) :- N1 is Head + N, sum(N1,Tail,Y).
It introduces an accumulator for the values of the partial sum and carries it with the tail of the list. Here is the trace of the execution of the sum(X,[1,2,3]) query.
?- trace, sum(S,[1,2,3]),notrace,nodebug.
Call: (7) sum(_G584, [1, 2, 3]) ? creep
Call: (8) sum(0, [1, 2, 3], _G584) ? creep
^ Call: (9) _G792 is 1+0 ? creep
^ Exit: (9) 1 is 1+0 ? creep
Call: (9) sum(1, [2, 3], _G584) ? creep
^ Call: (10) _G795 is 2+1 ? creep
^ Exit: (10) 3 is 2+1 ? creep
Call: (10) sum(3, [3], _G584) ? creep
^ Call: (11) _G798 is 3+3 ? creep
^ Exit: (11) 6 is 3+3 ? creep
Call: (11) sum(6, [], _G584) ? creep
Exit: (11) sum(6, [], 6) ? creep
Exit: (10) sum(3, [3], 6) ? creep
Exit: (9) sum(1, [2, 3], 6) ? creep
Exit: (8) sum(0, [1, 2, 3], 6) ? creep
Exit: (7) sum(6, [1, 2, 3]) ? creep
S = 6 .

Here is another version doing that. I have been using concept mapping software to help in designing code, I cannot do complicated stuff in my head.
sum(A, [], A).
sum(Total, [Head|Tail], AuxNum) :-
Sum is Head+AuxNum,
sum(Total, Tail, Sum).
1 ?- trace,sum(Total,[1,2,3],0).
Call: (7) sum(_G2090, [1, 2, 3], 0) ? creep
Call: (8) _G2221 is 1+0 ? creep
Exit: (8) 1 is 1+0 ? creep
Call: (8) sum(_G2090, [2, 3], 1) ? creep
Call: (9) _G2224 is 2+1 ? creep
Exit: (9) 3 is 2+1 ? creep
Call: (9) sum(_G2090, [3], 3) ? creep
Call: (10) _G2227 is 3+3 ? creep
Exit: (10) 6 is 3+3 ? creep
Call: (10) sum(_G2090, [], 6) ? creep
Exit: (10) sum(6, [], 6) ? creep
Exit: (9) sum(6, [3], 3) ? creep
Exit: (8) sum(6, [2, 3], 1) ? creep
Exit: (7) sum(6, [1, 2, 3], 0) ? creep
Total = 6.

Related

Prolog basic exercise with lists gives stack size error

I'm starting to learn prolog, and I'm stuck with this problem, it would be really helpful if someone could tell me what I'm doing wrong and why is it wrong so I can learn.
Exercise
Write a predicate that follows the syntax:
supr_bigger(Elem,List,Result)
where Result is the list List, but with all of the elements bigger than Elem deleted.
Code
supr_bigger(_,[],[]).
supr_bigger(Elem,[X|Y],R) :- X =< Elem,
insert(X,R,R1),
supr_bigger(Elem,Y,R1).
supr_bigger(Elem,[X|Y],R) :- X > Elem, supr_bigger(Elem,Y,R).
insert(Z,L1,L2) :- choose(Z,L2,L1).
choose(X,[X|L],L).
choose(X,[Y|L1],[Y|L2]) :- choose(X,L1,L2).
When I try to test the code above, this error shows up:
?- supr_bigger(3,[3,2,5,4,1,2,6],R).
ERROR: Stack limit (1,0Gb) exceeded
ERROR: Stack sizes: local: 2Kb, global: 0,9Gb, trail: 0Kb
ERROR: Stack depth: 16, last-call:13%, Choice points: 11
A lot of thanks in advance.
You can use predicate trace/1 to find out what is wrong with your code:
?- trace, supr_bigger(3, [3,2,1,4], R).
Call: (11) supr_bigger(3, [3, 2, 1, 4], _4526) ? creep
Call: (12) 3=<3 ? creep
Exit: (12) 3=<3 ? creep
Call: (12) insert(3, _4526, _5168) ? creep
Call: (13) choose(3, _5210, _4526) ? creep
Exit: (13) choose(3, [3|_4526], _4526) ? creep
Exit: (12) insert(3, _4526, [3|_4526]) ? creep
Call: (12) supr_bigger(3, [2, 1, 4], [3|_4526]) ? creep
Call: (13) 2=<3 ? creep
Exit: (13) 2=<3 ? creep
Call: (13) insert(2, [3|_4526], _5482) ? creep
Call: (14) choose(2, _5524, [3|_4526]) ? creep
Exit: (14) choose(2, [2, 3|_4526], [3|_4526]) ? creep
Exit: (13) insert(2, [3|_4526], [2, 3|_4526]) ? creep
Call: (13) supr_bigger(3, [1, 4], [2, 3|_4526]) ? creep
Call: (14) 1=<3 ? creep
Exit: (14) 1=<3 ? creep
Call: (14) insert(1, [2, 3|_4526], _5796) ? creep
Call: (15) choose(1, _5838, [2, 3|_4526]) ? creep
Exit: (15) choose(1, [1, 2, 3|_4526], [2, 3|_4526]) ? creep
Exit: (14) insert(1, [2, 3|_4526], [1, 2, 3|_4526]) ? creep
Call: (14) supr_bigger(3, [4], [1, 2, 3|_4526]) ? creep
Call: (15) 4=<3 ? creep
Fail: (15) 4=<3 ? creep
Redo: (14) supr_bigger(3, [4], [1, 2, 3|_4526]) ? creep
Call: (15) 4>3 ? creep
Exit: (15) 4>3 ? creep
Call: (15) supr_bigger(3, [], [1, 2, 3|_4526]) ? creep
Fail: (15) supr_bigger(3, [], [1, 2, 3|_4526]) ?
As you can observe, when the input list is empty (call 15), the output list actually contains all the elements that should have been selected. However, the base clause in the recusive definition of supr_bigger/3 cannot be applied in this case, since lists [] (clause's third argument) and [1, 2, 3|_4526] (goal's third argument) do not match.
To solve the problem, you could modify your code to:
Close the open list [1, 2, 3|_4526], transforming it into [1, 2, 3].
Add a new argument to collect the final result.
But, since your code has many other problems, it's better to try a simpler approach:
supr_bigger(_, [], []).
supr_bigger(B, [X|Xs], [X|Ys]) :- X =< B, supr_bigger(B, Xs, Ys).
supr_bigger(B, [X|Xs], Ys) :- X > B, supr_bigger(B, Xs, Ys).
Example:
?- supr_bigger(3, [3,2,1,4], R).
R = [3, 2, 1] ;
false.
To eliminate spurious choice points, you can do as follows
supr_bigger(B, L, R) :-
best_supr_bigger(L, B, R).
best_supr_bigger([], _, []).
best_supr_bigger([X|Xs], B, R) :-
( X =< B
-> R = [X|Ys]
; R = Ys ),
best_supr_bigger(Xs, B, Ys).
Example:
?- supr_bigger(3, [3,2,1,4], R).
R = [3, 2, 1].

Prolog list permutation

I have the following code that generates all possible permutations of a list, but I can't figure it out why it is working.
remove(X,[X|T],T).
remove(X,[F|T],[F|T1]) :- remove(X,T,T1).
perm([X|Y],Z) :- perm(Y,W), remove(X,Z,W).
perm([],[]).
Could someone give me some explanation or send me to a reference, please?
I'm just picking up Prolog, so I don't know the correct terms, but I think the logic goes as following:
The rules for remove(X,L,T) is straightforward, it defines T as a list with X removed from L. For example, given T=[1], which L satisfies X=2? the answer is [1,2] or [2,1].
For perm, let's take the example of perm([1,2,3], P).
According to the definition, P is a permutation of [1,2,3] if W is a permuation of [2,3], where W is P with 1 removed.
Assuming we somehow know W is [2,3] or [3,2] through the magic of backtracking, then P must be [1,2,3],[2,1,3],[2,3,1],...
How did we find out permutation of [2,3] is [2,3] or [3,2]? It happens when W2 is a permutation of [3], where W2 is P2 with 2 removed.
Assuming we somehow know W2 is [3], then P2 must be [2,3] or [3,2].
How did we find out permutation of [3] is [3]? It happens when W3 is a permutation of [], where W3 is P3 with 3 removed. Since W3 must be [] due to the base case, then P3 must be [3].
Just learned about the trace mode, it provides a step-by-step explanation:
?- trace.
true.
[trace] 2 ?- perm([1,2],X).
Call: (7) perm([1, 2], _G22903) ? creep
Call: (8) perm([2], _G22988) ? creep
Call: (9) perm([], _G22988) ? creep
Exit: (9) perm([], []) ? creep
Call: (9) remove(2, _G22988, []) ? creep
Exit: (9) remove(2, [2], []) ? creep
Exit: (8) perm([2], [2]) ? creep
Call: (8) remove(1, _G22903, [2]) ? creep
Exit: (8) remove(1, [1, 2], [2]) ? creep
Exit: (7) perm([1, 2], [1, 2]) ? creep
X = [1, 2] ;
Redo: (8) remove(1, _G22903, [2]) ? creep
Call: (9) remove(1, _G22984, []) ? creep
Exit: (9) remove(1, [1], []) ? creep
Exit: (8) remove(1, [2, 1], [2]) ? creep
Exit: (7) perm([1, 2], [2, 1]) ? creep
X = [2, 1] ;
Redo: (9) remove(1, _G22984, []) ? creep
Fail: (9) remove(1, _G22984, []) ? creep
Fail: (8) remove(1, _G22903, [2]) ? creep
Redo: (9) remove(2, _G22988, []) ? creep
Fail: (9) remove(2, _G22988, []) ? creep
Fail: (8) perm([2], _G22988) ? creep
Fail: (7) perm([1, 2], _G22903) ? creep
false.

Why does using [H|T] as a parameter instead of a normal variable cause my predicate to fail?

I'm creating a predicate to remove a specified element from a list so remove(Xs,X,Ys) should hold if Ys is the result of removing all occurrences
of X from Xs. My initial failing predicate is shown below:
remove([],_,[]).
remove([H1|T1],H1,[H2|T2]) :- % e.g. [2,3] , 2, [3]
remove(T1,H1,[H2|T2]). % remove first head -> [3], 2, [3]
remove([H1|T1],Y,[H1|T2]) :- % heads match e.g. [1,2,3], 2, [1,3]
H1\==Y,
remove(T1,Y,T2). % remove heads -> [2,3], 2, [3]
This was failing but then I noticed that I had a redundant [H2|Y2] where I could have just used a variable e.g. Ys. I made this change thinking that it would still fail but instead it starting working. The working code is shown below:
remove([],_,[]).
remove([H1|T1],H1,Ys) :- % e.g. [2,3] , 2, [3]
remove(T1,H1,Ys). % remove first head -> [3], 2, [3]
remove([H1|T1],Y,[H1|T2]) :- % heads match e.g. [1,2,3], 2, [1,3]
H1\==Y,
remove(T1,Y,T2). % remove heads -> [2,3], 2, [3]
Can someone explain why changing [H2|T2] to Ys made it work?
Somewhere in the progression of the query, the pattern, remove([H|T], H, []) is coming up which will match the head of the second clause of your second version, remove([H1|T1], H1, Ys), but will not match the head of the second clause of your first version, remove([H1|T1], H1, [H2|T2]).
If you run trace on the query, remove([1, 2, 3, 2], 2, [1, 3]) using your first program version, you get:
Call: (6) remove([1, 2, 3, 2], 2, [1, 3]) ? creep
Call: (7) 1\==2 ? creep
Exit: (7) 1\==2 ? creep
Call: (7) remove([2, 3, 2], 2, [3]) ? creep
Call: (8) remove([3, 2], 2, [3]) ? creep
Call: (9) 3\==2 ? creep
Exit: (9) 3\==2 ? creep
Call: (9) remove([2], 2, []) ? creep
Fail: (9) remove([2], 2, []) ? creep <---- NOTE THIS FAILURE! (no clause match)
Fail: (8) remove([3, 2], 2, [3]) ? creep
Redo: (7) remove([2, 3, 2], 2, [3]) ? creep
Fail: (7) remove([2, 3, 2], 2, [3]) ? creep
Fail: (6) remove([1, 2, 3, 2], 2, [1, 3]) ? creep
The case remove([2], 2, []) will not match the second clause of your first implementation:
remove([H1|T1], H1, [H2|T2])...
So H1 = 2, T1 = [], but [H2|T2] is not unifiable with [].
But it will match the second clause of your second implementation:
remove([H1|T1], H1, Ys).
Here you get, H1 = 2, T1 = [], and Ys = []. Here it is in the trace for your second version:
[trace] ?- remove([1,2,3,2],2,[1,3]).
Call: (6) remove([1, 2, 3, 2], 2, [1, 3]) ? creep
Call: (7) 1\==2 ? creep
Exit: (7) 1\==2 ? creep
Call: (7) remove([2, 3, 2], 2, [3]) ? creep
Call: (8) remove([3, 2], 2, [3]) ? creep
Call: (9) 3\==2 ? creep
Exit: (9) 3\==2 ? creep
Call: (9) remove([2], 2, []) ? creep <---- SUCCESS! (2nd clause match)
Call: (10) remove([], 2, []) ? creep <---- SUCCESS!
Exit: (10) remove([], 2, []) ? creep
Exit: (9) remove([2], 2, []) ? creep
Exit: (8) remove([3, 2], 2, [3]) ? creep
Exit: (7) remove([2, 3, 2], 2, [3]) ? creep
Exit: (6) remove([1, 2, 3, 2], 2, [1, 3]) ? creep

My Prolog "translator" script returns an empty list

I am trying to write a simple translator, where you enter a list of numerical numbers and it returns their string values like so :
translate([1,2,3], X).
X=[one, two, three].
The code I have written works...except it returns an empty list. Here is my code and the trace:
means(1, one).
means(2, two).
means(3, three).
means(4, four).
means(5, five).
means(6, six).
means(7, seven).
means(8, eight).
means(9, nine).
means(10, ten).
translate([], X).
translate([H|T], []):-
means(H, X),
translate(T, X).
translate([H|T], X):-
means(H, Y),
translate(T, [X|Y]).
[trace] 1 ?- translate([1,2,3], X).
Call: (6) translate([1, 2, 3], _G2219) ? creep
Call: (7) means(1, _G2301) ? creep
Exit: (7) means(1, one) ? creep
Call: (7) translate([2, 3], one) ? creep
Call: (8) means(2, _G2301) ? creep
Exit: (8) means(2, two) ? creep
Call: (8) translate([3], [one|two]) ? creep
Call: (9) means(3, _G2304) ? creep
Exit: (9) means(3, three) ? creep
Call: (9) translate([], [[one|two]|three]) ? creep
Exit: (9) translate([], [[one|two]|three]) ? creep
Exit: (8) translate([3], [one|two]) ? creep
Exit: (7) translate([2, 3], one) ? creep
Exit: (6) translate([1, 2, 3], []) ? creep
X = [] .
My other question is: why is my list concatenating as [[one|two]|three]? instead of [one, two, three]?
Thanks,
You get empty list because of translate([H|T], []) clause.
The whole program (except means facts) can be just this simple:
translate([], []).
translate([NumH | NumT], [WordH | WordT]) :-
means(NumH, WordH),
translate(NumT, WordT).
Doing it manually Sergey's way is good practice, but you can simplify even further with maplist/3:
translate(Numbers, Words) :- maplist(means, Numbers, Words).

Why does changing the order of facts change the behavior of the predicate?

This is my first idea:
perm([X|Y],Z) :- takeout(X,Z,W), perm(Y, W).
perm([],[]).
When I tried to run -? perm([1, 2, 3], P)., it showed a stack overflow problem.
But if we change the order of the two statements, it will work.
perm([X|Y],Z) :- perm(Y, W), takeout(X,Z,W).
perm([],[]).
Why? I am a Prolog beginner, please help.
The takeout/3 you refer to is commonly known as select(X, Xs0, Xs)
Here is another definition - to illustrate an uncommon usage of DCGs.
perm(Xs,Ys) :-
phrase(perm(Xs),[],Ys).
perm([]) --> [].
perm([X|Xs]) --> perm(Xs), ins(X).
ins(X),[X] --> [].
ins(X),[Y] --> [Y], ins(X).
Well, your takeout predicate may look like that:
takeout( X, [X|R], R ).
takeout( X, [F|R], [F|S] ) :-
takeout( X, R, S ).
SWI-Prolog has a useful predicate named trace.
In first case:
X = [1, 2, 3] ;
Redo: (10) takeout(3, _G477, _G485) ? creep
Call: (11) takeout(3, _G480, _G483) ? creep
Exit: (11) takeout(3, [3|_G483], _G483) ? creep
Exit: (10) takeout(3, [_G479, 3|_G483], [_G479|_G483]) ? creep
Call: (10) perm([], [_G479|_G483]) ? creep
Fail: (10) perm([], [_G479|_G483]) ? creep
Redo: (11) takeout(3, _G480, _G483) ? creep
Call: (12) takeout(3, _G486, _G489) ? creep
Exit: (12) takeout(3, [3|_G489], _G489) ? creep
Exit: (11) takeout(3, [_G485, 3|_G489], [_G485|_G489]) ? creep
Exit: (10) takeout(3, [_G479, _G485, 3|_G489], [_G479, _G485|_G489]) ? creep
Call: (10) perm([], [_G479, _G485|_G489]) ? creep
Fail: (10) perm([], [_G479, _G485|_G489]) ? creep
Redo: (12) takeout(3, _G486, _G489) ? creep
Call: (13) takeout(3, _G492, _G495) ? creep
Exit: (13) takeout(3, [3|_G495], _G495) ? creep
Exit: (12) takeout(3, [_G491, 3|_G495], [_G491|_G495]) ? creep
Exit: (11) takeout(3, [_G485, _G491, 3|_G495], [_G485, _G491|_G495]) ? creep
Exit: (10) takeout(3, [_G479, _G485, _G491, 3|_G495], [_G479, _G485, _G491|_G495]) ? creep
Call: (10) perm([], [_G479, _G485, _G491|_G495]) ? creep
Fail: (10) perm([], [_G479, _G485, _G491|_G495]) ? creep
Redo: (13) takeout(3, _G492, _G495) ? creep
Call: (14) takeout(3, _G498, _G501) ? creep
Exit: (14) takeout(3, [3|_G501], _G501) ? creep
Exit: (13) takeout(3, [_G497, 3|_G501], [_G497|_G501]) ? creep
Exit: (12) takeout(3, [_G491, _G497, 3|_G501], [_G491, _G497|_G501]) ? creep
Exit: (11) takeout(3, [_G485, _G491, _G497, 3|_G501], [_G485, _G491, _G497|_G501]) ? creep
In second case:
X = [1, 2, 3] ;
Redo: (8) takeout(1, _G451, [2, 3]) ? creep
Call: (9) takeout(1, _G532, [3]) ? creep
Exit: (9) takeout(1, [1, 3], [3]) ? creep
Exit: (8) takeout(1, [2, 1, 3], [2, 3]) ? creep
Exit: (7) perm([1, 2, 3], [2, 1, 3]) ? creep
So, the order of predicate enumeration is actually important. In first case you produced a lot of states with unknown values. It will be a good idea (as possible) to take a list of paper, running trace and drawing what's really going on.
But in brief, in first case you're producing a lot of unknown variables coated with the takeout fact, which cannot be matched with perm.
Prolog uses SLD resolution and thus order of clauses and order of literals within a clause do make a difference. Basically the engine tries to resolve clause heads by searching top-to-bottom in a depth-first fashion. In other words, there is a procedural semantics on the top of the declarative semantics. This distinction sometimes confuses beginners but, on the other hand, it is the key reason why Prolog is truly a programming language (i.e. Turing complete).
your base case perm([],[]) needs to appear first, otherwise it will keep descending into the perm predicate until you run out of stack space. keep that in mind for future predicates too, its very important in prolog.
Also, you should probably switch up the order of perm & takeout in the other predicate.