I have the following codes. Trying to make a reverse list. but it doesnt work.
reverse([],[H|T]).
reverse([H|T],Z) :- reverse(T,[H|Z]).
I run this in prolog and I get this:
1 ?- trace, reverse([1,2,3],X).
Call: (7) reverse([1, 2, 3], _G396) ? creep
Call: (8) reverse([2, 3], [1|_G396]) ? creep
Call: (9) reverse([3], [2, 1|_G396]) ? creep
Call: (10) reverse([], [3, 2, 1|_G396]) ? creep
Exit: (10) reverse([], [3, 2, 1|_G396]) ? creep
Exit: (9) reverse([3], [2, 1|_G396]) ? creep
Exit: (8) reverse([2, 3], [1|_G396]) ? creep
Exit: (7) reverse([1, 2, 3], _G396) ? creep
true.
this should give me [3,2,1], instead of [1,2,3]. what is going wrong here??
When a list is empty, its reverse is empty.
So
reverse([], []).
In another case, you append the first element of the list at the end of the revese of the rest of the list. so :
reverse([H|T],Z) :-
reverse(T,Z1),
append(Z1, [H], Z).
You almost got it right. What you need is an "accumulator" which collects the result so far and passes it to the return variable at the end of the recursion:
reverse([],Z,Z).
reverse([H|T],Z,Acc) :- reverse(T,Z,[H|Acc]).
Otherwise the reversed list is forgotten as the function returns from the recursive calls. You need to instantiate the accumulator with an empty list when you call reverse/3:
?- reverse([1,2,3],X,[]).
If you do the trace you will see that the second argument does not get instantiated until your original list is empty.
Related
I m trying to do a list member(member/2) with my own predicate.
starting this example
?-app([a,r,t],[t,s,m,n,a],L3).
L3=[a,t]
I tried to do similar exercises so I did this with prolog:
app([],_,[]).
app([H|T],[H1,T1],[H|L1]):- H is H1, L1 is H,! ,app(T,T1,L1).
app([_H|T],L,L2):- app(T,L,L2).
and all working regular, but the value in a list will be overwritten during the execution, in fact, the trace is :
trace, app([3,2],[3,5],X).
Call: (9) app([3, 2], [3, 5], _7426) ? creep
Call: (10) 3 is 3 ? creep
Exit: (10) 3 is 3 ? creep
Call: (10) _7736 is 3 ? creep
Exit: (10) 3 is 3 ? creep
Call: (10) app([2], 5, 3) ? creep
Call: (11) app([], 5, 3) ? creep
Fail: (11) app([], 5, 3) ? creep
Fail: (10) app([2], 5, 3) ? creep
Fail: (9) app([3, 2], [3, 5], _7426) ? creep
false.
I tried to make a modify on the base case in this way:
app([],_,_N).
but the output is every wrong:
trace, app([3,2],[3,5],X).
Call: (9) app([3, 2], [3, 5], _7426) ? creep
Call: (10) 3 is 3 ? creep
Exit: (10) 3 is 3 ? creep
Call: (10) _7736 is 3 ? creep
Exit: (10) 3 is 3 ? creep
Call: (10) app([2], 5, 3) ? creep
Call: (11) app([], 5, 3) ? creep
Exit: (11) app([], 5, 3) ? creep
Exit: (10) app([2], 5, 3) ? creep
Exit: (9) app([3, 2], [3, 5], [3|3]) ? creep
X = [3|3].
where I m wrong?
I think you're trying to do a sublist/2 predicate:
%! sublist(Sub, List)
% is true if Sub is a list that occurs in
% some position in List
sublist(Sub, List) :-
% first partition off some tail of the list
append(_Prefix, Tail, List),
% then get some prefix of the tail, this is a sublist
append(Sub, _TailTail, Tail).
There's more ways to do this, but I think append/3 is simple to
understand. This is a different problem from member/2, which is finding elements in a list, here our problem is to carve up a list into chunks, hence the very different implementation than you see in member/2. You'll often find in Prolog the first step to a solution is to define the problem well. Good luck in your Prolog learning.
I need some help with understanding the following Prolog source code:
addone([],[]).
addone([H|T],[H1|T1]):-H1 is H + 1, addone(T,T1).
This code, takes a given list and therefore prints out another one which has +1 added to each argument of it.
I don't understand how exactly this work, if I trace it:
[trace] 69 ?- addone([1,2,3],X).
Call: (6) addone([1, 2, 3], _G1196) ? creep
Call: (7) _G1273 is 1+1 ? creep
Exit: (7) 2 is 1+1 ? creep
Call: (7) addone([2, 3], _G1274) ? creep
Call: (8) _G1279 is 2+1 ? creep
Exit: (8) 3 is 2+1 ? creep
Call: (8) addone([3], _G1280) ? creep
Call: (9) _G1285 is 3+1 ? creep
Exit: (9) 4 is 3+1 ? creep
Call: (9) addone([], _G1286) ? creep
Exit: (9) addone([], []) ? creep
Exit: (8) addone([3], [4]) ? creep
Exit: (7) addone([2, 3], [3, 4]) ? creep
Exit: (6) addone([1, 2, 3], [2, 3, 4]) ? creep
X = [2, 3, 4].
I get to the point:
Call: (9) addone([], _G1286) ? creep
Exit: (9) addone([], []) ? creep
From here I don't understand how when I reach the base clause Prolog recalls its saved values?
Can you please explain me how this thing works, what is the logic behind it?
Thank you in advance, Petar!
I guess the answer you might be looking for is:
When Prolog sees a predicate defined like this (most simple example):
foo([]).
foo([_|_]).
This predicate will now be deterministic on proper lists. In other words, it will succeed exactly once. This is because Prolog can recognize by loooking at the two clauses that they are mutually exclusive. In other words, for any non-empty list the second clause only can apply, and for an empty list the first clause only can apply.
In other words, for a proper list of length Len, after Len calls of the second clause, a call of the first clause will follow. At that point it succeeds, and all recursive calls (which were tail recursive) will succeed, in reverse order of how they were called.
In your example, before the recursive call is even made, a value is calculated and ready to be used when the call succeeds.
One thing here is that when you call with it a second argument a variable, you will keep on unifying this variable with a head of a list (the number you calculated) and a free tail [H1|T1], which you pass to the recursive call addone(T, T1). Only when the first argument is the empty list, will the second argument also be unified with an empty list: addone([], []). Now, on the return from the recursive calls, the list of values (growing from behind) will be unified with the free tails [4|[]], [3|[4|[]]] [2|[3|[4|[]]]], eventually building the final list in the second argument.
This is a predicate that get permutations of a list. Can somebody explain to me how to trace this predicate? I am using SWI.
perm([H|T],L) :- perm(T,P) , insert(H,P,L).
perm([],[]).
insert(X,L,[X|L]).
insert(X,[H|T],[H|T1]) :- insert(X,T,T1).
Here's an example of using trace in SWI Prolog.
Entering the code:
?- [user].
|: perm([H|T],L) :- perm(T,P) , insert(H,P,L).
|: perm([],[]).
|:
|: insert(X,L,[X|L]).
|: insert(X,[H|T],[H|T1]) :- insert(X,T,T1).
|: % user://1 compiled 0.01 sec, 6 clauses
true.
Running a trace. Press "Enter" at the question marks ? to "creep" (take a step):
?- trace.
true.
[trace] ?- perm([1,2,3], L).
Call: (6) perm([1, 2, 3], _G366) ? creep
Call: (7) perm([2, 3], _G445) ? creep
Call: (8) perm([3], _G445) ? creep
Call: (9) perm([], _G445) ? creep
Exit: (9) perm([], []) ? creep
Call: (9) insert(3, [], _G446) ? creep
Exit: (9) insert(3, [], [3]) ? creep
Exit: (8) perm([3], [3]) ? creep
Call: (8) insert(2, [3], _G449) ? creep
Exit: (8) insert(2, [3], [2, 3]) ? creep
Exit: (7) perm([2, 3], [2, 3]) ? creep
Call: (7) insert(1, [2, 3], _G366) ? creep
Exit: (7) insert(1, [2, 3], [1, 2, 3]) ? creep
Exit: (6) perm([1, 2, 3], [1, 2, 3]) ? creep
L = [1, 2, 3]
As you might expect, this trace shows that perm calls itself recursively until it gets to the empty tail ([]) of the input list [1,2,3]. It then shows calls to insert which follow those recursive calls, along with the arguments occurring in those calls. The _Gnnn variables are uninstantiated arguments on a Call that gets instantiated in the clause which you see on the Exit.
This is my min() function in Prolog that should find the smallest element in a list of numbers. My idea was to test that the Result is smaller or equal to every element in the list. The head of the list is removed until it is empty. When this point is reached, the set in result was correct.
min([], Result).
min([Head|Tail], Result) :-
Result =< Head,
min(Tail, Result).
When consulting this file in SWI-Prolog, it can test if a value is the minimal element with min([5, 3, 7, 6], 3) which returns true. But min([5, 3, 7, 6], X) does not find a value for X but just returns true.
How can I make it find the value for X?
If you turn tracing on you can see what's wrong with your script.
1 ?- trace.
true.
Original version:
/** Version 0 */
min([], Result).
min([Head|Tail], Result) :-
Result =< Head,
min(Tail, Result).
Output:
[trace] 2 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G4129) ? creep
Call: (7) _G4129=<5 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (7) _G4129=<5 ? creep
You're trying to compare an unistantiated variable with 5. Solution: swap lines in the script so that the variable is instantiated before the comparison.
/** Version 1 */
min([], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
Output:
[trace] 5 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G517) ? creep
Call: (7) min([3, 7, 6], _G517) ? creep
Call: (8) min([7, 6], _G517) ? creep
Call: (9) min([6], _G517) ? creep
Call: (10) min([], _G517) ? creep
Exit: (10) min([], _G517) ? creep
Call: (10) _G517=<6 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (10) _G517=<6 ?
[trace] 102 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G3067) ? creep
Call: (7) min([3, 7, 6], _G3067) ? creep
Call: (8) min([7, 6], _G3067) ? creep
Call: (9) min([6], _G3067) ? creep
Call: (10) min([], _G3067) ? creep
Exit: (10) min([], _G3067) ? creep
Call: (10) _G3067=<6 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (10) _G3067=<6 ?
This way the script goes a bit further but when computing the minimum of the tail it reaches a comparison with an unistantiated variable again. Solution: change min([], Result). to min([Result], Result).
/** version 2 */
min([Result], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
Output:
[trace] 8 ?- min([5,3,7,6],3).
Call: (6) min([5, 3, 7, 6], 3) ? creep
Call: (7) min([3, 7, 6], 3) ? creep
Call: (8) min([7, 6], 3) ? creep
Call: (9) min([6], 3) ? creep
Call: (10) min([], 3) ? creep
Fail: (10) min([], 3) ? creep
Fail: (9) min([6], 3) ? creep
Fail: (8) min([7, 6], 3) ? creep
Fail: (7) min([3, 7, 6], 3) ? creep
Fail: (6) min([5, 3, 7, 6], 3) ? creep
false.
The program now only returns false. This is because you only consider the case the minimum of the tail is smaller than or equal than the head. This program will only return a correct result when the input list is sorted decreasingly (so that the minimum of the tail is smaller than the head, recursively).
[trace] 10 ?- min([5,4,3,2],X).
Call: (6) min([5, 4, 3, 2], _G2469) ? creep
Call: (7) min([4, 3, 2], _G2469) ? creep
Call: (8) min([3, 2], _G2469) ? creep
Call: (9) min([2], _G2469) ? creep
Exit: (9) min([2], 2) ? creep
Call: (9) 2=<3 ? creep
Exit: (9) 2=<3 ? creep
Exit: (8) min([3, 2], 2) ? creep
Call: (8) 2=<4 ? creep
Exit: (8) 2=<4 ? creep
Exit: (7) min([4, 3, 2], 2) ? creep
Call: (7) 2=<5 ? creep
Exit: (7) 2=<5 ? creep
Exit: (6) min([5, 4, 3, 2], 2) ? creep
X = 2 .
So you need to take care of the case when the minimum of the tail is strictly greater than the head by adding the clause:
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
And here's the final version:
/** version 3 */
min([Result], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
(turn tracing off with nodebug.)
The min of an empty list can't be set.
You can just write
min([X], X).
hoping that X is an integer ; I assume it is !
then
min([Head|Tail], Result) :-
% you fetch the min of the rest of the list
min(Tail, R1),
(Head < R1
-> Result = Head
; Result = R1).
My SWI-Prolog reports
?- min([5, 3, 7, 6], X).
ERROR: user://1:18:
=</2: Arguments are not sufficiently instantiated
which makes sense as the first X =< 3 is performed with unbound X. To make the predicate work, you need to follow the definition of minimum, which is not defined for empty lists:
min([X], X).
min([X|L], Min) :-
L = [_|_], % non-empty tail; could be replaced by a cut
min(L, MinL),
Min is min(X, MinL).
(Note that the final line backs off to the built-in min, which is evaluated by is.)
Alternatively, you can take minima of pairs of elements, giving
min([X], X).
min([X,Y|L], Min) :-
MinXY is min(X, Y),
min([MinXY|L], Min).
This version is tail-recursive.
It couldn't possibly have returned true there. X =< 3 causes "ERROR: =</2: Arguments are not sufficiently instantiated". Perhaps you used #=< for comparison, but with it X #=< 3 just succeeds, without instantiating X in any way. So X would get passed unchanged, and min([], X) would just finally succeed - exactly what you've observed.
Your code is wrong in another way too. min([5, 3, 7, 6], 0) succeeds too, and it shouldn't.
others provided you with recursive solutions. For an iterative one, we typically add another, accumulating argument, and pass the Result down the chain unchanged to receive the final value from the accumulator for us:
min([H|T], Result):- min(T,H,Result).
min([], Result, Result).
min([Head|Tail], M, Result) :-
M =< Head -> min(Tail, M, Result)
; min(Tail, Head, Result).
Empty list has no minimum value. An argument list's head is used as initial value for the minimum.
Q. Given [1,2,3] in Prolog get back [6,5,3] by reverse accumulation
I have the start code:
accumalate([H],[H]).
accumalate([H1 | H2], [Hnew, H2]),
Hnew is H1 + H2.
....
I am looking for basic Prolog solution.
We are not here to do you homework for you. So the best we can do is provide you with some tips. So ask yourself these questions:
What are the base cases here (for which inputs is the output immediate)?
You have accumulate([N], [N])., but what about empty lists?
In what order must the additions be performed?
More specifically, which elements must be added first?
Other than that, I can tell you that you can solve this using three clauses. No other predicates required. Good luck!
Bonus: you may want to define the head of the recursive clause as follows:
accumulate([N|T], [N1,N2|T2]).
Here is my take:
accumulate([],[]).
accumulate([H|T], [H1|T1]):-
sum([H|T],H1),
accumulate(T,T1).
sum([],0).
sum([H|T],Y):-
sum(T,Y1),
Y is H + Y1.
You can of course use a built-in sumlist/2 in place of the hand-crafted sum/2 if you prefer that.
Once you are done with the basic implementation , Try solving this problem in O(n) time. The idea is to start from the first element and keep on adding it to a secondary list till your original list is empty. The secondary list is the reverse list which you need.
If you append the two lists in your recursive step, you will end up having a O(N^2) complexity.
ac([], 0, []).
ac([H|T], ST, [ST|Res]) :-
ac(T, X, Res),
ST is H + X.
accum(List, Res) :-
ac(List, _, Res).
[trace] ?- accum([1,2,3], X).
Call: (6) accum([1, 2, 3], _G376) ? creep
Call: (7) ac([1, 2, 3], _G458, _G376) ? creep
Call: (8) ac([2, 3], _G461, _G454) ? creep
Call: (9) ac([3], _G464, _G457) ? creep
Call: (10) ac([], _G467, _G460) ? creep
Exit: (10) ac([], 0, []) ? creep
Call: (10) _G459 is 3+0 ? creep
Exit: (10) 3 is 3+0 ? creep
Exit: (9) ac([3], 3, [3]) ? creep
Call: (9) _G456 is 2+3 ? creep
Exit: (9) 5 is 2+3 ? creep
Exit: (8) ac([2, 3], 5, [5, 3]) ? creep
Call: (8) _G453 is 1+5 ? creep
Exit: (8) 6 is 1+5 ? creep
Exit: (7) ac([1, 2, 3], 6, [6, 5, 3]) ? creep
Exit: (6) accum([1, 2, 3], [6, 5, 3]) ? creep
X = [6, 5, 3].