Prolog flatten list - prolog

flatten([A|B],R):- (islist(A)->(flatten(A,R1),R=R1);(write(A),append([A],R1,R))), flatten(B,R1).
flatten(X,X).
islist([_|_]).
This is the code i written but i have strange problem..
I get
257 ?- flatten([1,[],2,[3],[3,[3,5]]],R).
1[]23335335
R = [1, [], 2, [3], [3, [3, 5]]] .
Although the numbers from write are not list they are appended as list:S...

There are some errors in your definition of flatten/2:
Your first clause will fail because if A is a list it will first instantiate R1 with R and then you try to unify it again with flatten(B, R1).
flatten(X,X). -> This clause leaves the list 'as is' without any flattening.
Check this other implementation:
flatten(List, Flattened):-
flatten(List, [], Flattened).
flatten([], Flattened, Flattened).
flatten([Item|Tail], L, Flattened):-
flatten(Item, L1, Flattened),
flatten(Tail, L, L1).
flatten(Item, Flattened, [Item|Flattened]):-
\+ is_list(Item).
Here we use two predicates: flatten/2 and flatten/3. The 'work' will be done in flatten/3 where the second argument will hold the intermediate flattened list.
The first clause is the base case: when we reach the empty list we are done so we instantiate the third argument with the intermediate flattened list.
The second clause deals with recursion. It flattens the first item in the list (whether it is an item or a sublist), and proceeds with the rest of the input list.
The last clause is the 'base case' for the non-lists items. It prepends the item at the beginning of the intermediate flattened list, but it only does this for items which are not lists as that case was taken care in the second clause.

Related

Merging 2 lists into a third but in pairs

I want, given 2 lists, to merge them into a third one but each element of the third list is a list of the first and second list's elements.
E.g. given the list1 [1,2,3] and list2 [1,2,3] I want the final list to be [[1,1],[2,2],[3,3]]
What I've done so far is
merge([],[],Z).
merge([H1|T1],[T2|T2],Z):-
append([H1],[H2],W),merge(T1,T2,[W,Z]).
but I get a False result. Why isn't it working?
There are some flaws in your code:
when the first two lists are empty, the result must be an empty list too;
Instead of [T2|T2] you should write [H2|T2] to represent the second list;
there is no need to use append([H1],[H2],W) to create a list with two elements, just write [H1,H2];
since the recursive call must merge the tails of the first and second lists, there is no way the result of this call to be a list starting with the element [H1,H2].
Thus, a correct definition for that predicate is as follows:
my_merge([], [], []).
my_merge([H1|T1], [H2|T2], [[H1,H2]|T3]):-
my_merge(T1, T2, T3).
Examples:
?- my_merge([a,b,c], [1,2,3], L3).
L3 = [[a, 1], [b, 2], [c, 3]].
?- my_merge(L1, L2, [[1,a],[2,b],[3,c]]).
L1 = [1, 2, 3],
L2 = [a, b, c].
Remark Consider the possibility of representing the pair [H1,H2] as H1-H2, as the latter representation is more commonly used in Prolog.

How to check certain elements in a list with anonymous variables

