Understanding the splitting in Swi-prolog - list

I have this code for splitting input list into its halves. It seems to be OK.
halve(List,A,B) :- halve(List,List,A,B), !.
halve(B,[],[],B).
halve(B,[_],[],B).
halve([H|T],[_,_|T2],[H|A],B) :-halve(T,T2,A,B).
Ok, so I tried to decode it. The beginning is clear:
"Halve took list and 2 logic variables" is this:
halve(List,A,B)
(1) Then continuous this part:
:- halve(List,List,A,B).
And this means, that I am creating new two lists (List, List) from the first one or what? What exacly represents ":-"? I guess the new lists = halves will be the A, and B, right?
(2) Second, please, I don't quite get these two lines:
halve(B,[],[],B).
halve(B,[_],[],B).
Maybe you could explain it on some examples, please?
(3) Well, I hope after your explanation of (1) and (2), I'll get the final part by myself...
halve([H|T],[_,_|T2],[H|A],B) :- halve(T,T2,A,B).
Thank you very, very much for helping me.
Ok, our first problem already has its solution. Long story short, it works like this:
halve([1,2,3,4,5],[1,2],[3,4,5]).
->true
If you notice it splits the list into its halves but if the list has an odd number of the elements, the second half is the bigger one.
Now what I want to obtain is to have the first one bigger.
So I'm thinking about this:
I'm going to reach this:
Halves_div([1,2,3],A,B).
A=[1,2],
B=[3].
Let's say my input is list: [1,2,3]. So I'll start with splitting list's head and tail: [H|T] and then I will merge the H with new empty list - my 1st Half (A).
After that I have A=[1], B=[] and Input=[2,3].
For merging I have:
merge([],List,List).
merge([H|T],List,[H|New]) :- merge(T,List,New).
And one more thing - I need to check whether the 1st half is already >= 2nd half, right?
So this is my idea and only thing I'd love you to help me is to write it in prolog. I'm kinda confused how to put it together.
Thanks!
It seems my idea of solution is too complicated and I found something better!

