Divide lists and increment every element of list by its depth in Prolog - list

I'm trying to increment every element of list by its depth. For example:
foo([0, 0, [0]], [1, 1, [2]]) -> true
Also, I'd like to do that without any built-in Prolog list predicates. Any ideas on how to solve this?

For divide_half, you need to verify 2 things (which can be done independently): that the lists define some kind of split, and that parts of the split have close enough lengths.
For the second, start by trying to FIND each element, then modify that to track the depth, and finally modify THAT to build up a copy of the list w/ the elements modified (though I don't understand what it means to one-increment something by a number).

This definition divides a list without any built-in predicates:
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).

Related

List of pair list to on list PROLOG

I have one list of lists like this: [[a,b],[b,c],[c,d]] and I want to has [a,b,c].
My code is:
unMakeTuple([],_).
unMakeTuple([[A,_]|T],Ret):-
insertOnList(A,Ret,Ret1),
nl,write(Ret),
nl,write(Ret1),
unMakeTuple(T,Ret1).
insertOnList(E,[],[E]).
insertOnList(E,[H|T],[H|T1]):-
insertOnList(E,T,T1).
And return me a empty list.
Someone can help me?
Thank you.
You here want basically make a mapping where we obtain the head of every sublist.
So we can define a predicate head/2:
head([H|_],H).
and then use maplist/3:
unMakeTuple(A,B) :-
maplist(head,A,B).
then we obtain:
?- unMakeTuple([[a,b],[b,c],[c,d]],X).
X = [a, b, c].
Although writing a custom predicate can of course be beneficial as well. The advantage here is that (a) it is very declarative and easy to understand that we map a list A to a mapB by for each element unify the elements of the two lists by the head predicate; (b) we can be quite certain that maplist/3 works correctly and (c) we can expect that maplist/3 will be optimized such that processing is done fast.
#Willem Van Onsem's solution using maplist/3 above is the better way to do this, but another way to do this is to just write a predicate that adds all the heads of the inner lists to a resulting list. Some sort of recursive solution like this should work:
head([H|_], H).
get_heads([], []).
get_heads([X|Xs], List) :-
head(X, H),
List = [H|Rest],
get_heads(Xs, Rest).
Which works as follows:
?- get_heads([[a,b],[b,c],[c,d]], X).
X = [a, b, c].

How to check if all elements of one list are members of another list in Prolog

I'm learning Prolog right now and the recursive thinking is difficult to me.
I have two lists e.g. L1=[1,2,3] and L2=[3,1,2] and I should check if all elements of L1 are contained in L2
So allMembers(L1,L2). should return true and allMembers(L1,[2,3,4]). should return false, because there is no 4 in L1
I thought it would be possible to get the head of the one list and return true if it finds that element in the other list (by splitting it down until the list only contains one item), but I have no idea how to do that in Prolog.
It would be nice if you could help me getting faster on the uptake (?)
I found similar problems here, but couldn't find an answer to my specific problem :/
Edit:
I now have:
isMemberOf(X,[X|_]).
isMemberOf(X,[_|T]):- member(X,T).
which I need to use for any element in L1 to L2
Quick solution using de facto standard predicates:
all_from_first_in_second(List1, List2) :-
forall(member(Element,List1), member(Element,List2)).
Probably the simplest way to define it may be:
% contained_in(L1, L2) succeeds if all elements of L1 are contained in L2
contained_in(L1, L2) :- maplist(contains(L2), L1).
contains(L, X) :- member(X, L).
maplist/2 will apply contains(L2) to each element of L1, and will succeed if every call succeeds. contains/2 is like member/2 but puts the arguments in the order that make it work with maplist.
To solve your sub-problem: member(A,B) is true if A is a member of the list B.
Simply use list_permuted/2 like this:
?- list_permuted([1,2,3],[3,1,2]).
true.
Note that list_permuted/2 demands that both lists have the same items in the same quantity!
This solves the question with only self defined predicates:
% allMembers(L1,L2) checks if all elements of L1 are available in L2
% solve the sub problem
isMemberOf(X,[X|_]).
isMemberOf(X,[_|T]):- isMemberOf(X,T).
% iterate through 'L1' and ask if the member exists in 'L2'
allMembers([],_).
allMembers([H|T],L):- allMembers(T,L), isMemberOf(H,L).

Prolog Applying Constraints to Original List Items in Matrix

