elem function of no limit list - list

list comprehension haskell
paar = [(a,b) | a<-[a | a<-[1..], mod a 3 == 0], b<-[b*b | b<-[1..]]]
a = divisor 3
b = square
The Elements must be constructed by equitable order.
the test >elem (9, 9801) must be True
my Error
Main> elem (9, 9801) test
ERROR - Garbage collection fails to reclaim sufficient space
How can I implement this with Cantor's diagonal argument?
thx

Not quite sure what your goal is here, but here's the reason why your code blows up.
Prelude> let paar = [(a,b) | a<-[a | a<-[1..], mod a 3 == 0], b<-[b*b | b<-[1..]]]
Prelude> take 10 paar
[(3,1),(3,4),(3,9),(3,16),(3,25),(3,36),(3,49),(3,64),(3,81),(3,100)]
Notice you're generating all the (3, ?) pairs before any other. The elem function works by searching this list linearly from the beginning. As there are an infinite number of (3, ?) pairs, you will never reach the (9, ?) ones.
In addition, your code is probably holding on to paar somewhere, preventing it from being garbage collected. This results in elem (9, 9801) paar taking not only infinite time but also infinite space, leading to the crash you described.
Ultimately, you probably need to take another approach to solving your problem. For example, something like this:
elemPaar :: (Integer, Integer) -> Bool
elemPaar (a, b) = mod a 3 == 0 && isSquare b
where isSquare = ...
Or alternatively figure out some other search strategy than straight up linear search through an infinite list.

