Related
So I am writing a predicate and part of it is to check if 2 two lists have the same tail.
I know, there is a last\2 but I tried this one as well but it failed and I suspect it's because of this part of code:
check([H|_,T],[Y|,_,U]):- T = U
It raises an error message: unexpected comma or bar at the of list
Is there an other way around?
You might be better off using last/2 but if you want to explicitly iterate you can do the following.
The predicate uses four clauses.
If they have one element each,
If they are both lists of more than two elements,
and 4. When one of the list lengths reach one.
ctail([H], [H]).
ctail([_, H1|T1], [_, H2|T2]) :-
ctail([H1|T1], [H2|T2]).
ctail([H1], [_, H2|T2]) :-
ctail([H1], [H2|T2]).
ctail([_, H1|T1], [H2]) :-
ctail([H1|T1], [H2]).
?- ctail([1, 2, 3, 4, 5], [a, b, c, d]).
false.
?- ctail([1, 2, 3, 4, 5], [a, b, c, d, 5]).
true
I am quite new in prolog and I've met this structure and I could not figure out how to substact the integer (1) and the matrix.
The exact structure is:
s(1,
[
[[a], [b, c], [f], [s]],
[[4], [k], [1], [5]],
[[f], [s], [w], []],
[[4], [], [w], [3, 53]]
]
)
I've tried with functions that extract elements of lists/matrices, but I haven't met anything in () before.
My guess is you have a variable with the content s(Integer, Matrix) and want to extract the Integer and Matrix. This is actually quite easy:
Lets go with a dummy object S = s(3, [[[1,2],[a,b]]]). You only have S and want to access 3 and [[[1,2],[a,b]]]
?- S = s(3, [[[1,2],[a,b]]]),
S = s(I,M).
I = 3,
M = [[[1, 2], [a, b]]],
S = s(3, [[[1, 2], [a, b]]])
You can put this in some kind of function too. The following example will output an addtion if the predicate name is a, a substraction for s and or h it will put the first parameter as head of a list of the second parameter:
doIt(a(A,B),Out) :-
Out is A+B.
doIt(s(A,B),Out) :-
Out is A-B.
doIt(h(A,B),[A|B]).
?- doIt(a(2,1),A).
A = 3
?- doIt(s(2,1),A).
A = 1
?- doIt(h(2,1),A).
A = [2|1]
the following code works, but if need help to understand how it is working.
%Multiplication of List Elements, Lists have same length
listmulti([],[],[]).
listmulti([H1|B1],[H2|B2],[Result|Spare]) :-
listmulti(B1,B2,Spare),
Result is H1 * H2.
Everything is understandable, but not the Spare variables. Without it the code don't work.
I added my Prolog trace here, to see what happens.
trace,(listmulti([2,1],[3,5],Result)).
Call:listmulti([2, 1], [3, 5], _5956)
Call:listmulti([1], [5], _6268)
Call:listmulti([], [], _6274)
Exit:listmulti([], [], [])
Call:_6272 is 1*5
Exit:5 is 1*5
Exit:listmulti([1], [5], [5])
Call:_6266 is 2*3
Exit:6 is 2*3
Exit:listmulti([2, 1], [3, 5], [6, 5])
Result = [6, 5]
What are the _5956 and so on digits? Help variables from Prolog?
What happens with the Spare variable, it is Empty all the time? Why i need the Spare variable? Why I can't write only [Result] so like this
listmulti([H1|B1],[H2|B2],[Result])
Thanks for your answers in advance and best greetings.
Prolog communicates the results of computations by binding variables to terms. Variables can start out unbound, i.e., not bound to any value, and can become bound during a computation by unification.
To some extent you already know this. After all, when you write a query like
?- listmulti([2,1],[3,5],Result).
you do not specify a value for Result -- it is unbound. But when you run the query, Prolog will bind Result to a term and tell you what it is:
Result = [6, 5].
We can visualize this by printing the value of Result before and after it is bound by calling listmulti:
?- write('before the query, Result is: '), write(Result), nl,
| listmulti([2,1], [3,5], Result),
| write('after the query, Result is: '), write(Result), nl.
before the query, Result is: _G1699
after the query, Result is: [6,5]
Result = [6, 5].
In the beginning, Result is just some unbound variable, which is shown as _G1699 in this case. (Different variables have different numbers so you can distinguish them.) After the query is run, that same variable is now bound to the list [6, 5].
This is also what the tracer was telling you, although it takes some practice to read its output:
Call:listmulti([1], [5], _6268)
...
Exit:listmulti([1], [5], [5])
This is a pair of states just before and just after executing listmulti([1], [5], Spare). The current instance of Spare is unbound before the call and is bound to [5] afterwards, as listmulti computed the element-wise product of the lists [1] and [5].
Now consider the following version of your predicate:
listmulti([],[],[]).
listmulti([H1|B1], [H2|B2], AllResults) :-
listmulti(B1,B2, ResultsForTheTailsOfTheLists),
Result is H1 * H2,
AllResults = [Result | ResultsForTheTailsOfTheLists].
When you call this with two lists of numbers in the first two arguments, operationally this will decompose those lists into their heads and tails, and compute the element-wise product of the tails. The result of this is a list of ResultsForTheTailsOfTheLists. The product of the heads is computed as Result. And then the results for the complete lists is just the list containing Result followed by all of the ResultsForTheTailsOfTheLists. Is this clearer?
The final twist is that in Prolog you can create lists and other data structures before you know what you will put in them. You can construct a list like this:
?- Head = a, Tail = [b, c], List = [Head | Tail].
Head = a,
Tail = [b, c],
List = [a, b, c].
but you can also construct the list first and only then bind its head and tail:
?- List = [Head | Tail], Head = a, Tail = [b, c].
List = [a, b, c],
Head = a,
Tail = [b, c].
And this is what is going on in your original definition: In the head, once you know that you are looking at two lists of numbers, you know that the result will be of the form [HeadResult | TailResults]. Having this term in the clause head builds it right away. Only later do you compute HeadResult and the TailResults through a recursive call. Overall this gives you a complete list.
?- permutation([A,B,C],Z).
Z = [A, B, C] ;
Z = [A, C, B] ;
Z = [B, A, C] ;
Z = [B, C, A] ;
Z = [C, A, B] ;
Z = [C, B, A] ;
false.
Makes sense. I can work on a permutation of [A,B,C] and that permutation contains the same elements as in [A,B,C], so everything I do to those elements will apply to my original list.
Now:
?- findall(X, permutation([A,B,C], X), Z).
Z = [[_G1577, _G1580, _G1583], [_G1565, _G1568, _G1571], [_G1553, _G1556, _G1559], [_G1541, _G1544, _G1547], [_G1529, _G1532, _G1535], [_G1517, _G1520, _G1523]].
Why?? Why is findall/3 giving me lists which contain completely unrelated variables, instead of A,B,C? The lists in Z are not even related to each other, so really the result I get is just 6 random lists of length 3, which is totally not what I queried.
With this behavior we get ridiculous results like this:
?- findall(X, permutation([A,B,C],X), Z), A = 1.
A = 1,
Z = [[_G1669, _G1672, _G1675], [_G1657, _G1660, _G1663], [_G1645, _G1648, _G1651], [_G1633, _G1636, _G1639], [_G1621, _G1624, _G1627], [_G1609, _G1612, _G1615]].
Which makes no sense from a logical standpoint.
I understand that findall/3 is not really a relational, pure logic predicate but I don't see how this justifies the behavior shown here.
My questions are therefore:
Why was this behavior chosen for the predicate?
Are there common situations where this behavior is actually preferable to the one I want?
How to implement a version of findall/3 with the behavior I want?
Why was this behavior chosen for the predicate?
findall/3 is a highly primitive built-in predicate that is relatively easy to implement and that does not address all the nitty-gritty details you are interested in. At least it is reentrant - thus can be used recursively.
Historically, DEC10 Prolog did not document findall/3. That is, neither in 1978 nor 1984. The 1984 version did however provide setof/3 which internally uses a findall-like predicate. Implementing it in ISO-Prolog (without findall/3) is relatively tricky since you have to handle errors and nesting. Many implementations rely on implementation specific primitives.
Are there common situations where this behavior is actually preferable to the one I want?
Findall succeeds if there is no solution whereas both setof/3 and bagof/3 simply fail. This might be a reason to prefer it. At least some more sophisticated constructs than those are needed which are most probably built based on findall.
It gets pretty messy in the presence of constraints. In fact, it is so messy, that as of the current point in time I am still unaware of an implementation that would deal in a reasonable manner with clpfd-constraints in this very situation. Think of:
?- findall(A, (A in 1..3 ; A in 5..7), As).
Here, SWI copies constraints, where SICStus does not copy them permitting you thus to use it as building-block for a more sophisticated implementation.
How to implement a version of findall/3 with the behavior I want?
First, consider setof/3 and bagof/3 (here). Maybe you are happy with them already - as long as no constraints are involved...
A solution to your last question.
?- setof(X,permutation([A,B,C],X),Z).
Z = [[A, B, C], [A, C, B], [B, A, C], [B, C, A], [C, A, B], [C, B, A]].
If we look at the description of findall at sicstus we see
findall(?Template,:Goal,?Bag) ISO
Bag is a list of instances of Template in all proofs of Goal found by Prolog. The order of the list corresponds to the order in which the proofs are found. The list may be empty and all variables are taken as being existentially quantified. This means that each invocation of findall/3 succeeds exactly once, and that no variables in Goal get bound. Avoiding the management of universally quantified variables can save considerable time and space.
So I guess the existential quantifying creates this unwanted behaviour of findall.
?- findall(X, permutation([A,B,C],X), Z), A = 1.
In this query Prolog will find all permutation of the elements on the list [A,B,C], but since Prolog can not instantiate the variables A, B, C, the result will be this that you are getting, the anonymous variable:
Z = [[_G1669, _G1672, _G1675], [_G1657, _G1660, _G1663], [_G1645, _G1648, _G1651], [_G1633, _G1636, _G1639], [_G1621, _G1624, _G1627], [_G1609, _G1612, _G1615]].
On the other hand, if you first instantiate the variables A, B and C, you will get a different result:
?- A=1, B=2, C=3, findall(X, permutation([A,B,C],X), Z).
A = 1,
B = 2,
C = 3,
Z = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
This didn't happend before in your query findall(X, permutation([A,B,C],X), Z), A = 1. because Prolog will first try to solve the condition findall(X, permutation([A,B,C],X), Z) and then A = 1
Hey I'm trying to create a predicate for the generating of a deep reverse on nested Lists in PROLOG.
Currently I got this predicate
reverse(L,A) :- rev(L,[], A).
rev([],A,A).
rev([H|L],R,A) :- rev(L,[H|R],A).
The result looks like this:
reverse([1,2,3],A).
A = [3, 2, 1].
reverse([[0,1],2,3],A).
A = [3, 2, [0, 1]].
The problem is, that the inner List is not reversed. It should look like this:
reverse([[0,1],2,3],A).
A = [3, 2, [1, 0]].
reverse([1,2,[3,4,5,[6,7],8],[9,10],11,12],A).
A = [12,11,[10,9],[8,[7,6],5,4,3],2,1].
Thanks for any help.
The way you represent your data is called defaulty, because you need a default case when reasoning over it:
is it a list? → something holds
otherwise → something else holds.
Such a representation is a rich source of troubles. Consider for example my_reverse/2 from the other answer. The main problem with it is that it prematurely and incorrectly commits to one of the cases, although both cases are still possible:
?- my_reverse([X], Ls).
Ls = [X].
But this answer only holds for the case where X is not a list! This problem leads to the following strange behaviour of the predicate:
?- my_reverse([X], Ls), X = [1,2,3].
Ls = [[1, 2, 3]],
X = [1, 2, 3].
This mean that even though X is a list, its elements are not reversed!
You should always aim for cleaner representations to distinguish the cases that can arise.
For example, what would you say about the following way to represent your data:
list(Ls) represents the list Ls
n(N) represents the number N.
With such a representations, we can distinguish the cases symbolically. I leave this as the starting point for a more declarative solution.
To keep things as simple as possible, we could add a test if the current element being checked is a list or not. If it is indeed a list, then its elements should be reversed as well. So in code:
my_reverse(L,R) :- rev(L,[],R).
rev([],A,A).
rev([H|T],A,R) :-
( is_list(H) -> % If H is a list
rev(H,[],X), % then reverse H as well
rev(T,[X|A],R)
;
rev(T,[H|A],R)
).
Also, not that it really matters, just to try and avoid confusion, note how I used A and R for respectively Accumulator and Result. In your code they are currently swapped, which -for me personally- can be a bit confusing, especially when predicates become longer and more complex.
Anyway, let's look at the queries you provided:
?- my_reverse([[0,1],2,3],R).
R = [3, 2, [1, 0]].
?- my_reverse([1,2,[3,4,5,[6,7],8],[9,10],11,12],R).
R = [12, 11, [10, 9], [8, [7, 6], 5, 4, 3], 2, 1].
And some general queries:
?- my_reverse(L,R).
L = R, R = [] ;
L = R, R = [_G2437] ;
L = [_G2437, _G2443],
R = [_G2443, _G2437] ;
L = [_G2437, _G2443, _G2449],
R = [_G2449, _G2443, _G2437] ;
L = [_G2437, _G2443, _G2449, _G2455],
R = [_G2455, _G2449, _G2443, _G2437]
...
?- my_reverse([[X,Y]|T],R), member(a,T), length(X,2).
X = [_G2588, _G2591],
T = [a],
R = [a, [Y, [_G2588, _G2591]]]
;
X = [_G2594, _G2597],
T = [a, _G2588],
R = [_G2588, a, [Y, [_G2594, _G2597]]]
;
X = [_G2594, _G2597],
T = [_G2582, a],
R = [a, _G2582, [Y, [_G2594, _G2597]]]
...
Note however that using this predicate, no termination occurs after finding the first answer to the query:
?- my_reverse(X,[X]).
X = [X] ;
...
But since this wasn't a requirement/demand in OP's question, I assumed it to be okay.
EDIT:
Please read #mat's answer as a follow-up to this problem.
an additional solution for your problem is to use cut and the built-in predicate "is_list/1" to check if you treat a simple term or a list in the current call.
here is the code:
deepReverse(List,R):-deepReverseTail(List,[],R).
deepReverseTail([],Acc,Acc).
deepReverseTail([H|T],Acc,R):- % when H is a list
is_list(H), % check if it's a list.
!, % cut the process if not.
deepReverseTail(H,[],Hrev), % reverse this current list
deepReverseTail(T,[Hrev|Acc],R). % continue the general recursion
deepReverseTail([H|T],Acc,R):- deepReverseTail(T,[H|Acc],R). % when H is a simple term
the "cut" in the third line make sure you treat only list in this definition, while treating simple terms will be in the next definitions.
an output example:
7 ?- deepReverse([a,[d,f],[],[[k],g]],R)
R = [[g, [k]], [], [f, d], a].