Prolog variable names - prolog

for example..
insert(X,Ys,[X|Ys]).
insert(X,[Y|Ys],[Y|Zs]) :- insert(X,Ys,Zs)
why the use of Zs as a variable.. the base case is obviously simple.. head of X::YS.
but the recursive statement is going to be a continuation from the 1st goal.
so for insert(a,[b,c],L) you get L=[a,b,c]
second time around you get [b,a,c]
third time you get [b,c,a]
but what is the actual technical definition of Zs in the program?
[trace] 1 ?- insert(a,[b,c],L).
Call: (6) insert(a, [b, c], _G522) ? creep
Exit: (6) insert(a, [b, c], [a, b, c]) ? creep
L = [a, b, c] ;
Redo: (6) insert(a, [b, c], _G522) ? creep
Call: (7) insert(a, [c], _G595) ? creep
Exit: (7) insert(a, [c], [a, c]) ? creep
Exit: (6) insert(a, [b, c], [b, a, c]) ? creep
L = [b, a, c] ;
Does the continuation begin at the recusive call? Meaning that the 1st goal ended # the base case.. so we start next time # the recursive? Also I can see start using different variable locations for L (aka _G522 vs _G595).

Zs is the result of inserting X into Ys.
In Prolog, you don't usually speak of continuations, but of choice points. When insert(a,[b,c],L) has returned its first result and you start backtracking, the Prolog compiler goes back up into the call chain to find the last choice point:
the last operation was execution of insert's first clause, which was deterministic and bound L;
before that, the last operation was choosing between both clauses, which was a choice point.
Since at this choice point, the first clause was selected, the second one is chosen upon backtracking, causing Zs to be bound in the predicate. L is unbound by backtracking from the first clause and re-bound when the second option returns.

There are no continuations in Prolog, but there's built in backtracking.
To be honest it took me some time too to understand the program.
The thing is that Prolog heavily relies on pattern matching, and choicepoints are inserted when there's more than one pattern that matches. If you want a deterministic program (i.e. without choicepoints) you have to ensure that at a time only one pattern matches (this is the recommended way), or the undesired execution path fails somewhere (this means you throw away all the calculations done in this path). The simplest way to ensure one choicepoint is using the cut operator (!/0).
"what is the actual technical definition of Zs in the program?"
In Prolog you don't have to declare variables, they can be introduced anywhere, and where they get bound (get an actual value, that's immutable) is sometimes hard to follow. Without the first predicate there would be always an unbound variable at the and of the second list, but that variable gets bound when being unified with [X|YS] in the first predicate after the recursive call. As the first predicate doesn't contain a body, the program terminates, and offers a solution to the user. As you see your program can't terminate in the second predicate, only in the first, but that's not surprising from a recursive function, just think of the classic factorial example.
factorial(0,1).
factorial(N,F) :-
N>0,
N1 is N-1,
factorial(N1,F1),
F is N * F1.

Related

First elements of list of list Prolog

I m studying Prolog and i see this code
foo([],[]).
foo([[A,_ ]|L], [A|P]) :-foo(L ,P).
The result say that this code take N element of list of list,
Ad example if we give this query:
?foo([[car],[house],[man]],X)
X= [c,h,m]
At first read i see that something wrong.
For me this code take the tail of list of list and the rest of first element of the list , so for me first expansion will be (trace)
foo([[house],[man]], ar)
foo([[man]], ouse)
foo([], an)
false.
I try to compile with swi-prolog and give this trace:
[trace] ?- trace,foo([[car],[house],[man]],X).
Call: (9) foo([[car], [house], [man]], _1016) ? creep
Fail: (9) foo([[car], [house], [man]], _1016) ? creep
false.
What are I wrong?
Obtaining the first elements
The pattern [A, _] in your clause is wrong, or at at least not generic enough. [A, _] unifies with a list that contains exactly two elements, but this will thus fail for lists with more than two elements, or with one elements, like you found out.
You need to use the [A|_] pattern: indeed a list where the head is A, and we are not interested in the rest (tail). like:
foo([],[]).
foo([[A|_]|L], [A|P]) :- foo(L, P).
That being said, you can simplify this, by implementing a predicate that takes the head of a list:
head([H|_], H).
and then make use of maplist/3 [swi-doc]:
foo(A, B) :-
maplist(head, A, B).
maplist will thus call head like head(Ai, Bi), with Ai and Bi elements of A and B respectively.
Obtaining a substring with the first character
but based on the sample output, this is not what you want: you also want to obtain the first "character" of the atom, we can do that by using string_chars/2 [swi-doc]:
head_first([A|_], C) :-
string_chars(A, [C|_]).
and then define foo/2 again with maplist/3 [swi-doc]:
foo(A, B) :-
maplist(head_first, A, B).
we then obtain:
?- foo([[car],[house],[man]], X).
X = [c, h, m].