Imagine having a list like L = [1, 4, _, 5, _]
If I would want to check if 4 is a member of this list, I could do this with: member(4, L). This will return True, because there is a 4 in this list. However it returns true with every element I check, using member/2. This, of course, happens, because an anonymous variable can be matched with anything. So it will always return True. I was wondering if there would be a way I can remove all anonymous variables from list L. So a NewList would be [1, 4, 5].
Instead of removing variables from the list and then use member/2 you could also opt to implement your own predicate that describes a member/2-like relation for non-variable elements:
nonvarmember(X,[Y|_]) :-
nonvar(Y), % only try to unify with X if Y is not a variable
X=Y.
nonvarmember(X,[_Y|Ys]) :-
nonvarmember(X,Ys).
Now let's see how this predicate works:
?- nonvarmember(4,[1,4,_,5,_]).
true ;
false.
?- nonvarmember(4,[1,_,_,5,_]).
false.
?- nonvarmember(4,[1,4,_,5,_,Z]).
true ;
false.
However, the first argument still can be a variable:
?- nonvarmember(X,[1,4,_,5,_,Z]).
X = 1 ;
X = 4 ;
X = 5 ;
false.
?- nonvarmember(X,[_,_,_]).
false.
But be aware that it does not matter if you remove the variable elements from the list first and subsequently use member/2 or if you use nonvarmember/2, you run into the following problem: List-elements that are instantiated after you check for membership are not accounted for and hence might lead to unsound answers. The following example illustrates the problem:
?- A=4, nonvarmember(4,[A,B,C]).
A = 4 ;
false.
?- nonvarmember(4,[A,B,C]), A=4.
false.
In order to check if certain items are in a list that contains anonymous variables, you'd first need to (temporarily) remove all anonymous variables from that list. To do so you could use the built-in predicate subtract/3 and var/1.
subtract/3: the first element being the list you want to check, the second element being a list containing elements you want to remove from the list and the third element being the resulting list.
var/1: contains only one element (X) and returns True if X is an unbound variable.
In this case we want to subtract every element (X) that is returning True when var(X). In code, this is written as var(_).
Now we simply fill in the subtract/3 predicate like this: subtract(L, [var(_)], NewList).
NewList now only stores bound variables and member/2 will now work as intented.
In case of Swi-Prolog (at least) you can use include/3 and exclude/3 predicates to filter lists. You can use these predicates together with var/1 and nonvar/1, to remove variables from list.
In your particular case, checking whether 4 belongs to the list [1, 4, _, 5, _] could be done as follows:
L1 = [1, 4, _, 5, _],
exclude(var, L1, L2),
member(4, L2).

How prolog deals with this step-by-step?

I'm trying to understand prolog but I am stuck with one example, can you explain to me how is prolog going through this call:
eli(2,[2,2,1],L).
using those facts:
eli(X,[],[]).
eli(X,[Y],[Y]).
eli(X,[X,X|L],L1) :- eli(X,L,L1).
eli(X,[Y|L],[Y|L1]) :- eli(X,L,L1).
The results are:
L = [1]
L = [1]
L = [2, 2, 1]
L = [2, 2, 1]
and I'm not really sure why.
Thanks in advance!
It looks like your predicate is mean to delete two consecutive appearance of any element.
First clause, if the target list is empty, return the empty list. In this case the X variable in the fact is not necessary. Replace X by te anonymous variable.
eli(_,[],[]).
Second clause is similar to the first, but it matches the target list if it contains only one element. Variable X is also not necessary.
eli(_,[Y],[Y]).
Third clause, if the target list contains two or more elements, and in the Head of the list both elements are equal to X, don't copy this two elements to the Result list, and make a recursive call to the eli/3 predicate in the body of the rule, to continue the search.
eli(X,[X,X|L],L1) :- eli(X,L,L1), !.
In this case we add the cut predicate, to avoid backtracking after this rule succeeded. Otherwise you may get undesired results, like L = [2, 2, 1] in your test.
And the last clause, copy the element in the Head of the Target list to the Result list, and continue the recursive call, this will stop when the Target list is empty or contains only one element (your first two clauses).
eli(X,[Y|L],[Y|L1]) :- eli(X,L,L1).
Now this is your predicate eli/3:
eli(_,[],[]).
eli(_,[Y],[Y]).
eli(X,[X,X|L],L1) :- eli(X,L,L1), !.
eli(X,[Y|L],[Y|L1]) :- eli(X,L,L1).
Test:
?- eli(2,[2,2,1],L).
L = [1]
?- eli(2,[1,2,2,3],L).
L = [1, 3]

Find a element in a sublist from a list at prolog