Here's an alternate ordering of the same list (by hammar's suggestion):
-- the integer points along the diagonals of slope -1 on the cartesian plane,
-- organized by x-intercept
-- diagonals = [ (0,0), (1,0), (0,1), (2,0), (1,1), (0,2), ...
diagonals = [ (n-i, i) | n <- [0..], i <- [0..n] ]
-- the multiples of three paired with the squares
paar = [ (3*x, y^2) | (x,y) <- diagonals ]
and in action:
ghci> take 10 diagonals
[(0,0),(1,0),(0,1),(2,0),(1,1),(0,2),(3,0),(2,1),(1,2),(0,3)]
ghci> take 10 paar
[(0,0),(3,0),(0,1),(6,0),(3,1),(0,4),(9,0),(6,1),(3,4),(0,9)]
ghci> elem (9, 9801) paar
True
By using a diagonal path to iterate through all the possible values, we guarantee that we reach each finite point in finite time (though some points are still outside the bounds of memory).
As hammar points out in his comment, though, this isn't sufficient, as it will still take
an infinite amount of time to get a False answer.
However, we have an order on the elements of paar, namely (3*a,b^2) comes before (3*c,d^2) when
a + b < c + d. So to determine whether a given pair (x,y) is in paar, we only have to check
pairs (p,q) while p/3 + sqrt q <= x/3 + sqrt y.
To avoid using Floating numbers, we can use a slightly looser condition, that p <= x || q <= y.
Certainly p > x && q > y implies p/3 + sqrt q > x/3 + sqrt y, so this will still include any possible solutions, and it's guaranteed to terminate.
So we can build this check in
-- check only a finite number of elements so we can get a False result as well
isElem (p, q) = elem (p,q) $ takeWhile (\(a,b) -> a <= p || b <= q) paar
And use it:
ghci> isElem (9,9801)
True
ghci> isElem (9,9802)
False
ghci> isElem (10,9801)
False

Related

How to simplify algebra equations represented as list of list

With Prolog I want to simplify algebra expression represented as as list of list:
algebra equation
f = 3x+2
list of list
[[3,1],[2,0]]
3 and 2 are coefficients
1 and 0 are exponents
That should be obvious.
I am looking for some tips or suggestions on how to code the simplifications for this example:
f = 3x+2x+1+2
[[3,1],[2,1],[1,0],[2,0]]
simplified:
f = 5x+3
[[5,1],[3,0]]
I have tried some built in functions but did not get the proper idea about how to use them.
One liner, similar to what's proposed by joel76:
simplify(I,O) :-
bagof([S,E],L^(bagof(C,member([C,E],I),L),sum_list(L,S)),O).
The inner bagof collects C (coefficients) given E (exponents), the resulting list L is summed into S, and paired with E becomes [S,E], an element (monomial) of O.
If you omit the universal quantification specifier (that is L^) you get single monomials on backtracking.
You can solve your problem in this way:
simplify(_,_,S,S,[]):- !.
simplify(L,I,Sum,NTot,[[I,S]|T]):-
Sum =< NTot,
findall(X,member([X,I],L),LO),
length(LO,N),
S1 is Sum + N,
sum_list(LO,S),
I1 is I+1,
simplify(L,I1,S1,NTot,T).
write_function([]).
write_function([[D,V]|T]):-
write(' + '),write(V),write('x^'),write(D),
write_function(T).
test:-
L = [[3,1],[2,1],[1,0],[2,0]],
length(L,N),
simplify(L,0,0,N,LO),
LO = [[D,V]|T],
write('f='),write(V),write('x^'),write(D),
write_function(T).
The main predicate is simplify/5 which uses findall/3 to find all the coefficients with the same degree and then sums them using sum_list/2. Then you can write the result in a fancy way using write_function/1.
In SWI-Prolog You can use aggregate :
pred(>, [_,X], [_,Y]) :- X > Y.
pred(<, [_,X], [_,Y]) :- X < Y.
pred(=, [_,X], [_,X]).
simplify(In, Out) :-
aggregate(set([S,X]), aggregate(sum(P), member([P,X], In), S), Temp),
predsort(pred, Temp, Out).
For example :
?- simplify([[3,1],[2,1],[1,0],[2,0]], Out).
Out = [[5, 1], [3, 0]] ;
false.

Clip up numbers bigger than maximum

I have this function:
fun min x y = if x >= y then y else x
and I need to use this function (as a partial application) and make function clipupdown with arguments number and list, where number represents the minimal number that should exist in that list and all numbers lower than min should be set to that minimal number. For example when I call:
clipdown 10 [1,11,21,4,6,7,12]
I should get
[10,11,21,10,10,10,12]
Any hints?
Any hints?
What do you get when you call min (edit: or, actually max) with only one element?
min 10
how do you map a function over a list?
fun clipdown lowest numbers = map (max lowest) numbers
You have to use max, instead of min. Whenever the program finds a number below the minimum, it should choose the minimum (which is greater than the encountered number). So you need to choose the max value.
Since Int.min and Int.max already exist, but take tuples, you could write a function
fun curry f x y = f (x, y)
and use this like map o curry Int.max to get clipdown.
Similarly you could get clipup with map o curry Int.min.
You might also get clipupdown by composing both like
fun clipupdown lower higher = clipdown lower o clipup higher
But you could also use that (map f) ∘ (map g) = map (f ∘ g):
fun clipupdown lower higher = map (curry Int.max lower o curry Int.min higher)
This is called map fusion.

How to move first N elements to the end of the list

I am wondering how can I move first N elements from a list and put them at the end.
For example:
[1,2,3,4] and I want to move first 2 elements , so the result will be [3,4,1,2].
rule(List1,N,List2) :- length(List1,Y), ...
I don't know how to start, any advice ?
Since we are speaking of predicates - i.e. true relations among arguments - and Prolog library builtins are written with efficiency and generality in mind, you should know that - for instance - length/2 can generate a list, as well as 'measuring' its length, and append/3 can also split a list in two. Then, your task could be
'move first N elements to the end of the list'(L,N,R) :-
length(-,-),
append(-,-,-),
append(-,-,-).
Replace each dash with an appropriate variable, and you'll get
?- 'move first N elements to the end of the list'([1,2,3,4],2,R).
R = [3, 4, 1, 2].
You could opt to adopt a more general perspective on the task. If you think about it, taking the first N elements of a list and appending them at the end can be seen as a rotation to the left by N steps (just imagine the list elements arranged in a circle). The predicate name rotate/3 in #Willem Van Onsem's answer also indicates this perspective. You can actually define such a predicate as a true relation, that is making it work in all directions. Additionally it would be desirable to abstain from imposing unnecessary restrictions on the arguments while retaining nice termination properties. To reflect the relational nature of the predicate, let's choose a descriptive name. As the third argument is the left rotation by N steps of the list that is the first argument, let's maybe call it list_n_lrot/3 and define it like so:
:- use_module(library(lists)).
:- use_module(library(clpfd)).
list_n_lrot([],0,[]). % <- special case
list_n_lrot(L,N,LR) :-
list_list_samelength(L,LR,Len), % <- structural constraint
NMod #= N mod Len,
list_n_heads_tail(L,NMod,H,T),
append(T,H,LR).
list_list_samelength([],[],0).
list_list_samelength([_X|Xs],[_Y|Ys],N1) :-
N1 #> 0,
N0 #= N1-1,
list_list_samelength(Xs,Ys,N0).
list_n_heads_tail(L,N,H,T) :-
if_(N=0,(L=T,H=[]),
(N0#=N-1,L=[X|Xs],H=[X|Ys],list_n_heads_tail(Xs,N0,Ys,T))).
Now let's step through the definition and observe some of its effects by example. The first rule of list_n_lrot/3 is only included to deal with the special case of empty lists:
?- list_n_lrot([],N,R).
N = 0,
R = [] ;
false.
?- list_n_lrot(L,N,[]).
L = [],
N = 0 ;
false.
?- list_n_lrot(L,N,R).
L = R, R = [],
N = 0 ;
...
If you don't want to include these cases in your solution just omit that rule. Throughout the predicates CLP(FD) is used for arithmetic constraints, so the second argument of list_n_lrot/3 can be variable without leading to instantiation errors. The goal list_list_samelength/2 is a structural constraint to ensure the two lists are of same length. This helps avoiding an infinite loop after producing all answers in the case that only the third argument is ground (to see this, remove the first two goals of list_n_lrot/3 and replace the third with list_n_heads_tail(L,N,H,T) and then try the query ?- list_n_lrot(L,N,[1,2,3]).). It's also the reason why the most general query is listing the solutions in a fair order, that is producing all possibilities for every list length instead of only listing the rotation by 0 steps:
?- list_n_lrot(L,N,R).
... % <- first solutions
L = R, R = [_G2142, _G2145, _G2148], % <- length 3, rotation by 0 steps
N mod 3#=0 ;
L = [_G2502, _G2505, _G2508], % <- length 3, rotation by 1 step
R = [_G2505, _G2508, _G2502],
N mod 3#=1 ;
L = [_G2865, _G2868, _G2871], % <- length 3, rotation by 2 steps
R = [_G2871, _G2865, _G2868],
N mod 3#=2 ;
... % <- further solutions
Finally, it also describes the actual length of the two lists, which is used in the next goal to determine the remainder of N modulo the length of the list. Consider the following: If you rotate a list of length N by N steps you arrive at the initial list again. So a rotation by N+1 steps yields the same list as a rotation by 1 step. Algebraically speaking, this goal is exploiting the fact that congruence modulo N is partitioning the infinite set of integers into a finite number of residue classes. So for a list of length N it is sufficient to produce the N rotations that correspond to the N residue classes in order to cover all possible rotations (see the query above for N=3). On the other hand, a given N > list length can be easily computed by taking the smallest non-negative member of its residue class. For example, given a list with three elements, a rotation by 2 or 5 steps respectively yields the same result:
?- list_n_lrot([1,2,3],2,R).
R = [3, 1, 2].
?- list_n_lrot([1,2,3],5,R).
R = [3, 1, 2].
And of course you could also left rotate the list by a negative number of steps, that is rotating it in the other direction:
?- list_n_lrot([1,2,3],-1,R).
R = [3, 1, 2].
On a side note: Since this constitutes rotation to the right, you could easily define right rotation by simply writing:
list_n_rrot(L,N,R) :-
list_n_lrot(L,-N,R).
?- list_n_rrot([1,2,3],1,R).
R = [3, 1, 2].
The predicate list_n_heads_tail/4 is quite similar to splitAt/4 in Willem's post. However, due to the use of if_/3 the predicate succeeds deterministically (no need to hit ; after the only answer since no unnecessary choicepoints are left open), if one of the lists and the second argument of list_n_lrot/3 are ground:
?- list_n_lrot2([a,b,c,d,e],2,R).
R = [c, d, e, a, b].
?- list_n_lrot2(L,2,[c,d,e,a,b]).
L = [a, b, c, d, e].
You can observe another nice effect of using CLP(FD) with the second solution of the most general query:
?- list_n_lrot(L,N,R).
L = R, R = [],
N = 0 ;
L = R, R = [_G125], % <- here
N in inf..sup ; % <- here
...
This answer states, that for a list with one element any rotation by an arbitrary number of steps yields the very same list again. So in principle, this single general answer summarizes an infinite number of concrete answers. Furthermore, you can also ask questions like: What lists are there with regard to a rotation by 2 steps?
?- list_n_lrot2(L,2,R).
L = R, R = [_G19] ;
L = R, R = [_G19, _G54] ;
L = [_G19, _G54, _G22],
R = [_G22, _G19, _G54] ;
...
To finally come back to the example in your question:
?- list_n_lrot([1,2,3,4],2,R).
R = [3, 4, 1, 2].
Note how this more general approach to define arbitrary rotations on lists subsumes your use case of relocating the first N elements to the end of the list.
Try this
despI([C|B],R):-append(B,[C|[]],R).
desp(A,0,A).
desp([C|B],N,R):-N1 is N - 1, despI([C|B],R1), desp(R1,N1,R),!.
The first predicate moves one element to the end of the list, then the only thing I do is "repeat" that N times.
?-de([1,2,3,4],2,R).
R = [3, 4, 1, 2].
?- de([1,2,3,4,5,6,7],4,R).
R = [5, 6, 7, 1, 2, 3, 4].
We can do this with a predicate that works in two phases:
a collect phase: we collect the first N items of the list; and
an emit phase: we construct a list where we add these elements at the tail.
Let is construct the two phases with separate predicate. For the collect phase, we could use the following predicate:
% splitAt(L,N,L1,L2).
splitAt(L,0,[],L).
splitAt([H|T],N,[H|T1],L2) :-
N > 0,
N1 is N-1,
splitAt(T,N1,T1,L2).
Now for the emit phase, we could use append/3. So then the full predicate is:
rotate(L,N,R) :-
splitAt(L,N,L1,L2),
append(L2,L1,R).
This gives:
?- rotate([1,2,3,4],0,R).
R = [1, 2, 3, 4] .
?- rotate([1,2,3,4],1,R).
R = [2, 3, 4, 1] .
?- rotate([1,2,3,4],2,R).
R = [3, 4, 1, 2] .
?- rotate([1,2,3,4],3,R).
R = [4, 1, 2, 3] .
?- rotate([1,2,3,4],4,R).
R = [1, 2, 3, 4].
The algorithm works in O(n).

Masking in Prolog

I have recently been trying to figure out Prolog and been messing with lists of lists in Prolog. I am trying to create a sort of mask I suppose in p
Prolog. I have a predicate that determines the difference between two lists of lists (L1 and L2 lets say) in Prolog and saves them as a list of a list(Lets say R). I have another predicate that simply states if the difference is equal to zero(noDifference). I would like to have two resulting lists of lists (M1 and M2) based off of L1 and L2 compared to the R. For example I would like to compare all values of L1 and L2 to R, if a negative value is at a location of R then the value in the same location of L1 is saved into M1. And if a positive value is at a location of R then the value in the same location of L2 is saved into M2 if that makes sense. Before all of this I check with my noDifference function to see if the difference is 0 and if so all values of M1 and M2's lists of lists will be 0.
This is what I have so far(I'm not sure if I started it right)
masker(L1,L2,R,M1,M2):- noDifference(R1), M1=R, M2=R1;
and for the rest of it here are what some example values should look like under the hood
L1=[[1,5,3,8],[1,5,3,8]]
L2=[[5,4,7,4],[5,4,7,4]]
R=[[4,-1,4,-4],[4,-1,4,-4]]
M1=[[0,5,0,8],[0,5,0,8]]Neg values of L1 at R are stored rest are 0)
M2=[[5,0,7,0],[5,0,7,0]](Pos values of L2 at R are stored rest are 0)
Any insight if what I am doing so far is right and how to properly formulate the subgoals/where I should go next would be awesome!
edit with ex predicate
?- masker([[1,5,3,8],[1,5,3,8]],
[[5,4,7,4],[5,4,7,4]],
[[4,-1,4,-4],[4,-1,4,-4]], M1, M2).
M1=[[0,5,0,8],[0,5,0,8]].
M2=[[5,0,7,0],[5,0,7,0]].
Think what your predicate should describe. It is a relation between five lists of lists which, according to the example you provided, are of same length. This suggests the base case with five empty lists. Otherwise the heads of all five lists are lists themselves, that are in a specific relation to each other, let's call it lists_mask_mlists/5. And of course the same should be true for the tails, which can be realized by a recursive goal. So your predicate masker/5 could look something like that:
masker([],[],[],[],[]).
masker([X|Xs],[Y|Ys],[M|Ms],[R1|R1s],[R2|R2s]) :-
lists_mask_mlists(X,Y,M,R1,R2),
masker(Xs,Ys,Ms,R1s,R2s).
The actual masking relation also has a base case with five empty lists. Otherwise there are two further cases:
1) The current masking element (head of the third list) is negative: The head of the first list is the head of the fourth list and the head of the fifth list is 0
2) The current masking element is positive: The head of the second list is the head of the fifth list and the head of the fourth list is 0
You can express that like so:
lists_mask_mlists([],[],[],[],[]).
lists_mask_mlists([X|Xs],[_Y|Ys],[M|Ms],[X|R1s],[0|R2s]) :- % 1)
M < 0,
lists_mask_mlists(Xs,Ys,Ms,R1s,R2s).
lists_mask_mlists([_X|Xs],[Y|Ys],[M|Ms],[0|R1s],[Y|R2s]) :- % 2)
M >= 0,
lists_mask_mlists(Xs,Ys,Ms,R1s,R2s).
With this predicate your example query yields the desired result:
?- masker([[1,5,3,8],[1,5,3,8]],[[5,4,7,4],[5,4,7,4]],[[4,-1,4,-4],[4,-1,4,-4]],M1,M2).
M1 = [[0,5,0,8],[0,5,0,8]],
M2 = [[5,0,7,0],[5,0,7,0]] ? ;
no
Note however, that due to < and >= this only works, if the third list is variable free. Replacing the first 4 in the third argument by a variable yields an instantiation error:
?- masker([[1,5,3,8],[1,5,3,8]],[[5,4,7,4],[5,4,7,4]],[[X,-1,4,-4],[4,-1,4,-4]],M1,M2).
ERROR at clause 2 of user:masked/5 !!
INSTANTIATION ERROR- =:=/2: expected bound value
If you intend to use the predicate with a third argument that is not variable free, you might like to consider using clpfd. Include the line
:-use_module(library(clpfd)).
in your source file and alter lists_mask_mlists/5 like so:
lists_mask_mlists([],[],[],[],[]).
lists_mask_mlists([X|Xs],[_Y|Ys],[M|Ms],[X|R1s],[0|R2s]) :-
M #< 0, % <- here
lists_mask_mlists(Xs,Ys,Ms,R1s,R2s).
lists_mask_mlists([_X|Xs],[Y|Ys],[M|Ms],[0|R1s],[Y|R2s]) :-
M #>= 0, % <- here
lists_mask_mlists(Xs,Ys,Ms,R1s,R2s).
Now the second query works too:
?- masker([[1,5,3,8],[1,5,3,8]],[[5,4,7,4],[5,4,7,4]],[[X,-1,4,-4],[4,-1,4,-4]],M1,M2).
M1 = [[1,5,0,8],[0,5,0,8]],
M2 = [[0,0,7,0],[5,0,7,0]],
X in inf.. -1 ? ;
M1 = [[0,5,0,8],[0,5,0,8]],
M2 = [[5,0,7,0],[5,0,7,0]],
X in 0..sup ? ;
no
#tas has presented a good solution and explanation (+1).
Building on this code, I would like to improve the space efficiency of the program. Consider again the example query with the CLP(FD) based solution:
?- masker([[1,5,3,8],[1,5,3,8]],[[5,4,7,4],[5,4,7,4]],[[4,-1,4,-4],[4,-1,4,-4]],M1,M2).
M1 = [[0, 5, 0, 8], [0, 5, 0, 8]],
M2 = [[5, 0, 7, 0], [5, 0, 7, 0]] ;
false.
We see from the ; false that choice points were accumulated during the execution of this program, because it was not apparent to the Prolog engine that the clauses were in fact mutually exclusive.
Obviously, such programs use more memory than necessary to keep track of remaining choices.
Resist the temptation to impurely cut away branches of the computation, because that will only lead to even more problems.
Instead, consider using if_/3.
All it takes to apply if_/3 in this case is a very easy reification of the CLP(FD) constraint (#<)/2, which is easy to do with zcompare/3:
#<(X, Y, T) :-
zcompare(C, X, Y),
less_true(C, T).
less_true(<, true).
less_true(>, false).
less_true(=, false).
With this definition, the whole program becomes:
:- use_module(library(clpfd)).
masker([], [], [], [], []).
masker([X|Xs], [Y|Ys], [M|Ms], [R1|R1s], [R2|R2s]) :-
lists_mask_mlists(X, Y, M, R1, R2),
masker(Xs, Ys, Ms, R1s, R2s).
lists_mask_mlists([], [], [], [], []).
lists_mask_mlists([X|Xs], [Y|Ys], [M|Ms], R1s0, R2s0) :-
if_(M #< 0,
(R1s0 = [X|R1s], R2s0 = [0|R2s]),
(R1s0 = [0|R1s], R2s0 = [Y|R2s])),
lists_mask_mlists(Xs, Ys, Ms, R1s, R2s).
And now the point:
?- masker([[1,5,3,8],[1,5,3,8]],[[5,4,7,4],[5,4,7,4]],[[4,-1,4,-4],[4,-1,4,-4]],M1,M2).
M1 = [[0, 5, 0, 8], [0, 5, 0, 8]],
M2 = [[5, 0, 7, 0], [5, 0, 7, 0]].
This example query is now deterministic!
And the program is still general enough to also handle the second example query!

How to get integers from list where sum of them is less than X?

Sorry for the mess that was here.
I wanted a classic greedy algorithm for knapsack problem in haskell for integers.
But there was other question - how to refer to list in list comprehension?
There are several approaches to this:
Generate all lists which are smaller. Take the longest
For every n <= X, generate [1..n] and check whether its sum is lesser x. Take the longest of those sets:
allLists x = takeWhile ( (<=x) . sum) $ inits [1..]
theList = last . allLists
where inits is from Data.List
Alternatively, we remember mathematics
We know that the sum of [1..n] is n*(n+1)/2. We want x >= n * (n+1)/2. We solve for n and get that n should be 0.5 * (sqrt (8 * x + 1) - 1). Since that's not a natural number, we floor it:
theList x = [1..n]
where n = floor $ 0.5 * (sqrt (8 * (fromIntegral x) + 1) - 1)
This will give all the lists that its sum is not greater than 100:
takeWhile (\l -> sum l <= 100) $ inits [1..]