Prolog: Head of a variable list is not instantated - list

I'm writing a simple code generating a simple list with 5 numbers whose first variable should be positive and I'm trying to understand why this code fails
test([H|T]) :- H > 0, length(T,4).
when I call with
length(X,5), test(X).
it shows me the following error:
ERROR: Arguments are not sufficiently instantiated
When I debug the code, the H variable in test isn't instantiated.
Anyone know why?

The issue here is that your rule for test([H|T]) doesn't describe in Prolog that H is a positive integer. It only tests if H > 0, which fails since H has not instantiation. Just attempting to compare an uninstantiated variable with a number (H > 0 in this case) doesn't cause Prolog to assume you intended H to be a number, and further, doesn't instantiate H.
Further, your rule for test/1 doesn't describe the rest of the list (T) other than to force that it be length 4. Since you're query establishes the rule that the length of the original list be 5, this stipulation is redundant.
You appear to be wanting to define test(L) such that it means L is an arbitrary list of positive integers. This is generally done using CLP(FD):
:- use_module(library(clpfd)).
test(X) :- X ins 1..10000.
This rule says that X is a list whose values are in the range 1 to 10000. The appropriate query to generate the lists of length 5 would then be:
?- length(X, 5), test(X), label(X).
X = [1, 1, 1, 1, 1] ;
X = [1, 1, 1, 1, 2] ;
X = [1, 1, 1, 1, 3] ;
X = [1, 1, 1, 1, 4] ;
X = [1, 1, 1, 1, 5] ;
...
If you want to restrict it further and say that elements need to be unique, you can use all_different/1:
test(X) :- X ins 1..10000, all_different(X).
?- length(X, 5), test(X), label(X).
X = [1, 2, 3, 4, 5] ;
X = [1, 2, 3, 4, 6] ;
X = [1, 2, 3, 4, 7] ;
X = [1, 2, 3, 4, 8] ;
X = [1, 2, 3, 4, 9] ;
X = [1, 2, 3, 4, 10] ;
...

Related

Eigen MatrixXi to VectorXi conversion

I have a MatrixXi, say
[0, 1, 2]
[0, 2, 3]
[4, 7, 6]
[4, 6, 5]
[0, 4, 5]
[0, 5, 1]
[1, 5, 6]
I get a part of it by doing:
MatrixXi MR = F.middleRows(first, last);
with first and last at will. Now I'd like to turn those n rows into a column VectorXi, like:
[0,
1,
2,
0,
2,
3]
possibly without using a for loop. I've tried:
VectorXi VRT(MR.rows() * MR.cols());
VRT.tail(MR.rows() * MR.cols()) = MR.array();
But I get:
Assertion failed: (rows == this->rows() && cols == this->cols() && "DenseBase::resize() does not actually allow to resize."), function resize, file /Users/max/Developer/Stage/Workspace/AutoTools3D/dep/libigl/external/eigen/Eigen/src/Core/DenseBase.h, line 257.
How do I get that? I'm using Eigen before v4 so I cannot use reshape...
Thank you
As pointed out by chtz, this works:
Eigen::VectorXi VR(MR.size());
Eigen::MatrixXi::Map(VR.data(), MR.cols(), MR.rows()) =
MR.transpose();

List negative indexing of 0; x[-0]

Can anyone explain how works Negative index of 0?
x = [2, 3, 5, 6]
print(x[-0])
output: 2
What you enter as the index gets evaluated. For example :
x = [2, 3, 5, 6]
print(x[2 - 1])
It prints 3 because it is evaluated as print(x[1]). Here you used -0 so it is the same as 0.

Unique combinations of 0 and 1 in list in prolog