I have this
initialstate(0,[],[[1,0],[2,3],[1,2],[2,3]]).
I would like to find which sublist inside the list is the same with the number 1.
And after delete the sublist who had the number one.
It would be something like that :
?- initialstate(_,_,[X,_]), initialstate(_,_,list),
delete(list,X,Newlist),assertz(initialstate(A,B,Newlist)).
I know this is wrong but i am trying to explain you what i want to do.
I want my final list to be :
initialstate(0,[],[[2,3],[2,3]]).
Edit: A new answer to incorporate CapelliC's endorsement of delete/3 and OPs further queries in the comments.
Predicate:
initial_state_without_elements(initialstate(A,B,List), Element,
initialstate(A,B,FilteredList) ):-
delete(List, Element, FilteredList).
Query:
?- initial_state_without_elements(initialstate(0,[],[[1,0],[2,3],[1,2],[2,3]]), [2,_], NewState).
NewState = initialstate(0, [], [[1, 0], [1, 2]]).
We want to take some list of lists, ListOfLists, and remove all the sublists, Ls, that contain a given Element. In general, to check if an element X is in some list List, we we can use member(X, List).
So we want a list of lists, SubListsWithout, which contains all Ls of ListOfLists for which member(Element, SubList) is false.
Here is a predicate sublists_without_elements/3, which takes a list of lists, an element, and a variable as arguments, and unifies the variable with a list of the sublists of the first which do not contain the element. This predicate uses the standard recursive technique for describing lists:
sublists_without_element([], _, []).
sublists_without_element([L|Ls], Element, SubListsWithout) :-
member(Element, L), !,
sublists_without_element(Ls, Element, SubListsWithout).
sublists_without_element([L|Ls], Element, [L|SubListsWithout]) :-
sublists_without_element(Ls, Element, SubListsWithout).
The first clause is our base case: the empty list has no sublists, regardless of the element.
The second clause is true if (1) Element is a member of L, and (2) SubListsWithout is a list of the sublists of Ls which do not contain Element. (note: *L has not been added to SubListsWithout in this clause, which means it has been excluded from the lits we are accumulating. The ! is used to prune the search path here, because once we know that an Element is a member of L, we don't want to have anything to do with L again.)
The third clause is true if L is added to SubListsWithout, and SubListsWithout contains the rest of the sublists of Ls which do not have Element as a member.
The above is one way to write your own predicate to filter a list. It is important that you be able to write and read predicates of this form, because you will see tons of them. However, you'll also want to get to know the standard libraries of your Prolog implementation. In SWI-Prolg, you can simply use exclude\3 to accomplish the above task. Thus, you could achieve your desired goal in with the following:
filter_initial_state(initial_state(A,B,List),
Element,
initial_state(A,B,FilteredList)) :-
exclude(member(Element), List, FilteredList).
You can use it thus,
?- filter_initial_state(initial_state(0,[],[[1,0],[2,3],[1,2],[2,3]]), 1, Filtered).
and prolog will reply,
Filtered = initial_state(0, [], [[2, 3], [2, 3]]).
I think you've chosen the right builtin (delete/3), but there is some detail wrong. Here is a working 'query':
?- retract(initialstate(A,B,C)), C=[[X,_]|_], delete(C,[X,_],Newlist), assertz(initialstate(A,B,Newlist)).
A = 0,
B = [],
C = [[1, 0], [2, 3], [1, 2], [2, 3]],
X = 1,
Newlist = [[2, 3], [2, 3]].
First of all: if you do a assertz without first doing a retract you'll end with having an almost duplicate of your data, and probably is not what you want. assertz stores the updated initialstate after the old one (there is asserta, but I doubt will correct the bug).
Second, note how to use pattern matching to extract the essential information:
C=[[X,_]|_]
the use of _ (i.e. an anonymous var) is essential, because allows to specify which part of the complex structure we must ignore when using it. And we must use it also to indicate to delete/3 what to match.
delete(C,[X,_],Newlist)

How does this permutation algorithm work

ar([],[]).
ar([p(_,_)|L],L1):-ar(L,L2),L1=L2.
ar([p(X,Y)|L],L1):-ar(L,L2),L1=[p(X,Y)|L2].
(p stands for point, having the coordinates X and Y)
Please help me to understand how the result is being constructed, especially the part where L1 gets a new value, thanks!
The definition of your predicate ar/2 behaves like the powerset function, being a syntactic variant of the following (where X is restricted to terms of p/2):
% clause 1: base case
ps([], []).
% clause 2: omit the element X
ps([_X|Y], Z) :-
ps(Y, Z).
% clause 3: keep the element X
ps([X|Y], [X|Z]) :-
ps(Y, Z).
The predicates ps/2 (and your ar/2) basically backtrack to bind all sub-lists of the list in the first argument to that of the second argument. It achieves this with the choice represented by the second and third clauses: either omit or keep a list element when constructing the new list.
Consider what Prolog does when executing the goal ps([a,b],L):
ps([_|[b]], Z) :- ps([b], Z). (via clause 2, drop a).
ps([b|[]], Z) :- ps([], Z). (via clause 2, drop b; note that [b] = [b|[]]).
ps([], Z) binds Z = [] (via clause 1, gives solution 1).
ps([b|[]], [b|Z]) :- ps([], Z). (via clause 3, keep b).
ps([], Z) binds Z = [] (via clause 1, gives solution 2).
ps([_|[b]], [a|Z]) :- ps([b], Z). (via clause 3, keep a).
ps([b|[]], Z) :- ps([], Z). (via clause 2, drop b).
ps([], Z) binds Z = [] (via clause 1, gives solution 3).
ps([b|[]], [b|Z]) :- ps([], Z). (via clause 3, keep b).
ps([], Z) binds Z = [] (via clause 1, gives solution 4).
Each of the deepest levels which hit the 'base-case' of clause 1 return up the call stack. Each of these cases result in the following:
Drop both a and b: []
Drop a, keep b: [b]
Keep a, drop b: [a]
Keep both a and b: [a,b]
Thus, we can backtrack to generate [], [b], [a] and [a,b], i.e., the four sub-lists of [a,b].
First of all, note that this procedure does not compute a permutation, but a sort of sublist: a list with "some" points removed, where by "some" is said in general form (one of the solutions is the empty list and also other solution is the original list), assuming the input list is well formed.
If the input list is not well formed (it has one item which is not a "point") then the procedure will fail.
Now let's explain the three clauses of ar/2, which is a recursive procedure:
First clause,
ar([], []).
states that if the first argument is the empty list, then the second argument is also the input list; i.e. for an empty list the only "sublist" conforming with the rules of the procedure is also an empty list.
This is also the base case of the recursive procedure.
The second clause,
ar([p(_,_)|L], L1):-ar(L, L2), L1=L2.
can be rewritten without using the L2 variable because it will eventually unify with L1:
ar([p(_,_)|L], L1):-ar(L, L1).
This clause is skipping the head of the input list and continuing with recursion. Upon return of recursion it will unify the resulting list (second argument of ar/2 call) with the second argument of the head of the clause.
The third clause,
ar([p(X,Y)|L], L1):-ar(L, L2), L1=[p(X,Y)|L2].
can be, again, rewritten without using the L2 variable by means of building the resulting list in the head of the clause:
ar([p(X,Y)|L], [p(X,Y)|L1]):-ar(L,L1).
This clause will take the head of the input list, continue recursion with the tail and then unify second argument of the head of the clause with the item taken and the resulting list of the recursion. That is, it will keep the item (head) of the input list along with the result of recursion.
Also note that this procedure is not reversible, if called with the first argument uninstantiated and the second argument instantiated it will loop forever.

Resources