To start, a Prolog clause looks like that:
Head :- Body
You can read that as "Head if Body", or "Body implies Head".
Note that sometimes you just have
Head
That's because Head is always true. Instead of calling Head a clause, we rather call it a fact in this case.
So here, we have:
halve(List,A,B) :- halve(List,List,A,B).
That means that halve(List, A, B) is true if halve(List, List, A, B) is true. Concretely it's just a way to delegate the work of halve/3 to halve/4, a so called worker predicate.
Why do we need a worker predicate? Well, because here we'd like to use another variable to calculate our A and B terms. But we couldn't do that with halve/3 because the 3 argument spots of halve/3 were already taken by the input list, List, the first half of the result, A and the second half of the result, B.
About the List, List thing, it's just a way to say that we call halve/4 with the same first and second argument, like you would in any programming language.
Then the interesting stuff starts. Prolog will try to prove that halve/4 is true for some given arguments. Let's say to illustrate the execution that we called halve/3 this way:
?- halve([1, 2], A, B).
Then, if you followed what I talked about previously, Prolog will now try to prove that halve/3 is true by proving that halve/4 is true with the following arguments: halve([1, 2], [1, 2], A, B)..
To do that, Prolog has 3 choices. The first choice is the following clause:
halve(B,[],[],B).
Obviously, that won't work. Because when Prolog will try to fit the second argument of the caller "in" the second argument of the callee through unification, it will fail. Because
[1, 2] can't be unified with [].
Only two choices left, the next is:
halve(B,[_],[],B).
Same thing here, Prolog cannot unify [1, 2] and [_] because _ is just a variable (see my post about the anonymous variable _ if you've troubles with it).
So the only chance Prolog has to find a solution to the problem you presented it is the last clause, that is:
halve([H|T],[_,_|T2],[H|A],B) :- halve(T,T2,A,B).
Here, Prolog will find a way to unify thing, let's see which way:
we have to unify [1, 2] with [H|T]. That means that H = 1. and T = [2].
we have to unify [1, 2] with [_,_|T2]. that means that T2 = [].
now we start to build our results with the next unification, ie A = [H|A'] (I primed the second A because variables are scoped locally and they are not the same). Here we tell that when we'll have our result calculated from the body of the clause, we'll add H to it. Here H is 1 so we already know that the first element of A will be 1.
Ok ok, unification succeeded, great! We can proceed to the body of the clause. It just calls halve/4 in a recursive manner with those values (calculated above):
halve([2], [], A, B).
And here we start all over again. Though this time things will be fast since the first choice Prolog has will be a good fit:
halve(B,[],[],B).
can be unified to
halve([2], [], A, B).
with those values: A = [] and B = [2].
So that's a good step, we now reached the "base case" of the recursion. We just have to build our result from bottom to top now. Remember when we called recursively our predicate halve/4 a few steps above? We had already said that the first element of A would be 1. Now we know that the tail is [] so we can state that A = [1]. We hadn't stated anything particular about B so B = [2] is left untouched as the result.
Now that I detailed the execution, you might wonder, why does this work? Well, if you pay attention, you'll note that the second argument of halve/4 is gone through twice as fast as the first one. [H|T] vs [_, _|T2]. That means that when we hit the end of the list with our second argument, the first one is still at the middle of our list. This way we can divide the thing in two parts.
I hope I helped you catch some of the subtle things at work here.

halve(List,A,B) copies first half of List to A and unifies second half with B
That will be true when length of our list will be even: halve(B,[],[],B).
That will be true when length of out list will be odd: halve(B,[_],[],B).
halve([H|T],[_,_|T2],[H|A],B) :- halve(T,T2,A,B).
Here we are setting 2 lets call them 'pointers' in each step we copy one element from beginning of our list to A because we want get first half.
Because in each step we are removing 2 elements from our list [_,_|T2] Predicate will stop when list will have only one left element or empty, then it will unify rest of our list with B. If you cant understand use trace/0

This version might prove useful ...
split_in_half(Xs, Ys, Zs) :- length(Xs, Len),
Half is Len // 2, % // denotes integer division, rounding down
split_at(Xs, Half, Ys, Zs).
split_at(Xs, N, Ys, Zs) :- length(Ys, N), append(Ys, Zs, Xs).

Related

Checking if the difference between consecutive elements is the same

I am new to using arithmetic in Prolog.
I’ve done a few small programs, but mostly involving logic. I am trying to implement a function that will return true or false if the difference between every consecutive pair of elements is the same or not.
My input would look like this: sameSeqDiffs([3, 5, 7, 9], 2)
I feel like I need to split the first two elements from the list, find their difference, and add the result to a new list. Once all the elements have been processed, check if the elements of the new list are all the same.
I’ve been taught some Prolog with building relationships and querying those, but this doesn’t seem to fit in with Prolog.
Update1: This is what I've come up with so far. I am brand new to this syntax and am still getting an error on my code, but I hope it conveys the general idea of what I'm trying to do.
diff([X,Y|Rest], Result):-
diff([Y,Z|Rest], Result2):-
Result2 = Result,
Z - Y = Result.
Update2: I know I still have much to do on this code, but here is where I will remain until this weekend, I have some other stuff to do. I think I understand the logic of it a bit more, and I think I need to figure out how to run the last line of the function only if there is at least two more things in the rest of the list to process.
diff([X,Y|Rest], Result):-
number(Y),
Y-X=Result,
diff([Rest], Result).
Update3: I believe I have the function the way I want it to. The only quirk I noticed is that when I run and input like: sameSeqDiffs([3,5,7],2).I get true returned immediately followed by a false. Is this the correct operation or am I still missing something?
sameSeqDiffs([X,Y], Result):-
A is Y - X,
A = Result.
sameSeqDiffs([X,Y,Z|T], Result):-
sameSeqDiffs([Y,Z|T], Result).
Update 4: I posted a new question about this....here is the link: Output seems to only test the very last in the list for difference function
Prolog's syntax
The syntax is a bit off: normally a clause has a head like foo(X, Y, Z), then an arrow (:-), followed by a body. That body normally does not contain any arrows :-. So the second arrow :- makes not much sense.
Predicates and unification
Secondly in Prolog predicates have no input or output, a predicate is true or false (well it can also error, or got stuck into an infinite loop, but that is typically behavior we want to avoid). It communicates answers by unifying variables. For example a call sameSeqDiffs([3, 5, 7, 9], X). can succeed by unifying X with 2, and then the predicate - given it is implemented correctly - will return true..
Inductive definitions
In order to design a predicate, on typically first aims to come up with an inductive definition: a definition that consists out of one or more base cases, and one or more "recursive" cases (where the predicate is defined by parts of itself).
For example here we can say:
(base case) For a list of exactly two elements [X, Y], the predicate sameSeqDiffs([X, Y], D) holds, given D is the difference between Y and X.
In Prolog this will look like:
sameSeqDiffs([X, Y], D) :-
___.
(with the ___ to be filled in).
Now for the inductive case we can define a sameSeqDiffs/2 in terms of itself, although not with the same parameters of course. In mathematics, one sometimes defines a function f such that for example f(i) = 2×f(i-1); with for example f(0) = 1 as base. We can in a similar way define an inductive case for sameSeqDiffs/2:
(inductive case) For a list of more than two elements, all elements in the list have the same difference, given the first two elements have a difference D, and in the list of elements except the first element, all elements have that difference D as well.
In Prolog this will look like:
sameSeqDiffs([X, Y, Z|T], D) :-
___,
sameSeqDiffs(___, ___).
Arithmetic in Prolog
A common mistake people who start programming in Prolog make is they think that, like it is common in many programming languages, Prolog add semantics to certain functors.
For example one can think that A - 1 will decrement A. For Prolog this is however just -(A, 1), it is not minus, or anything else, just a functor. As a result Prolog will not evaluate such expressions. So if you write X = A - 1, then X is just X = -(A,1).
Then how can we perform numerical operations? Prolog systems have a predicate is/2, that evaluates the right hand side by attaching semantics to the right hand side. So the is/2 predicate will interpret this (+)/2, (-)/2, etc. functors ((+)/2 as plus, (-)/2 as minus, etc.).
So we can evaluate an expression like:
A = 4, is(X, A - 1).
and then X will be set to 3, not 4-1. Prolog also allows to write the is infix, like:
A = 4, X is A - 1.
Here you will need this to calculate the difference between two elements.
You were very close with your second attempt. It should have been
samediffs( [X, Y | Rest], Result):-
Result is Y - X,
samediffs( [Y | Rest], Result).
And you don't even need "to split the first two elements from the list". This will take care of itself.
How? Simple: calling samediffs( List, D), on the first entry into the predicate, the not yet instantiated D = Result will be instantiated to the calculated difference between the second and the first element in the list by the call Result is Y - X.
On each subsequent entry into the predicate, which is to say, for each subsequent pair of elements X, Y in the list, the call Result is Y - X will calculate the difference for that pair, and will check the numerical equality for it and Result which at this point holds the previously calculated value.
In case they aren't equal, the predicate will fail.
In case they are, the recursion will continue.
The only thing missing is the base case for this recursion:
samediffs( [_], _Result).
samediffs( [], _Result).
In case it was a singleton (or even empty) list all along, this will leave the differences argument _Result uninstantiated. It can be interpreted as a checking predicate, in such a case. There's certainly no unequal differences between elements in a singleton (or even more so, empty) list.
In general, ......
recursion(A, B):- base_case( A, B).
recursion( Thing, NewThing):-
combined( Thing, Shell, Core),
recursion( Core, NewCore),
combined( NewThing, Shell, NewCore).
...... Recursion!

Finding a specific sequence of elements in a list, prolog

I have to write a predicate that takes a List and succeeds if the list contains elements "a, b, c"in that order anywhere in the list, other wise it fails. I am pretty lost on where to start(not looking for a solution, just a hint to the right direction).
Declarative wording
Almost always, when a Prolog task is formulated in a rather imperative way, the solution will be comparatively limited. This means that we typically can only use it in a few modes and directions, while other modes may even yield wrong results.
Therefore, I suggest to use more declarative wording.
You say:
a predicate that takes a list and succeeds if the list contains elements "a, b, c" in that order anywhere in the list, otherwise it fails.
That's a rather procedural way to look at this. Note that in Prolog, any argument can also be a logical variable, and thus there may not even be a list to "take". Instead, we expect the predicate to generate such lists in these cases!
Watch your wording! Very often, when you are able to express the task declaratively, an elegant and general Prolog solution will be straight-forward and often follows quite naturally from the task description.
Describing solutions
First, let us focus on what holds. There is no need to express what doesn't hold, because the predicate will not succeed anyways in such cases.
What do we want to describe?
Essentially, we want to describe lists of the form [...,a,b,c,...].
There are already some answers, with various drawbacks.
A pure way to do it uses the meta-predicate if_/3 from Indexing dif/2:
abc([X,Y,Z|Vs]) :-
if_((X=a,Y=b,Z=c), true, abc([Y,Z|Vs])).
Generality
This works in all directions. First, let us try the most general query, where the single argument is a fresh variable:
?- abc(Vs).
Vs = [a, b, c|_5032] ;
Vs = [a, b, a, b, c|_5144] ;
Vs = [a, b, a, b, a, b, c|_5286] .
Thus, we can generate solutions, which is a very nice property of a relation!
The predicate is monotonic, and therefore iterative deepening is possible to fairly enumerate answers:
?- length(Vs, _), abc(Vs).
Vs = [a, b, c] ;
Vs = [a, b, c, _11600] ;
Vs = [a, a, b, c] ;
Vs = [_11982, a, b, c],
dif(_11982, a) ;
Vs = [a, b, c, _11600, _11606] .
From this, it follows that there are no solutions with less than 3 elements. In this case, that's quite obvious. In other cases, such results may be much less obvious from the task description.
Efficiency
The predicate is deterministic if its argument is sufficiently instantiated.
For example:
?- abc([a,b,c]).
true.
?- abc([z,a,b,c]).
true.
?- abc([a,b,c,z]).
true.
Note that no choice points remain in these cases!
Here are three approaches you could take, in roughly ascending order by flexibility:
First, is to use the predicate nth0/3 to find the position of a, b, and c in the list, and then check that the position of a < position of b < position of c. For multiple instances of a, b, and c in the list (e.g. [c,b,a,b,c,a]) nth0 will find positions of each matching element in turn, such that if there are three positions that fit the criteria (even if they are not the first positions) the predicate will succeed.
Hint 1.1: The syntax for nth0 to find the position of a.
nth0(PositionA,[c,b,a,b,c,a],a)
Hint 1.2: The syntax of less than (for completeness)
PositionA < PositionB
Partial Solution 1: A sequence of commands using nth0 to check that a, b, and c appear in some order in the list [c,b,a,b,c,a] (assembling the predicate is left to you)
nth0(PositionA,[c,b,a,b,c,a],a),
nth0(PositionB,[c,b,a,b,c,a],b),
nth0(PositionC,[c,b,a,b,c,a],c),
PositionA < PositionB,
PositionB < PositionC.
Second approach uses list pattern matching - we observe that, when going down the list, we must encounter a, then b, then c. To do that, we can construct three predicates that find a, b, and c, and then pass on the rest of the list where appropriate. We must construct these predicates to ignore other elements until they see their target.
Hint 2.1: The head of a predicate where a is the first element of the list
find_a([a|Rest]) :-
Hint 2.2: The head of a predicate where anything is the first element of the list
find_a([_|Rest]) :-
Hint 2.3: When we find a, we start looking for b
find_a([a|Rest]) :-
find_b(Rest).
Hint 2.4: When we don't find a, we keep looking for a
find_a([_|Rest]) :-
find_a(Rest).
Hint 2.5: Order matters (kind-of)
If we place find_a([a|Rest]) first in the knowledge base then Prolog will always try to unify against it first, so we'll match the first a we find. If we place it second, this will still work, but with a lot of extra backtracking, and we'll find each a in reverse order.
Hint 2.6: Don't forget the base case!
Remember that, even though you don't need to do anything once you find c, you still need to create a fact stating that it is the head of the list: find_c([c|_]).
The third approach is essentially a generalised version of the second approach - instead of creating predicates to find a, b, and c, you create a predicate that finds a list of elements in order.
Hint 3.1: Your predicate should take two lists and compare the heads of each
compare([A|Targets],[B|Checks]) :-
Hint 3.2: If the same variable name appears in multiple places, it must have the same value for the predicate to match
compare([A|Targets],[A|Checks]) :- % succeeds when the same element is at the head of each list
Hint 3.3: If they match, keep going down both lists
compare(Targets,Checks).
Hint 3.4: If they don't match, only go down the Checks list
compare([A|Targets],Checks).
Hint 3.5: Never forget the base case (when there are no more targets)
compare([],_).
Hint 3.6: As before, ordering is still important
compare([A|Targets],[A|Checks]) :- ... should be in the knowledge base before compare(Targets,[_|Checks]) :- ...
Solution 3:
compare([],_).
compare([A|Targets],[A|Checks]) :-
compare(Targets,Checks).
compare(Targets,[_|Checks]) :-
compare(Targets,Checks).
Hope this helps!
Another way to describe the relation uses a grammar. You are talking about a sequence, well, that's what the dcg formalism is for!
:- set_prolog_flag(double_quotes, chars).
abcsubsequence(Cs) :-
phrase(abc, Cs).
abc -->
..., "abc", ... .
or alternatively, if you permit further text in between:
abc -->
..., "a", ..., "b", ..., "c", ... .
So what is this magic ...? It's just any sequence:
... --> [] | [_], ... .
Efficiency-wise mat's solution is much better. But for correctness reasons above versions are better since they fail for abcsequence([a,b,c|non_list]). However, making relations a tiny bit more general by permitting such solutions is quite common in Prolog, you just have to be aware of it.
Finding a,b,c
To find the letters a,b,c in a list in that order one should start with the comment by #lurker which says [X, Y, Z | T].
has_abc([a,b,c|T]).
Since I am using SWI-Prolog and prefer not to receive the warning
Warning: somecode.pl:
Singleton variables: [T]
I will make a small change by changing T to _
has_abc([a,b,c|_]).
and then run some simple test
?- has_abc([a,b,c]).
true.
?- has_abc([a,b,c,z]).
true.
?- has_abc([z,a,b,c]).
false.
As you can see the predicate has_abc can find a,b,c at the start of a list but not any place else.
Taking a list a part
In Prolog a list can be recursively deconstructed using [H|T]
deconstruct_list([Head|Tail]) :-
write('Head of list: '),write(Head),nl,
deconstruct_list(Tail).
and a few demonstration cases
?- deconstruct_list([]).
false.
?- deconstruct_list([a]).
Head of list: a
false.
?- deconstruct_list([a,b]).
Head of list: a
Head of list: b
false.
?- deconstruct_list([a,b,c]).
Head of list: a
Head of list: b
Head of list: c
false.
Putting the predicates together
Now combining the first two predicates for finding a,b,c and deconstructing a list gives us
has_abc([a,b,c|_]).
has_abc([_|T]) :-
has_abc(T).
and a few test cases
?- has_abc([]).
false.
?- has_abc([a]).
false.
?- has_abc([a,b]).
false.
?- has_abc([a,b,c]).
true .
?- has_abc([z,a,b,c]).
true .
?- has_abc([a,b,c,z]).
true .
?- has_abc([z,a,b,c,z]).
true .
Resolving the choice-point with a cut
Almost there. There is a small problem because for the true answers we had to press Enter to exit which indicates we have a choice-point.
A way to fix this is with a cut (!) which say that once we have an answer stop looking for more answers.
has_abc([a,b,c|_]) :- !.
has_abc([_|T]) :-
has_abc(T).
and a few test cases
?- has_abc([]).
false.
?- has_abc([a]).
false.
?- has_abc([a,b]).
false.
?- has_abc([a,b,c]).
true.
?- has_abc([z,a,b,c]).
true.
?- has_abc([a,b,c,z]).
true.
?- has_abc([z,a,b,c,z]).
true.
?- has_abc([d]).
false.
?- has_abc([d,e]).
false.
?- has_abc([d,e,f]).
false.
?- has_abc([d,e,f,g]).
false.
Notice that when running the test cases one did not have to press Enter to end the query.
Resolving the choice-point without a cut
See the answer by mat

Prolog create list of lists

I'm having some (or a lot of) trouble with lists of lists in prolog.
So I have a list of numbers, say [5,6,1,3] as input.
The output should be [[5,25],[6,36],[1,1],[3,9]].
I already have a predicate that 'return's the 2 item lists (keep in mind that I'll have to change the get_squared_pair function to get some other relevant value):
get_squared_pair(Number, Result) :-
get_squared_value(Number, SquareValue),
Result = [Number, SquareValue].
get_squared_value(Number, Result) :-
Result is Number * Number.
Until here it's pretty logical. Now I need a predicate that recursively iterates though a list, adds the squared pair to a new list, and then returns this lists of lists. What I have right now is:
return_list([], 0).
return_list([Head | Tail], Result) :-
get_squared_pair(Head, Add),
append(Add,Result),
return_list(Tail, Result).
This doesn't work for a number of reasons, and it's mostly because I can't seem to figure out how the recursion actually works with lists, much less lists of lists. Also it's currently running in the wrong order which doesn't help.
I understand this might be a bit vague but I've tried googling my way out of this one but can't seem to translate what I find into my own problem very well.
Any help would be much appreciated!
Let's look at your get_squared_pair/2 first. Although it's working, it can be tidied up a bit which will also help understand how Prolog works. The primary mechanism of Prolog is unification, which is not the same as assignment which occurs in other languages. In unification, Prolog examines two terms and attempts to unify them by instantiating variables in one or both of the terms to make them match. There are some predicates in Prolog, like is/2 which are used to evaluate expressions in one argument, and then unify the first argument with that result.
Your first predicate, then, which you have written as:
get_squared_pair(Number, Result) :-
get_squared_value(Number, SquareValue),
Result = [Number, SquareValue].
get_squared_value(Number, Result) :-
Result is Number * Number.
Can be simplified in two ways. First, you can consolidate the get_squared_value/2 since it's just one line and doesn't really need its own predicate. And we'll rename the predicate so it's not imperative.
square_pair(Number, Square) :-
S is Number * Number, % Square the number
Square = [Number, S]. % Unify Square with the pair
Prolog can unify terms in the head of the clause, so you can avoid the redundant unification. So this is all you need:
square_pair(Number, [Number, Square]) :-
Square is Number * Number.
On to the main predicate, return_list/2. First, we'll rename this predicate to square_pairs. When doing recursion with lists, the most common pattern is to continue reducing a list until it is empty, and then a base case handles the empty list. Your implementation does this, but the base case is a little confused since the 2nd argument is an integer rather than a list:
square_pairs([], 0).
This really should be:
square_pairs([], []).
Your main predicate clause isn't making correct use of append/2. There are two forms of append in SWI Prolog: append/2 and append/3. You can look up what these do in the SWI Prolog online documentation. I can tell you that, in Prolog, you cannot change the value of a variable within a predicate clause once it's been instantiated except through backtracking. For example, look at the following sequence that might be in a predicate clause:
X = a, % Unify X with the atom 'a'
X = b, % Unify X with the atom 'b'
In this case, the second expression will always fail because X is already unified and cannot be unified again. However, if I have this:
foo(X), % Call foo, which unifies X with a value that makes 'foo' succeed
bar(X, Y), % Call bar, which might fail based upon the value of 'X'
In the above case, if bar(X, Y) fails, then Prolog will backtrack to the foo(X) call and seek another value of X which makes foo(X) succeed. If it finds one, then it will call bar(X, Y) again with the new value of X, and so on.
So append(Add, Result) does not append Add to Result yielding a new value for Result. In fact, append with two arguments says that the second list argument is the concatenation of all the elements of the first list, assuming the first argument is a list of lists, so the definition of append/2 doesn't match anyway.
When thinking about your recursion, realize that the argument lists are in one-to-one correspondence with each other. The head of the result list is the "square pair" for the head of the list in the first argument. Then, recursively, the tail of the 2nd argument is a list of the square pairs for the tail of the first argument. You just need to express that in Prolog. We can also use the technique I described above for unification within the head of the clause.
square_pairs([Head | Tail], [SqPair | SqTail]) :-
square_pair(Head, SqPair),
square_pairs(Tail, SqTail).
square_pairs([], []).
Now there's another simplification we can do, which is eliminate the square_pair/2 auxiliary predicate completely:
square_pairs([Head | Tail], [[Head, SqHead] | SqTail]) :-
SqHead is Head * Head,
square_pairs(Tail, SqTail).
square_pairs([], []).
There's a handy predicate in Prolog called maplist which can be used for defining a relationship which runs parallel between two lists, which is the scenario we have here. We can bring back the square_pair/2 predicate and use maplist:
square_pairs(Numbers, SquarePairs) :-
maplist(square_pair, Numbers, SquarePairs).
So you want to turn your list into another, such that each element (a number) is turned into a two-element list, the number and its square.
All you need to do is to tell that to Prolog. First, the second one:
turn_into_two(Num, [A,B]):-
what is A?
A is Num,
what is B? We just tell it to Prolog, too:
B is ... * ... .
Now, on to our list. A list [A|B] in Prolog consists of its head element A, and its tail B - unless it's an empty list [] of course. It doesn't matter what the list's elements are; a list is a list.
We need to account for all cases, or else we're not talking about lists but something else:
turn_list([], Res):-
so what is our result in case the list was empty? It should be empty as well, right?
Res = ... .
in the other case,
turn_list([A|B], Res):-
our result won't be empty, so it'll have its head and tail, correct?
Res = [C|D],
next we say what we know about the heads: the input list's head turns into that two elements list we've described above, right?
turn_into_two(A,C),
and then we say our piece about the tails. But what do we know about the tails? We know that one is the result of the conversion of the other, just as the whole list is:
turn_list( ... , ...) .
And that's it. Incidentally, what we've described, follows the paradigm of mapping. We could have used any other predicate in place of turn_into_two/2, and it would get called for each of the elements of the input list together with the corresponding element from the resulting list.

Declarative interpretation of this program that says if an element belongs to a list

From what I have understood the declarative paradigm indicate what is important to reach the solution and not how reach it but, being accustomed to think procedurally, I often make confusion...
So the solution is this one:
mymember(X, [X|_]).
mymember(X,[_|T]) :- mymember(X,T).
This is my declarative interpretation of this simple program:
1) X belong to the list if it is TRUE that X is the Head of this list (if the head element of the list unifies with the X element that I would know if is in the list)
2) If the first fact is not true (X don't unifies with the first list element) the program try to execute the second rule (and maybe here I have some interpretation problem). This rule say that: the head is true if the body of the rule is true)
The head of rule say that: X belongs to the TAIL of the list (I use an anonymous variable using the _ character to say that don't care of the first element of the list)
So this rule say that: It is TRUE that the X element belong to list without its head if it is TRUE that the X element belong to the tail of the list
Is it a correct declarative and logic interpretation of this program or I am missing something?
You're reading them as exclusive-or, but they're actually inclusive-or. Both 1) and 2) are correct, minus the connective "if the first fact is not true". It's not necessary for 1) to be false for 2) to hold. In other words, it can be true that X is both the head of the list and present in the tail of the list (for instance mymember(a, [a, b, a]).
Edit: responding to your comment.
There's a language barrier issue here, so let me try answering your question with yes and no.
Yes, that using ; produces another answer is evidence that Prolog was able to compute alternative answers. In one sense, ; triggers backtracking manually, but in another sense it is Prolog asking you if this is the answer you wanted, and then you're able to say "yes" or "no." When you say ; you're telling Prolog, in essence, "this isn't the right answer." But this is not the only way to trigger backtracking; in fact, most of the time you won't trigger it manually at all.
For instance, let's look at this:
even_member(X, L) :- member(X, L), 0 is X mod 2.
?- even_member(X, [1,5,17,23,4,19]).
X = 4 ;
false.
So here I defined a predicate that says, declaratively, X is an even_member of L if X is a member of L and X mod 2 = 0. When I used the predicate, we got the answer X = 4. We then pressed ; to say, this isn't the right answer, and Prolog said there are no more answers. But internally, member(X, L) backtracked 5 times before it found an element that satisfied the second part of the predicate--in other words, the statement 0 is X mod 2 tells Prolog that 1, 5, 17 and 23 are "wrong" the same way we do by pressing ; interactively. When we said we wanted another answer, we engaged the same machinery, so Prolog went back to member(X, L), found 19, and then found that 19 is not divisible by two and gave up.
Prolog backtracked six times, five of those times just to get the one answer. We only asked it to backtrack once, and it happened that it was the last possibility so it didn't backtrack again.
Let me try:
mymember(X, [X|_]).
X is a member of the list if it's the first element of the list
mymember(X,[_|T]) :- mymember(X,T).
X is a member of the list if it's a member of the rest of the list.
Suppose I give you a stack of (paper) programmer resumes and say "see if there is a programmer who knows Prolog among these"
What do you do? You look at the top resume. If that programmer knows Prolog, you're done.
If not, then the only way there can be such a resume is if it's in the rest of the stack.
point 2) doesn't hold: Prolog will try each rule searching for a solution.
But it will follow a strictly specified order searching in your database, resulting in a depth first search of the solution space.
I would read
X is a member of a list if it is the first element (i.e. unify the head, clause 1), or is a member of the tail (clause 2).