I have problem, because I want to generate permutations of a list (in prolog), which contains n zeros and 24 - n ones without repetitions. I've tried:findall(L, permutation(L,P), Bag) and then sort it to remove repetitions, but it causes stack overflow. Anyone has an efficient way to do this?
Instead of thinking about lists, think about binary numbers. The list will have a length of 24 elements. If all those elements are 1's we have:
?- X is 0b111111111111111111111111.
X = 16777215.
The de fact standard predicate between/3 can be used to generate numbers in the interval [0, 16777215]:
?- between(0, 16777215, N).
N = 0 ;
N = 1 ;
N = 2 ;
...
Only some of these numbers satisfy your condition. Thus, you will need to filter/test them and then convert the numbers that pass into a list representation of its binary equivalent.
Select n random numbers between 0 and 23 in ascending order. These integers give you the indexes of the zeroes and all the configurations are different. The key is generating these list of indexes.
%
% We need N monotonically increasing integer numbers (to be used
% as indexes) from [From,To].
%
need_indexes(N,From,To,Sol) :-
N>0,
!,
Delta is To-From+1,
N=<Delta, % Still have a chance to generate them all
N_less is N-1,
From_plus is From+1,
(
% Case 1: "From" is selected into the collection of index values
(need_indexes(N_less,From_plus,To,SubSol),Sol=[From|SubSol])
;
% Case 2: "From" is not selected, which is only possible if N<Delta
(N<Delta -> need_indexes(N,From_plus,To,Sol))
).
need_indexes(0,_,_,[]).
Now we can get list of indexes picked from the available possible indexes.
For example:
Give me 5 indexes from 0 to 23 (inclusive):
?- need_indexes(5,0,23,Collected).
Collected = [0, 1, 2, 3, 4] ;
Collected = [0, 1, 2, 3, 5] ;
Collected = [0, 1, 2, 3, 6] ;
Collected = [0, 1, 2, 3, 7] ;
...
Give them all:
?- findall(Collected,need_indexes(5,0,23,Collected),L),length(L,LL).
L = [[0, 1, 2, 3, 4], [0, 1, 2, 3, 5], [0, 1, 2, 3, 6], [0, 1, 2, 3, 7], [0, 1, 2, 3|...], [0, 1, 2|...], [0, 1|...], [0|...], [...|...]|...],
LL = 42504.
We are expecting: (24! / ((24-5)! * 5!)) solutions.
Indeed:
?- L is 20*21*22*23*24 / (1*2*3*4*5).
L = 42504.
Now the only problem is transforming every solution like [0, 1, 2, 3, 4] into a string of 0 and 1. This is left as an exercise!
Here is an even simpler answer to generate strings directly. Very direct.
need_list(ZeroCount,OneCount,Sol) :-
length(Zs,ZeroCount),maplist([X]>>(X='0'),Zs),
length(Os,OneCount),maplist([X]>>(X='1'),Os),
compose(Zs,Os,Sol).
compose([Z|Zs],[O|Os],[Z|More]) :- compose(Zs,[O|Os],More).
compose([Z|Zs],[O|Os],[O|More]) :- compose([Z|Zs],Os,More).
compose([],[O|Os],[O|More]) :- !,compose([],Os,More).
compose([Z|Zs],[],[Z|More]) :- !,compose(Zs,[],More).
compose([],[],[]).
rt(ZeroCount,Sol) :-
ZeroCount >= 0,
ZeroCount =< 24,
OneCount is 24-ZeroCount,
need_list(ZeroCount,OneCount,SolList),
atom_chars(Sol,SolList).
?- rt(20,Sol).
Sol = '000000000000000000001111' ;
Sol = '000000000000000000010111' ;
Sol = '000000000000000000011011' ;
Sol = '000000000000000000011101' ;
Sol = '000000000000000000011110' ;
Sol = '000000000000000000100111' ;
Sol = '000000000000000000101011' ;
Sol = '000000000000000000101101' ;
Sol = '000000000000000000101110' ;
Sol = '000000000000000000110011' ;
Sol = '000000000000000000110101' ;
....
?- findall(Collected,rt(5,Collected),L),length(L,LL).
L = ['000001111111111111111111', '000010111111111111111111', '000011011111111111111111', '000011101111111111111111', '000011110111111111111111', '000011111011111111111111', '000011111101111111111111', '000011111110111111111111', '000011111111011111111111'|...],
LL = 42504.

Replacing elements in an array in Python

I want to look in an array of elements. If an element exceeds a certain value x, replace it with another value y. It could be a bunch of elements that need to be replaced. Is there a function (code) to do this at once. I don't want to use for loop.
Does the any() function help here?
Thanks
I really don't know how one could possibly achieve such a thing without the if statement.
Don't know about any() but I gave it a try with map since you don't want a for loop. But, do note that the complexity order (Big O) is still n.
>>> array = [1, 2, 3, 4, 2, -2, -3, 8, 3, 0]
>>> array = map(lambda x: x if x < 3 else 2, array)
>>> array
[1, 2, 2, 2, 2, -2, -3, 2, 2, 0]
Basically, x if x < 3 else 2 works like If an element exceeds a certain value x, replaces it with another value y.

Prolog: Putting elements in a list for a decimal to binary conversion

Hello I was trying to modify a decimal to binary conversion function, so that it would display the results in a list. I'm new to prolog and I can't seem to get it to function properly.
dec2bin(0,0).
dec2bin(1,1).
dec2bin(N,L):- N>1,X is N mod 2,Y is N//2, dec2bin(Y,L1), L = [L1|[X]].
Then this is the result:
86 ?- dec2bin(26,L).
L = [[[[1, 1], 0], 1], 0]
Can someone help me understand what it is that I'm doing wrong.
Thanks
if you amend your code
dec2bin(0,[0]).
dec2bin(1,[1]).
dec2bin(N,L):-
N > 1,
X is N mod 2,
Y is N // 2,
dec2bin(Y,L1),
L = [X|L1].
you will get your solution with bits in reverse order:
?- dec2bin(26,L).
L = [0, 1, 0, 1, 1]
Instead of appending each bit, consider a final reverse/2, or invert the order by means of an accumulator
dec2bin(N,L) :- dec2bin(N,[],L).
dec2bin(0,L,[0|L]).
dec2bin(1,L,[1|L]).
dec2bin(N,L,R):-
N > 1,
X is N mod 2,
Y is N // 2,
dec2bin(Y,[X|L],R).
You have to apply some list concatenation, but you are just creating two terms lists and nesting them with L = [L1|[X]] when you consider L1 to be just a number.
If you consider it as a list, you can simply appending to it the newly created X, but to do so you have to rewrite the base cases of your recursion:
dec2bin(0,[0]).
dec2bin(1,[1]).
dec2bin(N,L):-
N > 1,
X is N mod 2,
Y is N // 2,
dec2bin(Y,L1),
append(L1, [X], L).
yielding to:
?- dec2bin(26,L).
L = [1, 1, 0, 1, 0]
where append/3 can be a library predicate or your own implementation.