Comparing first and last element of list with append - prolog

I'm a bit of a prolog noob thats why i am asking here, i couldn't find the anser else where.
The thing i am trying to do is this function in a different way:
firstlast([H,H]).
firstlast([F,_|T]):- firstlast([F|T]).
it basicly finds out if the first and last element is the same in a list with two or more elements.
Now i want to make this function with append, so instead of recursion just a single call to append.
append([],U,U).
append([H|T],U,[H|V]) :- append(T,U,V).
Example of how it should work:
firslasta([1,2,3,4,1]).
true.
firstlasta([1,3,4,1,5]).
false-
firstlasta([2,5,2,3,6,2]).
true.
Any help with this would be greatly appriciated :).

it's easy, using idiomatic Prolog:
to identify the first element of a list, (the Head, you know), we use[Head|_], where the underscore, an anonymous var, stay for an unspecified (the uninteresting) list' tail.
In a list of length 1, we have just the last to identify. Then append a list starting with an Elem to a list of 1 Elem:
firstlast(L) :- append([Elem|_], [Elem], L).

Related

Prolog checking if 2 lists have same number of elements

I am trying to figure out how to do this little thing. I have 2 lists for example [1,1,2,3,4] and [2,1,4,3,1], I need to confirm if all elements from list 1 are included in list 2, soo if i give the above lists as input this should be true, but if its like this [1,1,2,3,4] and [2,1,4,3,1,1] (three 1's) it should give false, this has to be done without using sort function.
I assume you know how to write a list as head and tail ([H|L]).
So you could use the predicate member/2 to ask for every element from the first list to be in the second list as well, but this would not solve the issue of duplicates. Using the predicate length/2 will not help in this case. So you need something that retracts one matching element from a list. You can either write your own find-and-remove-predicate or use the predicate append/3 to do so. append/3 is thought to append 2 lists to form a third one, but it can also be used to divide one list into two. If you state that your element as the head element of the second divided list you basically get a 'remove element' functionality. Once you've got the 2 divided lists, combine them into a new list and call the predicate again, but this time without the head element from list one and with the reappended-list. So in each step you remove one element from each list until you finally hit two empty lists (permut([],[]).). If something other than this two cases should appear, then the two lists are not permuations of each other and the predicate fails.
Since there is no use in backtracking other positions I inserted a cut (!) after successfully finding an element in the second list. The predicate works without the cut as well.
permut([],[]).
permut([H|T], Compare):-
append(C1, [H|C2], Compare),
!,
append(C1, C2, Cnext),
permut(T, Cnext).
gives the output
?- permut([1,2,3,4,5],[5,4,3,2,1]).
true.
?- permut([1,2,3,4,5],[5,4,3,2,1,1]).
false.
?- permut([1,2,3,4,5,6],[5,4,3,2,1]).
false.

Why does these rules work? (finding last element in list in prolog)

I am trying to understand the following set of rules, which supposed to find the last element in a list (for instance my_list(X,[1,2,3]) gives X=3).
my_last(X,[X]).
my_last(X, [_|L]) :- my_last(X, L).
I understand the first fact - X is the last element of a list if X is the only element in it, but how does the second rule work? this looks a bit strange to me as a prolog noob, I'd love to know if there's an intutive way to interprate it.
T
Read the Prolog predicate as logical rules. If there is more than one predicate clause for the predicate, you can think of it as "OR":
my_last(X,[X]).
X is the last element of the list, [X].
my_last(X, [_|L]) :- my_last(X, L).
X is the last element of the list [_|L] if X is the last element of the list L.
The second clause is a recursive definition. So it does, ultimately, need to terminate with the recursive call not matching the head of the recursive clause that is calling it. In this case, L eventually becomes [] and will no longer match [_|L]. This is important because, otherwise, you will get an infinite recursion.

update element in the list of list in prolog

I have a list of list and a list. I want to update the list of list by using the element from the second list.
For example:
I have a list of list
[[banan,NA],[apple,NA]] and a list [sweet,notsweet],
want to update the list of the list, so I will have a list of list
[[banana,sweet],[apple,notsweet]]
I have tried the code below, but I think I cannot figured out the base case correctly.
update([[]],[],[]).
update([[T|_]|HH],[FB|H2],[NState|_]) :-
NState=[T|FB],
update(HH,H2,NState).
Any help, will be much appreciate
thanks
You're almost there. First let's observe that the first list is empty if there are no more [fruit,*] pairs left, hence the first argument of your base case should be []. At that point the other lists have to be empty too, since they are of the same length.
In general, the first list will have a two-element list as its head, the first of which is being your object of interest and the second of which you don't care for, that is, something like [X,_]. The tail of that list will contain further X's, so let's maybe call it Xs. Then the first argument looks like [[X,_]|Xs]. The second argument is a flat list, so you can write [Y|Ys] (read as: the list starts with a Y that is followed by further Y's). The last argument is a two-element list [X,Y] that is followed by other such pairs (XY's), hence: [[X,Y]|XYs]. The relation has to hold for the tails as well, that can be described by a recursive goal. You can express the above in Prolog like so:
update([],[],[]).
update([[X,_]|Xs],[Y|Ys],[[X,Y]|XYs]) :-
update(Xs,Ys,XYs).
With these alterations to your predicate the example query from your comment yields the desired answer:
?- update([[banana,*],[apple,*]],[sweet,notsweet],C).
C = [[banana, sweet], [apple, notsweet]].

Get all Prefixes of a List, including [] in Prolog

I am new to Prolog and wanted to start learning the functionality of [H|T] by trying to write the prefix function on my own. The prefix function returns all possible prefixes to a list, such as for L = [a,b,c] would be [], [a], [a,b] and [a,b,c]. I am confused about how my own Prolog function would be able to return so many different solutions. I have it splitting the head and tail of the list, and appending the head to my new list that is going to be the different prefixes returned. This is what I have so far, but I think I am oversimplifying, and don't know how else to recursively call it to get all the different possibilities.
myPrefix([],[]).
myPrefix([H|T],List) :- myPrefix(T, [H|List]).
I looked at a lot of the other answers, but those just deal with getting the first element off of a list, not listing all possible prefixes. Any advice of how to go from here or more explanation as to how this head and tail of list manipulation functionality works is appreciated.
Assuming the first argument if instantiated is indeed is a proper list, then this should do it:
myPrefix(_, []).
myPrefix([H|T], [H|NT]):-
myPrefix(T, NT).
First clause ignores the first argument and unifies the second with the empty list.
Second clause takes the head of first argument list and puts it as the head of the second argument, and calls itself recursively.
So in effect, the second clause takes one by one as many items as desired and the first clause drops the tail.

Problem with accumulators in prolog

While learning Prolog, I'm trying to solve the following problem, using accumulators:
Write a predicate addone2/ whose first argument is a list of integers, and whose second argument is the list of integers obtained by adding 1 to each integer in the first list. For example, the query
addone([1,2,7,2],X).
should give
X = [2,3,8,3].
I created the following code:
addone([], _).
addone([E|Tail], [R|Rs]) :-
NewE is E+1,
append([R|Rs], [NewE], NewRs),
addone(Tail, NewRs).
But it's not working. Can someone tell me why? So, how do I use accumulators in Prolog?
Thanks!
anthares is correct in that you have to refine your base case. However, you are also making things very inefficiently with your append calls. In Prolog, it takes some time to get used to the power of unification, but for example, in this case it helps you to immediately set up your result list. Try the following:
addone([E|Tail], [E1|Rs]) :-
E1 is E+1,
addone(Tail, Rs).
That's really all there is to it. By immediately placing E1 in your second argument's pattern, you have already created the first element of your result list. The remaining elements Rs will be created during the recursion. A very typical Prolog pattern.
The bottom of your recursion should be addone([],[]). in order NewRs to be connected with the []

Resources