How to find the Nth element of a list, and print said element out?

so i have a homework question that asks me to find the third element of a list, as well as the last element of a list and print them out (2 separate programs).
I Thought my Code would work to find the third element, by keeping track of a index, but i recieve a error when i try to run the code:
findthird([], Result).
findthird(List, Result) :- secondFunc(List, 0, Result).
secondFunc([Head|Tail], Count, Result) :-
Count < 3, Count is Count+1, secondFunc(Tail, Count, Result).
secondFunc([Head|Tail], Count, [Head|Result]).
Have any ideas for this?
The output i receieve now Is :
| ?- findthird([2,3,4], Result).
Result = [2|_]
yes
I am still having a tough time wrapping my head around Prolog, i just cant seem to understand it.
Any help is appreciated as always,
Thank.
Updated with new attempt code***
Updated ** This is the code that solved my problem:
findthird([], Result).
findthird(List, Result) :- secondFunc(List, 0, Result).
secondFunc([], Count, []).
secondFunc([Head|Tail], Count, Result) :-
Count1 is Count+1, Count1 < 3, secondFunc(Tail, Count1, Result).
secondFunc([Head|Tail], Count, Head).
Input:
| ?- findthird([3,4,5], Result).
Output:
Result = 5 ?
yes
Input:
| ?- findthird([3,4,5,6,7], Result).
Output:
Result = 5 ?
yes
First of all, you have to understand that in Prolog, you don't manipulate return values of function. The reason behind this is that you do not manipulate functions, but predicates. So length(List) never evaluates to a number, but to true or false, as any other predicate. When you write findelement(List, length(List), len... the findelement predicate won't be called with something like [a, b, c] and 3, it will be called with something like [a, b, c] and length([a, b, c]). So already your program cannot work.
That put aside, your program is still very wrong. The basic way a recursion works in prolog or in functional languages (as well as when you use structural induction in maths) is as follows :
a clause for initialization
a clause for heredity
In your program, you don't have an initialization clause. Meaning that when recursion hits [], no clause can handle it, and the thing fails. The rest is false too, but I think it's especially important to get the recursion principles right first.
To illustrate that without spoiling the problem for you (it's homework after all), I'll take an example : say you wanna test if a sheepfold is safe. The sheepfold is safe if there's no wolf in it. If we represent the sheepfold by a list and the wolf by the atom wolf, we can write the predicate like that :
Initialization : if the sheepfold is empty, it's safe, there's no wolf in it.
safe_sheepfold([]).
Heredity : if the sheepfold is safe with n-1 members, it's safe with n members if the added member is not a wolf :
safe_sheepfold([Animal|Sheepfold]) :-
Animal =\= wolf,
safe_sheepfold(Sheepfold).
And that's it. To see how prolog handles the request, compile this and issue a trace. command before running the predicate, as pointed out in your last question, it will help you to understand how things work.
To let you think about that with a more concrete example, here is a classic predicate, factorial (it uses arithmetic too) :
Here is our initialization clause :
factorial(0, 1).
Here is our heredity clause :
factorial(N, F) :-
N > 0,
NextN is N - 1,
factorial(NextN, NextF),
F is NextF * N.
To keep this simple I didn't make this predicate tail recursive nor used cuts, you'll learn about those things later on!
I hope my rambling will be of some help.
edit post update :
It's almost that ! Now just a few more hints : the result you want is not a list, it's just an element, so try to modify the last clause to just return the element, not a list with the element. And the initialization clause is actually your last clause here (the thing that checks if you're above 3), so you don't need the one with [] ! You're almost there :)