Prolog - How do I get the tail to not be null

I have the following problem:
Define a predicate sorted(LL), that is satisfied when the list LL
contains other lists that are sorted in order of increasing length.
For example:
?- sorted([[],[1],[1,1],[1,1,1]]) -> yes.
?- sorted([[],[1],[1,1]]) -> yes.
?- sorted([[1],[],[1,1],[1,1,1]]) -> no.
And I have this code so far:
% shorter/2
shorter([],_).
shorter([_|T1], [_|T2]) :- shorter(T1,T2).
% sorted/1
sorted([]).
sorted([_]).
sorted([L1,L2 | T]) :- shorter2(L1, L2), sorted([L2,T]).
The problem is contained in the above line: sorted([L2,T]). When only one element is left in the list of lists, that call will append an empty list [] because of which shorter/2 will fail. It is depicted in the following SWIPL trace.
[trace] ?- sorted([[1],[2,3]]).
Call: (6) sorted([[1], [2, 3]]) ? creep
Call: (7) shorter2([1], [2, 3]) ? creep
Call: (8) shorter2([], [3]) ? creep
Exit: (8) shorter2([], [3]) ? creep
Exit: (7) shorter2([1], [2, 3]) ? creep
Call: (7) sorted([[2, 3], []]) ? creep <-- empty list appended
Call: (8) shorter2([2, 3], []) ? creep
Fail: (8) shorter2([2, 3], []) ? creep
Fail: (7) sorted([[2, 3], []]) ? creep
Fail: (6) sorted([[1], [2, 3]]) ? creep
#PauloMoura already gave you the right answer. Is there anything to learn about this? How did you encounter that problem? And how can you locate such problems systematically? I assume that you did not jump into the debugger to look at all those traces for sheer curiosity and a low on supply of animated gifs.
You rather encountered a problem. That is, you had the goal sorted([[1],[2,3]]). which you expected to succeed, but it did not. So you had here some unexpected failure. Sometimes also called insufficiency or incompleteness. This means that the definition for sorted/1 is too specialized, it describes a set of solutions that is too small — at least it misses sorted([[1],[2,3]]).
It often helps to minimize the problem, first. Also sorted([[],[3]]) fails, although we expect it to succeed. And sorted([[],[]]) even loops.
Understanding non-termination
Loops? That's often even easier to localize in a pure Prolog program. I will add goals false and goals like T = [] into the program. The resulting program fragment (called a failure slice) certainly will become completely dysfunctional. But it will retain a very nice property. For: if this new fragment loops, then also the original program will loop. Here is that program that still loops:
?- sorted([[],[]]), false.
sorted([]) :- false.
sorted([_]) :- false.
sorted([L1,L2 | T]) :- T = [], L1 = [], L2 = [],
shorter(L1, L2),
sorted([L2,T]).
shorter([],_).
shorter([_|T1], [_|T2]) :- false,
shorter(T1,T2).
in other words:
sorted([[],[]]) :-
shorter([],[]),
sorted([[],[]]).
So, procedurally speaking, that rule does not (always) reduce the length of the list.
Concluding reading
Another way to understand the problem is to read the recursive rule right-to-left in the direction the arrow is pointing. Actually, :- is meant to symbolize ←, well, 1970s style (listen to this French 1972 summerhit to until you understand). So let's try this. I will read:
sorted([L1,L2 | T]) :- shorter2(L1, L2), sorted([L2,T]).
^^^^^^^^^^^^^^ starting here
I start on the right side and interpret this as:
Provided, sorted([L2,T]) is true.
Maybe some extra remark: Now, you might get pretty uneasy. You might say: Who knows this? Maybe that is not true at all! But the point is, it's just conditional. OK?
and provided shorter(L1, L2) is true
then, we can conclude that sorted([L1, L2|T]) is true.
So we take a list of length 2 as granted and conclude that a list of length 2 or more holds as well.
But where do we actually state that a list of length 2 holds? There is no other place than this rule. Thus: Nowhere is this stated. And thus lists of length 2 or longer will never be sorted.
You have two typos in the last clause of the sorted/1 predicate, which should be:
sorted([L1,L2| T]) :- shorter(L1, L2), sorted([L2| T]).

