Prolog test is always true var(sum) error - prolog

I am trying to compile a SWI-Prolog program but keep getting test is always true, var (sum) error on line 7. I cant figure out what this means. Can someone please help? This is a program I am hoping will eventually solve Latin squares. Thank you.
:- use_module(library(clpfd)).
magic_counter(Count) :-
findall(a, magic_1(_Soln), As),
length(As, Count).
magic_1(Soln) :-
Row1 = [W1, W2, W3],
Row2 = [X1, X2, X3],
Row3 = [Y1, Y2, Y3],
Row1 ins 1..3,
Row2 ins 1..3,
Row3 ins 1..3,
Sum #= 6,
all_different(Row1),
all_different(Row2),
all_different(Row3),
all_different([W1,X1,Y1]),
all_different([W2,X2,Y2]),
all_different([W3,X3,Y3]),
W1 + W2 + W3 #= Sum,
X1 + X2 + X3 #= Sum,
Y1 + Y2 + Y3 #= Sum,
W1 + X1 + Y1 #= Sum,
W2 + X2 + Y2 #= Sum,
W3 + X3 + Y3 #= Sum,
append(Row1,Row2,Row12),
append(Row12,Row3,Soln),
labeling([], Soln).

It's a warning, not an error.
I posted some time again a request on SWI-Prolog mailing list for this problem, since some existing code begun to raise this warning after a refinement to messages. Here is the answer from Jan.
I think you can ignore the warning, or disable it, but this seems not advisable.

If a row consists of three integers between 1 and 3, and these integers must be distinct, then the sum of such a row must be 6 (by definition). Stating that the sum of such a row equals 6 is therefore an idle constraint. The same reasoning applies to the 'columns' for which you assert similar disjointness constraints.
Edit: Even though the above reasoning is correct, this is not the origin of the warning. Carlo is right on this, it simply depends on the way in which the constraint library rewrites the constraints.
test1:-
L = [X],
L ins 1..2,
Y #= 2,
X #= Y.
test2:-
L = [X],
L ins 1..2,
X #= 2.
test1/0 gives the warning, test2/0 does not. Still, I find it difficult to see why the warning is given in the first place, i.e. what the rational behind it is. For example, here is the expansion of test1/0 (notice my comments):
:- use_module(library(clpfd)).
test1:-
A=[D],
A ins 1..2,
(
integer(B)
->
(
var(2)
->
2 is B
;
true
->
B=:=2
;
C is B,
clpfd:clpfd_equal(C, 2)
)
;
true
->
(
var(B) % This does not throw a warning.
->
B is 2
;
C is 2,
clpfd:clpfd_equal(B, C)
)
;
clpfd:clpfd_equal(B, 2)
),
(
integer(D)
->
(
var(B) % This throws a "Test is always true" warning.
->
B is D
;
integer(B)
->
D=:=B
;
E is D,
clpfd:clpfd_equal(E, B)
)
;
integer(B)
->
(
var(D)
->
D is B
;
E is B,
clpfd:clpfd_equal(D, E)
)
;
clpfd:clpfd_equal(D, B)
).

Related

Argument is not instantiated, need it to start at zero but also be able to change it