I am currently working on a project that involves a matrix. I am stuck in my attempt to apply constraints to specific elements in my matrix. This is my matrix and domain definitions of the main class/predicate. So, the first 3 predicates are just creating the matrix and defining the domains while the last 2 predicates labels the different variables in regards to the domain and prints it out.
test(Solution, N) :-
length(Solution,8),
maplist(length_(8), Solution), %The variables
maplist(define_domain, Solution), %The domains
constraint(Solution),
maplist(labeling([]), Solution), %Labeling the variables
maplist(print_row, Solution).
length_(Length, List) :- length(List, Length).
define_domain(X):- X ins 0..9.
ww(X):-
write(X).
print_row(Row):-
%nested maplist call so it works on each element in the
maplist(ww, Row),
nl.
So, the constraints predicate which applies the constraint on my variables is where I am having problems. I have some facts that I need to capture so I tried using findall to loop through all the facts and use them to determine the which elements inside the list of the matrix that I need to apply the constraints to. The facts contains the row, column and length.
The nested findall predicate call uses row to determine which list inside the matrix, column to determine the index of the element of the that list to take and extracting a sublist based on the index of the element and its length. The outer findall predicate finds all the position predicates and collects all the sublists. Therefore, I have a collection of sublists contains the elements of the matrix where constraint needs to be applied. The constraint is applied in the constraint_apply predicate.
However, I discovered that the findall predicate creates copies of the original list instead of using the actual elements/variables in the original list after struggling for many hours. So, all the constraints that are being applied only affects the copies and not the originals.
Right now, I am thinking that maybe I am using the findall predicate wrongly to apply the constraints and trying out different ways to use it.
I would be grateful if someone could explain to me a better way to propagate my constraints in this scenario.Any helps/tips will be appreciated. How would you apply the constraints to the original list and elements in the matrix above?
constraint_apply([]).
constraint_apply([X|Xs]):-
sum(X, #<, 10),
all_different(X),
constraint_apply(Xs).
%Extract a slice from the lsit
constraint(Xs):-
findall(X, (position(R, C, L), End is C+L-1,
findall(Y, (nth1(R, Xs, N),between(C, End, M), nth1(M, N,Y)), X)), Row),
constraint_apply(Row).
I had a similar problem, and I solved using bagof/3 instead of findall/3.
I cannot test your code, so here is just a hint to the needed syntax
constraint(Xs):-
bagof(X, R^C^L^End^(
position(R, C, L),
End is C+L-1,
bagof(Y, N^M^(nth1(R, Xs, N), between(C, End, M), nth1(M, N, Y)), X)
), Row),
constraint_apply(Row).

Correctly building up a list in Prolog

I'm attempting to write a predicate to remove elements from an ordered list in Prolog. This is part of a homework assignment and I'm very confused about how Prolog's semantics work in general.
When I try the following function with the goal rdup([1,2], L). I get false. I've traced the goal and it looks like I'm not supposed to be building up the result list the way I am building it up with recursive calls to rdup. I'm not certain how I should be building up the result list. Here's the function:
rdup([],M).
rdup([X],[X]).
rdup([H1,H2|T], M) :- H1 \= H2, rdup(T, [M,H1,H2]).
rdup([H1,_|T], M) :- rdup(T, [M,H1]).
Can anyone tell me where my reasoning is wrong or how one is supposed to build up a list recursively in Prolog?
Firstly, it's not functions.
It's predicates, they only say, what's true, what's not, and under what conditions.
Here are your program:
rdup([],[]).
rdup([X],[X]).
rdup([H,H|T], M) :- rdup([H|T], M).
rdup([H1,H2|T], [H1|M]) :- H1 \= H2, rdup([H2|T], M).
Now a little bit of explanation.
Firstly, what says "rdup(X,Y)"? It's not saying "Take ordered list in X, and put list X without duplicates in Y", but it says "This fact will be true, if Y is an list X without duplicates, in assumption that X is an ordered list". Notice, that we don't talk about "returning values" or sth like that.
First line says, that the empty list is a list without duplicates of empty list. Quite obvious, right?
Next line is basically the same, but with one element.
Third line says, that if we have list, which consists from two same elements H and tail T, then the ordered list of this list ([H,H|T]) is the same, as it would be with only one element H. That's why we have "M" in both predicates unmodified.
I hope you will analyse the last predicate on your own, Prolog is not as hard as it looks to be. Good luck!

Override a list element?

Is there a way to add an element to a list, without caring if it already exists and the list still not containing duplicates?
If you are looking for efficiency there are better data structures than lists, ready to use in SWI-Prolog. In particular, your use case fits on add_nb_set(+Key, !Set, ?New).
Argument New controls the behaviour WRT duplicates: you should use true for don't care.
Argument Set must be 'allocated' with empty_nb_set(Set)
edit: I apologize, argument Set must be a free var for don't care behaviour, like for instance add_nb_set(Key, Set, _), as evident for the documentation page....
You could first check whether the item is contained in the list and add it only if it's not.
For example:
add_no_duplicates(List, Item, NList):-
member(Item, List) -> NList=List ; NList=[Item|List].
Test:
?- add_no_duplicates([a,b,c],d,L).
L = [d, a, b, c].
?- add_no_duplicates([a,b,c,d],d,L).
L = [a, b, c, d].
Note that add_no_duplicates/3 as written needs the input list (List) to be instantiated.
Basically you want to implement a set; check the list manual page for set operations.
It appears that there is no add but there is union/3 so you can add elements by intersecting with a set of the new element (intersection([NewEl], OldSet, NewSet). Note that you dont have to convert a list to a set (a list is a set as long as it doesnt have duplicates; list_to_set/2 just eliminates them).
Now if you have a list with duplicates and you want sometimes to add an element the way you stated you will have to implement something yourself.