Prolog: Compare 2 Lists and find out if at least one member of the first list exists in the other one

In the quest of learning more about prolog (and in the interest of solving my assignment), I have come across a situation where I need to compare 2 lists and find out if AT LEAST ONE element match ...
Here is an example what I want to do:
?-match([a,b,c],[x,y,z]).
no.
?-match([a,b,c],[x,y,b]).
yes.
My solution up to now:
compare_list([],[]).
compare_list([],_).
compare_list([L1Head|L1Tail],List2):-
member(L1Head,List2),
compare_list(L1Tail,List2).
but this solution gives a true when all the members of List1 are present in List2!
Please people, don't think that I am cheating on an assignment, the problem is much much more complex, I am just stuck at this point and need help to get out of this sticky corner... otherwise I have done the entire assignment myself!
your problem can be solved using the simpler builtins
match(L1,L2) :- member(E,L1),member(E,L2). % full join
add the nasty cut if you are really interested only in 'at least one' solution
match(L1,L2) :- member(E,L1),memberchk(E,L2),!. % really, just the first!
I'll comment on the attempt you've made, which is close, but not quite there:
compare_list([],[]).
compare_list([],_).
The first clause for compare_list/2 says that the empty list has at least one element in the empty list. The second says the empty list has at least one element in any other list. So the first clause is redundant (it's already covered by the second). Whether you want this to be true (that an empty list has an element in any other list) is up to you. Since an empty list has no members, one might consider this a failure case (and, thus, not be declared as true) but you can call it true by definition if you wish. However, it will cause some issues in the recursive case once you have your predicate correctly defined since reducing down to [] will become true and ultimately it might find any list has elements in any list (oops!). I'd leave these two clauses out and consider this case a fail.
compare_list([L1Head|L1Tail], List2):-
member(L1Head, List2),
compare_list(L1Tail, List2).
This says that the first list has an element in the second list if: (1) the head of the list is a member of the second list, AND (2) the tail of the first list has an element in the second list. Does this sound logically correct? If you think this through, given there are no additional compare_list/2 clauses, this is true only if EVERY element of the first list is a member of the second list, as you have observed.
Finally, you're missing the case where the first list has a head that is not a member of the second list. This shouldn't necessarily be a failure since the tail of the first list may have a member in the second list, even if the first element (head) is not a member.
Another way is to use nth0 predicate.
match(L1, L2) :-
nth0(_, L1, SharedItem),
nth0(_, L2, SharedItem).
The first nth0 says "is there a L1 list item with index '_' (ie don't care whether it is in first, second etc. position in the list), whose name is variable SharedItem.
The second nth0 does the same for L2.
But the nice trick is in the unification.. by using the same variable name SharedItem on both nth's, prolog will continue iterating through the lists until the same item is in both.
As always the 'trace.' predicate is your best friend.. run it before calling the above to see what prolog is doing in the background:
[trace] ?- match([a,b,c],[x,y,b]).
Call: (6) match([a, b, c], [x, y, b]) ? creep
Call: (7) lists:nth0(_G1965, [a, b, c], _G1967) ? creep
Exit: (7) lists:nth0(0, [a, b, c], a) ? creep
Call: (7) lists:nth0(_G1968, [x, y, b], a) ? creep
Fail: (7) lists:nth0(_G1968, [x, y, b], a) ? creep
Redo: (7) lists:nth0(_G1968, [a, b, c], _G1970) ? creep
Exit: (7) lists:nth0(1, [a, b, c], b) ? creep
Call: (7) lists:nth0(_G1968, [x, y, b], b) ? creep
Exit: (7) lists:nth0(2, [x, y, b], b) ? creep
Exit: (6) match([a, b, c], [x, y, b]) ? creep
true .
So the 'outer' loop is L1.. it first tries index 0 of L1(a), then when it fails to find it in L2, it does a Redo (of the first nth0), but this time with index 1(b), and finds it, then returns true.
Using your example predicate match/2. The solution is as simple as traverse recursively the List1 (on the left) and check if the Head belongs to the List2 via the memberchk/2 predicate. The reason to use memberchk/2 is that it succeeds only once (i.e., not re-executable on backtracking) and this is what your "AT LEAST ONE" condition states. If the List1 is empty, the predicate fails.
Code:
match([Head|Tail], List2):-
memberchk(Head,List2).
match([_|Tail],List2):-
match(Tail,List2).
Examples:
| ?- match([a,b,c],[x,y,z]).
no
| ?- match([a,b,c],[x,y,b]).
yes
| ?- match([a,b,c],[]).
no
| ?- match([],[x,y,b]).
no

what does the follow prolog codes do?

I am having trouble understanding the codes below.
Can someone explain step by step what is happening if I have the follow input:
append([1,2,3], Lst).
Actually, I don;t get how 1 and 2 is appended the list Lst as a result.
append([_], []).
append([H|T], [H|N]) :- append(T,N).
It sounds like you're new to Prolog. If so, welcome! Let's analyze this.
This unfortunately-named function has two clauses. Prolog looks at the clauses in order to see which one applies. When it finds one that matches, it tries to perform it. If there's a failure somewhere in performing it, it will back up and try the next option. Where precisely these choice points are varies depending on the program; in this program, the only one will be at the clause level, deciding which rule to use.
One way of looking at the first rule is that it is saying "A list with one element, regardless of what that element is, is related to the empty list." Looking at append([_], []), if we had X = [foo] and Y = [], it would hold, because [foo] is a one-item list and [] is the empty list. This rule is good Prolog style, because it will work regardless of instantiation: we could supply the left or the right or neither, it doesn't matter.
The second clause is also quite simple. It says that the left argument and the right argument are related if they both start with the same item, and if the rest of the lists are also related by this same predicate. In other words, if I have two lists X and Y such that append(X, Y) is true, then append([H|X], [H|Y]) is also true. It doesn't matter what H is and it doesn't matter what X and Y are, except insofar as would be implied by append/2.
Thinking logically, if I know that any one-item list is related to the empty list, and any list is related to a list that starts with the same item and otherwise is the same, the only kinds of lists that can be so related are lists where every item is the same, except the left list has one more item in it at the end which is not present on the right. So [1,2,3,4] is related to [1,2,3], but so is [1,2,3,foo] and [1,2,3].
Procedurally, let's look at what happens as this predicate is processed with this set of arguments:
append([1,2,3], X).
The first rule won't match on [1,2,3]. So we must look at the second rule:
append([1|[2,3]], [1|X]) :- append([2,3], X).
We can repeat:
append([2|[3]], [2|Y]) :- append([3], Y).
Now the first rule does match:
append([3], []).
So putting it all together:
append([1,2,3], [1|X]) implies
append([2,3], X=[2|Y]) implies
append([3], Y=[])
so Y = []
so X = [2]
so the right side is [1,2].
A Prolog trace will show you basically the same information:
?- trace, append([1,2,3], X).
Call: (7) append([1, 2, 3], _G1633) ? creep
Call: (8) append([2, 3], _G1752) ? creep
Call: (9) append([3], _G1755) ? creep
Exit: (9) append([3], []) ? creep
Exit: (8) append([2, 3], [2]) ? creep
Exit: (7) append([1, 2, 3], [1, 2]) ? creep
What makes this Prolog code confusing is that it doesn't look like you've told Prolog how to do anything. And it's true, you haven't, but by specifying what is true logically, Prolog is able to figure it out by itself. This is pretty clever code. If this were Haskell, we'd be talking about the built-in function init, which returns all of the list but the last item.
Hope this helps!

How to implement list concatenation in Prolog?

I have the following compact example that take 3 parameter L1, L2, L3 and append L1 and L2 in L3 (verify that L3 is the concatenation of L1 and L2)
I have this code (that work well):
myappend([], L, L).
myappend([X|L1], L2, [X|L]) :- myappend(L1,L2,L).
The fact is the base case and say that when the first list is a void list, the concatenation of the first list with second list is just the second list.
Ok, this is clear...the rule is pretty clear for me (but not at all) I can think this rule as the predicate that testing whether the 1st, 2nd and 3rd argument has the relation of 1st and 2nd concatenates is the 3rd argument
Ok, I'm trying to express the previous code in an extended form in which I have the body of this rule that represents all the predicates that must be satisfied (have to be TRUE) before so that the head of the rule is itself satisfied.
I have some problem to implement this code in SWI Prolog, this is my code:
concatena([],L,L).
/* REGOLA */
concatena(L1,L2,L3) :- L1 = [_|T], /* Always true: anonymous variable: "_" unifies everything */
concatena(T,L2,L3). /* Recursively call on the tail of L1 */
[X|L1],
[X|L3].
The fact is the base case (as the previous working example)
In my experiment the rule is different.
So that the head of the rule is verified, all the predicates in it's body have to be true...
I think that my idea is good until reaching the base case, in fact doing:
L1 = [_|T], /* It is always true */
concatena(T,L2,L3) /* Call recursively on a subproblem of the original problem, this problem have one less element
OK, so in this way, the base case is reached and so L3 is correctly unified with L2
In fact in the trace I have:
[trace] 3 ?- concatena([a,b],[c,d],L3).
Call: (6) concatena([a, b], [c, d], _G1514) ? creep
Call: (7) [a, b]=[_G1592|_G1593] ? creep
Exit: (7) [a, b]=[a, b] ? creep
Call: (7) concatena([b], [c, d], _G1514) ? creep
Call: (8) [b]=[_G1595|_G1596] ? creep
Exit: (8) [b]=[b] ? creep
Call: (8) concatena([], [c, d], _G1514) ? creep
Exit: (8) concatena([], [c, d], [c, d]) ?
(This is the same thing that happens when I look to the trace of the original working example...so until here should be corrected)
The problem is when the program do backtracking, don't work !!!
In the trace in fact I have this (this is how end the previous incomplete trace):
Exit: (7) concatena([b], [c, d], [c, d]) ? creep
Exit: (6) concatena([a, b], [c, d], [c, d]) ? creep
L3 = [c, d]
I am not completely clear what you are trying to do here: rewrite the second part of the myappend rule so that all the arguments are simple variable terms? In that case, you can just rewrite the arguments of the original myappend with the = operator:
concatena(L1,L2,L3) :- L1=[X|T], L3=[X|L4], concatena(T,L2,L4).
The second part of your rule, as you've written it here,
[X|L1],
[X|L3].
isn't being counted as part of the rule since it follows the ., so there is no backtracking and nothing is happening as the recursion is unwinding.

Resources