Whenever I run my code, I get an error that the arguments are not instantiated.
ads(X,Z):- mod(X,2) =:= 0, Z is Z+X.
ads(X,Z) :- mod(N,2) =\= 0,Z is Z.
sum_of_nums(0,0,0).
sum_of_nums(X,Y,Z) :- X=<Y, ad(X,Z), sum_of_nums(X+1,Y,Z).
I want to be able to add numbers from X to Y but only the even ones. Don't know why it doesn't work.
First, there are some tiny errors, your compiler should indicate, like the unnecessary singleton variables in the second clause. After repairing this, and replacing ads by ad we have:
ad(X,Z):- mod(X,2) =:= 0, Z is Z+X.
ad(X,Z) :- mod(X,2) =\= 0,Z is Z.
sum_of_nums(0,0,0).
sum_of_nums(X,Y,Z) :- X=<Y, ad(X,Z), sum_of_nums(X+1,Y,Z).
?- sum_of_nums(1,2,S).
error(instantiation_error,(is)/2).
To locate this error, I will insert some goals false such that the
resulting program still produces this instantiation error.
ad(X,Z):- mod(X,2) =:= 0, Z is Z+X, false.
ad(X,Z) :- false, mod(X,2) =\= 0,Z is Z.
sum_of_nums(0,0,0) :- false.
sum_of_nums(X,Y,Z) :- X=<Y, ad(X,Z), false, sum_of_nums(X+1,Y,Z).
?- sum_of_nums(1,2,S).
error(instantiation_error,(is)/2).
Therefore, you have an error in this part already.
It's the Z is Z+X. On the right hand side of (is)/2 you always
need to have variables that are instantiated (known). And Z is not
known.
Variables are a bit different in Prolog. You cannot reassign them.
And also, writing this in Prolog directly doesn't really show what the
language is good at.
sum_of(X, Y, 0) :-
X > Y.
sum_of(X1, Y, Z1) :-
X1 =< Y,
( X1 mod 2 =:= 0 -> S = X1 ; S = 0 ),
X2 is X1+1,
sum_of(X2, Y, Z2),
Z1 is Z2+S.
A more idiomatic way would be:
?- between(1,6,N).
N = 1
; N = 2
; N = 3
; N = 4
; N = 5
; N = 6.
?- between(1,6,N), N mod 2 =:= 0.
N = 2
; N = 4
; N = 6.
?- findall(N, ( between(1,6,N), N mod 2 =:= 0 ), Ns).
Ns = [2,4,6].
?- findall(N, ( between(1,6,N), N mod 2 =:= 0 ), Ns), sum_list(Ns,Sum).
Ns = [2,4,6], Sum = 12.
sum_of(X,Y,Sum) :-
findall(N, ( between(X,Y,N), N mod 2 =:= 0 ), Ns),
sum_list(Ns,Sum).

CLPFD constraint: is a prime number

I'm not even sure if this is possible, but I'm trying to write a predicate prime/1 which constrains its argument to be a prime number.
The problem I have is that I haven't found any way of expressing “apply that constraint to all integers less than the variable integer”.
Here is an attempt which doesn't work:
prime(N) :-
N #> 1 #/\ % Has to be strictly greater than 1
(
N #= 2 % Can be 2
#\/ % Or
(
N #> 2 #/\ % A number strictly greater than 2
N mod 2 #= 1 #/\ % which is odd
K #< N #/\
K #> 1 #/\
(#\ (
N mod K #= 0 % A non working attempt at expressing:
“there is no 1 < K < N such that K divides N”
))
)
).
I hoped that #\ would act like \+ and check that it is false for all possible cases but this doesn't seem to be the case, since this implementation does this:
?- X #< 100, prime(X), indomain(X).
X = 2 ; % Correct
X = 3 ; % Correct
X = 5 ; % Correct
X = 7 ; % Correct
X = 9 ; % Incorrect ; multiple of 3
X = 11 ; % Correct
X = 13 ; % Correct
X = 15 % Incorrect ; multiple of 5
…
Basically this unifies with 2\/{Odd integers greater than 2}.
EDIT
Expressing that a number is not prime is very easy:
composite(N) :-
I #>= J,
J #> 1,
N #= I*J.
Basically: “N is composite if it can be written as I*J with I >= J > 1”.
I am still unable to “negate” those constraints. I have tried using things like #==> (implies) but this doesn't seem to be implification at all! N #= I*J #==> J #= 1 will work for composite numbers, even though 12 = I*J doesn't imply that necessarily J = 1!
prime/1
This took me quite a while and I'm sure it's far from being very efficient but this seems to work, so here goes nothing:
We create a custom constraint propagator (following this example) for the constraint prime/1, as such:
:- use_module(library(clpfd)).
:- multifile clpfd:run_propagator/2.
prime(N) :-
clpfd:make_propagator(prime(N), Prop),
clpfd:init_propagator(N, Prop),
clpfd:trigger_once(Prop).
clpfd:run_propagator(prime(N), MState) :-
(
nonvar(N) -> clpfd:kill(MState), prime_decomposition(N, [_])
;
clpfd:fd_get(N, ND, NL, NU, NPs),
clpfd:cis_max(NL, n(2), NNL),
clpfd:update_bounds(N, ND, NPs, NL, NU, NNL, NU)
).
If N is a variable, we constrain its lower bound to be 2, or keep its original lower bound if it is bigger than 2.
If N is ground, then we check that N is prime, using this prime_decomposition/2 predicate:
prime_decomposition(2, [2]).
prime_decomposition(N, Z) :-
N #> 0,
indomain(N),
SN is ceiling(sqrt(N)),
prime_decomposition_1(N, SN, 2, [], Z).
prime_decomposition_1(1, _, _, L, L) :- !.
prime_decomposition_1(N, SN, D, L, LF) :-
(
0 #= N mod D -> !, false
;
D1 #= D+1,
(
D1 #> SN ->
LF = [N |L]
;
prime_decomposition_2(N, SN, D1, L, LF)
)
).
prime_decomposition_2(1, _, _, L, L) :- !.
prime_decomposition_2(N, SN, D, L, LF) :-
(
0 #= N mod D -> !, false
;
D1 #= D+2,
(
D1 #> SN ->
LF = [N |L]
;
prime_decomposition_2(N, SN, D1, L, LF)
)
).
You could obviously replace this predicate with any deterministic prime checking algorithm. This one is a modification of a prime factorization algorithm which has been modified to fail as soon as one factor is found.
Some queries
?- prime(X).
X in 2..sup,
prime(X).
?- X in -100..100, prime(X).
X in 2..100,
prime(X).
?- X in -100..0, prime(X).
false.
?- X in 100..200, prime(X).
X in 100..200,
prime(X).
?- X #< 20, prime(X), indomain(X).
X = 2 ;
X = 3 ;
X = 5 ;
X = 7 ;
X = 11 ;
X = 13 ;
X = 17 ;
X = 19.
?- prime(X), prime(Y), [X, Y] ins 123456789..1234567890, Y-X #= 2, indomain(Y).
X = 123457127,
Y = 123457129 ;
X = 123457289,
Y = 123457291 ;
X = 123457967,
Y = 123457969
…
?- time((X in 123456787654321..1234567876543210, prime(X), indomain(X))).
% 113,041,584 inferences, 5.070 CPU in 5.063 seconds (100% CPU, 22296027 Lips)
X = 123456787654391 .
Some problems
This constraint does not propagate as strongly as it should. For example:
?- prime(X), X in {2,3,8,16}.
X in 2..3\/8\/16,
prime(X).
when we should know that 8 and 16 are not possible since they are even numbers.
I have tried to add other constraints in the propagator but they seem to slow it down more than anything else, so I'm not sure if I was doing something wrong or if it is slower to update constaints than check for primeness when labeling.

Even sum & Odd product of a list, Swi-Prolog [duplicate]

I have a list of numbers, I need to calculate the sum of the even numbers of the list and the product of the odd numbers of the same list. I'm new in Prolog, and my searches so far weren't successful. Can anyone help me solve it ?
l_odd_even([]).
l_odd_even([H|T], Odd, [H|Etail]) :-
H rem 2 =:=0,
split(T, Odd, Etail).
l_odd_even([H|T], [H|Otail], Even) :-
H rem 2 =:=1,
split(T, Otail, Even).
Here is a suggestion for the sum of the even numbers from a list:
even(X) :-
Y is mod(X,2), % using "is" to evaluate to number
Y =:= 0.
odd(X) :- % using even
Y is X + 1,
even(Y).
sum_even(0, []). % empty list has zero sum
sum_even(X, [H|T]) :-
even(H),
sum_even(Y, T),
X is Y+H.
sum_even(X, [H|T]) :-
odd(H),
sum_even(X, T). % ignore the odd numbers
Note: My Prolog has oxidized, so there might be better solutions. :-)
Note: Holy cow! There seems to be no Prolog support for syntax highlighting (see here), so I used Erlang syntax.
Ha, it really works. :-)
Running some queries in GNU Prolog, I get:
| ?- sum_even(X,[]).
X = 0 ?
yes
| ?- sum_even(X,[2]).
X = 2 ?
yes
| ?- sum_even(X,[3]).
X = 0 ?
yes
| ?- sum_even(X,[5,4,3,2,1,0]).
X = 6 ?
yes
The ideas applied here should enable you to come up with the needed product.
Use clpfd!
:- use_module(library(clpfd)).
Building on meta-predicate foldl/4, we only need to define what a single folding step is:
sumprod_(Z,S0,S) :-
M #= Z mod 2,
rem_sumprod_(M,Z,S0,S).
rem_sumprod_(0,Z,S0-P,S-P) :-
S0 + Z #= S.
rem_sumprod_(1,Z,S-P0,S-P) :-
P0 * Z #= P.
Let's fold sumprod_/3 over the list!
l_odd_even(Zs,ProductOfOdds,SumOfEvens) :-
foldl(sumprod_,Zs,0-1,SumOfEvens-ProductOfOdds).
Sample query:
?- l_odd_even([1,2,3,4,5,6,7],Odd,Even).
Odd = 105,
Even = 12.
Alternatively, we can define sumprod_/3 even more concisely by using if_/3 and zeven_t/3:
sumprod_(Z,S0-P0,S-P) :-
if_(zeven_t(Z), (S0+Z #= S, P0=P),
(P0*Z #= P, S0=S)).
untested!
sum_odd_product_even([], S, P, S, P).
sum_odd_product_even([H|T], S0, P0, S, P) :-
S1 is S0 + H,
sum_even_product_odd(T, S1, P0, S, P).
sum_even_product_odd([], S, P, S, P).
sum_even_product_odd([H|T], S0, P0, S, P) :-
P1 is P0 * H,
sum_odd_product_even(T, S0, P1, S, P).
sum_odd_product_even(L, S, P) :-
sum_odd_product_even(L, 0, 1, S, P).
sum_even_product_odd(L, S, P) :-
sum_even_product_odd(L, 0, 1, S, P).
It shouldn't get much simpler than
%
% invoke the worker predicate with the accumulators seeded appropriately.
%
odds_and_evens( [O] , P , S ) :- odds_and_evens( [] , O , 0 , P , S ) .
odds_and_evens( [O,E|Ns] , P , S ) :- odds_and_evens( Ns , O , E , P , S ) .
odds_and_evens( [] , P , S , P , S ) . % if the list is exhausted, we're done.
odds_and_evens( [O] , X , X , P , S ) :- % if it's a single element list, we've only an odd element...
P is X*O , % - compute it's product
. % - and we're done.
odds_and_evens( [O,E|Ns] , X , Y , P , S ) :- % if the list is at least two elements in length'e both an odd and an even:
X1 is X*O , % - increment the odd accumulator
Y1 is Y+E , % - increment the even accumulator
odds_and_evens( Ns , X1 , Y1 , P , S ) % - recurse down (until it coalesces into one of the two special cases)
. % Easy!

Difference between matrix column and use of all_different

I'm trying to express a relation on transition from one element in a list-of-lists, to another element. What I want to be able to do, is to say that there should exist a certain difference between two arbitrary elements.
If we have the list
X=[X1,X2,X3,...Xn]
where all elements are lists of length Y.
I now want to express that there should a difference from Xa->Xb where all elements in Xa
is equal or less but one, and Xa and Xb is any given element of X (a!=b)
Ex: If Xa=[1,1,1,1] then Xb could be [1,1,1,2] since all elements are equal or decrease expect one, the last, which goes from 1->2.
I have written the following predicate to do this:
ensure_atleast_n_patterns( ListOfLists, DiffPattern, NoOfAtLeastEqualPatterns ) :-
(
%Loop through the list to set up the constraint between first
%element and the rest, move on to next element and and set
%up constraint from second element on on etc.
%Ex: if ListOfLists=[X1,X2,X3,X4], the following 'loops' will run:
%X1-X2, X1-X3,X1-4,X2-X3,X2-X4,X3,X4
fromto(ListOfLists, [This | Rest], Rest,[_]),
fromto(0,In1,Out1,PatternCount),
param([DiffPattern])
do
(
%Compare the difference between two elements:
foreach( X, Rest ),
fromto(0,In2,Out2,Sum2),
param([DiffPattern,This])
do
This=[X1,X2,X3,X4,X5],
X=[Y1,Y2,Y3,Y4,Y5],
DiffPattern=[P1,P2,P3,P4,P5],
X1 #< Y1 #<=> R1,
X2 #< Y2 #<=> R2,
X3 #< Y3 #<=> R3,
X4 #< Y4 #<=> R4,
X5 #< Y5 #<=> R5,
Result in 0..1,
(R1 #= P1) #/\ (R2 #= P2) #/\ (R3 #= P3) #/\ (R4 #= P4) #/\ (R5 #= P5) #<=> (Result #=1),
Out2 #= In2 + Result
),
Out1 #= In1 + Sum2
),
%Count up, and require that this pattern should at least be present
%NoOfAtLeastEqualPatterns times
PatternCount #>= NoOfAtLeastEqualPatterns.
This seams to work ok.
My problems occurs if I also try to use all_different() on the rows.
Ex: I would guess that a solution could be:
0,0,0,0,0
2,2,2,2,1
1,1,1,1,2
4,4,4,3,4
3,3,3,4,3
etc...
But labeling hangs 'forever'
Is my approach wrong? Any better way to solve this?
Test code:
mytest( X ):-
Tlen = 10,
Mind = 0,
Maxd = 20,
length( X1,Tlen),
length( X2,Tlen),
length( X3,Tlen),
length( X4,Tlen),
length( X5,Tlen),
domain(X1, Mind, Maxd),
domain(X2, Mind, Maxd),
domain(X3, Mind, Maxd),
domain(X4, Mind, Maxd),
domain(X5, Mind, Maxd),
all_different( X1 ),
all_different( X2 ),
all_different( X3 ),
all_different( X4 ),
all_different( X5 ),
X=[X1,X2,X3,X4,X5],
transpose( X, XT ),
ensure_atleast_n_patterns( XT, [0,0,0,0,1],1),
ensure_atleast_n_patterns( XT, [0,0,0,1,0],1),
ensure_atleast_n_patterns( XT, [0,0,1,0,0],1),
ensure_atleast_n_patterns( XT, [0,1,0,0,0],1),
ensure_atleast_n_patterns( XT, [1,0,0,0,0],1).
And I run it like this:
mytest(X),append(X, X_1), labeling( [], X_1 ).
There is one thing that makes me suspect that your code doesn't express what you have in mind. You say: "I now want to express that there should a difference from Xa->Xb where all elements in Xa is equal or less but one, and Xa and Xb is any given element of X (a!=b)". But in your code, you don't consider all pairs of elements. You only consider pairs where Xb is somewhere to the right of Xa (Xb is an element of Rest). This asymmetry likely makes it hard to find solutions.
Nevertheless, here's a solution with Tlen = Maxd = 5:
| ?- mytest([[0,3,4,1,2],[1,2,4,0,3],[1,4,2,0,3],[3,1,4,2,0],[3,4,1,2,0]]).
yes
But due to the asymmetry, the following fails:
| ?- mytest([[0,1,2,3,4],[1,0,3,2,4],[1,0,3,4,2],[3,2,0,1,4],[3,2,0,4,1]]).
no
If you fix your code so that it considers all pairs (Xa,Xb), then from any solution you could get another solution by permuting the elements of ListOfLists (the rows of XT). It's usually a good idea to reduce the search space by breaking this kind of solution symmetry. You can do that with:
lex_chain(XT),
By the way, I recommend all_distinct/1 instead of all_different/1.

Inverse factorial in Prolog

Can someone helping me to find a way to get the inverse factorial in Prolog...
For example inverse_factorial(6,X) ===> X = 3.
I have been working on it a lot of time.
I currently have the factorial, but i have to make it reversible. Please help me.
Prolog's predicates are relations, so once you have defined factorial, you have implicitly defined the inverse too. However, regular arithmetics is moded in Prolog, that is, the entire expression in (is)/2 or (>)/2 has to be known at runtime, and if it is not, an error occurs. Constraints overcome this shortcoming:
:- use_module(library(clpfd)).
n_factorial(0, 1).
n_factorial(N, F) :-
N #> 0, N1 #= N - 1, F #= N * F1,
n_factorial(N1, F1).
This definition now works in both directions.
?- n_factorial(N,6).
N = 3
; false.
?- n_factorial(3,F).
F = 6
; false.
Since SICStus 4.3.4 and SWI 7.1.25 also the following terminates:
?- n_factorial(N,N).
N = 1
; N = 2
; false.
See the manual for more.
For reference, here is the best implementation of a declarative factorial predicate I could come up with.
Two main points are different from #false's answer:
It uses an accumulator argument, and recursive calls increment the factor we multiply the factorial with, instead of a standard recursive implementation where the base case is 0. This makes the predicate much faster when the factorial is known and the initial number is not.
It uses if_/3 and (=)/3 extensively, from module reif, to get rid of unnecessary choice points when possible. It also uses (#>)/3 and the reified (===)/6 which is a variation of (=)/3 for cases where we have two couples that can be used for the if -> then part of if_.
factorial/2
factorial(N, F) :-
factorial(N, 0, 1, F).
factorial(N, I, N0, F) :-
F #> 0,
N #>= 0,
I #>= 0,
I #=< N,
N0 #> 0,
N0 #=< F,
if_(I #> 2,
( F #> N,
if_(===(N, I, N0, F, T1),
if_(T1 = true,
N0 = F,
N = I
),
( J #= I + 1,
N1 #= N0*J,
factorial(N, J, N1, F)
)
)
),
if_(N = I,
N0 = F,
( J #= I + 1,
N1 #= N0*J,
factorial(N, J, N1, F)
)
)
).
(#>)/3
#>(X, Y, T) :-
zcompare(C, X, Y),
greater_true(C, T).
greater_true(>, true).
greater_true(<, false).
greater_true(=, false).
(===)/6
===(X1, Y1, X2, Y2, T1, T) :-
( T1 == true -> =(X1, Y1, T)
; T1 == false -> =(X2, Y2, T)
; X1 == Y1 -> T1 = true, T = true
; X1 \= Y1 -> T1 = true, T = false
; X2 == Y2 -> T1 = false, T = true
; X2 \= Y2 -> T1 = false, T = false
; T1 = true, T = true, X1 = Y1
; T1 = true, T = false, dif(X1, Y1)
).
Some queries
?- factorial(N, N).
N = 1 ;
N = 2 ;
false. % One could probably get rid of the choice point at the cost of readability
?- factorial(N, 1).
N = 0 ;
N = 1 ;
false. % Same
?- factorial(10, N).
N = 3628800. % No choice point
?- time(factorial(N, 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000)).
% 79,283 inferences, 0.031 CPU in 0.027 seconds (116% CPU, 2541106 Lips)
N = 100. % No choice point
?- time(factorial(N, 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518284253697920827223758251185210916864000000000000000000000000)).
% 78,907 inferences, 0.031 CPU in 0.025 seconds (125% CPU, 2529054 Lips)
false.
?- F #> 10^100, factorial(N, F).
F = 11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000,
N = 70 ;
F = 850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000,
N = 71 ;
F = 61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000,
N = 72 ;
...
a simple 'low tech' way: enumerate integers until
you find the sought factorial, then 'get back' the number
the factorial being built is greater than the target. Then you can fail...
Practically, you can just add 2 arguments to your existing factorial implementation, the target and the found inverse.
Just implement factorial(X, XFact) and then swap arguments
factorial(X, XFact) :- f(X, 1, 1, XFact).
f(N, N, F, F) :- !.
f(N, N0, F0, F) :- succ(N0, N1), F1 is F0 * N1, f(N, N1, F1, F).

Resources