right-hand-side of clause doesn't agree with function result type [literal] - sml

I am trying to compute binomial coefficients using Dynamic Programming. I keep getting this error
fun binomial(m:int, n:int, DP) =
if n = m orelse n = 0 then
Array2.update(DP, m, n, 1)
else if Array2.sub(DP, m, n) = ~1 then (
if Array2.sub(DP, m-1, n) = ~1 then
Array2.update(DP, m-1, n, binomial(m-1, n, DP))
else
Array2.update(DP, m-1, n, Array2.sub(DP, m-1, n));
if Array2.sub(DP, m-1, n-1) = ~1 then
Array2.update(DP, m-1, n-1, binomial(m-1, n-1, DP))
else
Array2.update(DP, m-1, n-1, Array2.sub(DP, m-1, n-1));
let
val k = Array2.sub(DP, m-1, n) + Array2.sub(DP, m-1, n-1);
in
Array2.update(DP, m, n, k)
end
)
else
Array2.update(DP, m, n, Array2.sub(DP, m, n));
Array2.sub(DP, m, n)
I am don't understand what this error is trying to say.
6.5-25.48 Error: right-hand-side of clause doesn't agree with function result type [literal]
expression: unit
result type: int
in declaration:
binomial =
(fn (<pat> : int,<pat> : int,DP) =>
if <exp> orelse <exp>
then Array2.update <exp>
else if <exp> then <exp> else <exp>)
Can anyone help me?

Your function binomial returns the result of Array2.update, which is a unit. But you're passing this return value in to Array2.update as the last argument, which is expecting an int.
EDIT: Oh, now I see... Your only problem is that the last line (Array2.sub(DP,m,n)) isn't part of your function - if you want to build a list of expressions, you need to surround it with brackets. So instead of
fun binomial (m,n,DP) = <update logic>; Array2.sub(DP,m,n)
you want
fun binomial (m,n,DP) = (<update logic>; Array2.sub(DP,m,n))

Related

Cplex definition of variables

Firstly I am newly with cplex, i want to define R as a set of two pairs (i,j) and then write the below constrains:
zij ∈ {0, 1}, ∀ i, j s.t.(i, j) ∈ R
fj − fi ≥ 0 − M(1 − zij ), ∀ i, j s.t.(i, j) ∈ R
fi − fj ≥ E − Mzij , ∀ i, j s.t.(i, j) ∈ R
Noting:
E is a very small positive number
M is a “sufficiently large” number
and I have defined f as dvar int+ f[channels];
You could start with
int M=1000;
int E=2;
range R=1..10;
dvar boolean z[R,R];
dvar int+ f[R];
subject to
{
forall(i,j in R)
{
f[j]-f[i]>=0-M*(1-z[i][j]);
f[j]-f[i]>=E-M*z[i,j];
}
}

Prolog find indices in a list and output them as a list

I'm trying to implement a predicate indices_zero(L,R), which should find all positions of zeros in a list and output the indices in a new list.
I'm trying to do this with accumulators.
For example:
?-indices_zero([1,-2,3,0,5,0],R).
R=[4,6];
I have implemented following:
indices_zero(Ls,R):-
indices_zero(Ls,1,[],Result).
indices_zero([L|Ls],N,R,Result):-
L=:=0,
N1 is N+1,
indices-zero(Ls,N1,[N|R],Result).
indices_zero([L|Ls],N,R,Result):-
L=\=0,
N1 is N+1,
indices_zero(Ls,N1,R,Result).
indizes_zero([],_,Result,Result).
I'm not sure why my implementation doesn't work. I think my thirst clause
isn't correct, but I don't know how to solve this.
Try this.
indices_zero(Ls, R) :-
indices_zero(Ls, 1, [], R).
indices_zero([], _, Result, Result).
indices_zero([0|T], N, Result_in, Result_out) :-
N1 is N + 1,
indices_zero(T, N1, [N|Result_in], Result_out).
indices_zero([H|T], N, Result_in, Result_out) :-
H \== 0,
N1 is N + 1,
indices_zero(T, N1, Result_in, Result_out).
?- indices_zero([1,-2,3,0,5,0],R).
R = [6, 4] ;
false.
Here is a variation that builds the result while backtracking.
Notice the order of the indices in the answer are now in ascending order.
indices_zero(Ls,R) :-
indices_zero(Ls,1,R).
indices_zero([],_,[]).
indices_zero([0|T], N, [N|Result]) :-
N1 is N + 1,
indices_zero(T, N1, Result).
indices_zero([H|T], N, Result) :-
H \== 0,
N1 is N + 1,
indices_zero(T, N1, Result).
?- indices_zero([1,-2,3,0,5,0],R).
R = [4, 6] ;
false.

Finding nCr%m in C++ efficiently for very large N [duplicate]

I want to compute nCk mod m with following constraints:
n<=10^18
k<=10^5
m=10^9+7
I have read this article:
Calculating Binomial Coefficient (nCk) for large n & k
But here value of m is 1009. Hence using Lucas theorem, we need only to calculate 1009*1009 different values of aCb where a,b<=1009
How to do it with above constraints.
I cannot make a array of O(m*k) space complexity with given constraints.
Help!
The binominal coefficient of (n, k) is calculated by the formula:
(n, k) = n! / k! / (n - k)!
To make this work for large numbers n and k modulo m observe that:
Factorial of a number modulo m can be calculated step-by-step, in
each step taking the result % m. However, this will be far too slow with n up to 10^18. So there are faster methods where the complexity is bounded by the modulo, and you can use some of those.
The division (a / b) mod m is equal to (a * b^-1) mod m, where b^-1 is the inverse of b modulo m (that is, (b * b^-1 = 1) mod m).
This means that:
(n, k) mod m = (n! * (k!)^-1 * ((n - k)!)^-1) mod m
The inverse of a number can be efficiently found using the Extended Euclidean algorithm. Assuming you have the factorial calculation sorted out, the rest of the algorithm is straightforward, just watch out for integer overflows on multiplication. Here's reference code that works up to n=10^9. To handle for larger numbers the factorial computation should be replaced with a more efficient algorithm and the code should be slightly adapted to avoid integer overflows, but the main idea will remain the same:
#define MOD 1000000007
// Extended Euclidean algorithm
int xGCD(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
int x1, y1, gcd = xGCD(b, a % b, x1, y1);
x = y1;
y = x1 - (long long)(a / b) * y1;
return gcd;
}
// factorial of n modulo MOD
int modfact(int n) {
int result = 1;
while (n > 1) {
result = (long long)result * n % MOD;
n -= 1;
}
return result;
}
// multiply a and b modulo MOD
int modmult(int a, int b) {
return (long long)a * b % MOD;
}
// inverse of a modulo MOD
int inverse(int a) {
int x, y;
xGCD(a, MOD, x, y);
return x;
}
// binomial coefficient nCk modulo MOD
int bc(int n, int k)
{
return modmult(modmult(modfact(n), inverse(modfact(k))), inverse(modfact(n - k)));
}
Just use the fact that
(n, k) = n! / k! / (n - k)! = n*(n-1)*...*(n-k+1)/[k*(k-1)*...*1]
so you actually have just 2*k=2*10^5 factors. For the inverse of a number you can use suggestion of kfx since your m is prime.
First, you don't need to pre-compute and store all the possible aCb values! they can be computed per case.
Second, for the special case when (k < m) and (n < m^2), the Lucas theorem easily reduces to the following result:
(n choose k) mod m = ((n mod m) choose k) mod m
then since (n mod m) < 10^9+7 you can simply use the code proposed by #kfx.
We want to compute nCk (mod p). I'll handle when 0 <= k <= p-2, because Lucas's theorem handles the rest.
Wilson's theorem states that for prime p, (p-1)! = -1 (mod p), or equivalently (p-2)! = 1 (mod p) (by division).
By division: (k!)^(-1) = (p-2)!/(k!) = (p-2)(p-3)...(k+1) (mod p)
Thus, the binomial coefficient is n!/(k!(n-k)!) = n(n-1)...(n-k+1)/(k!) = n(n-1)...(n-k+1)(p-2)(p-3)...(k+1) (mod p)
Voila. You don't have to do any inverse computations or anything like that. It's also fairly easy to code. A couple optimizations to consider: (1) you can replace (p-2)(p-3)... with (-2)(-3)...; (2) nCk is symmetric in the sense that nCk = nC(n-k) so choose the half that requires you to do less computations.

Finding binomial coefficient for large n and k modulo m

I want to compute nCk mod m with following constraints:
n<=10^18
k<=10^5
m=10^9+7
I have read this article:
Calculating Binomial Coefficient (nCk) for large n & k
But here value of m is 1009. Hence using Lucas theorem, we need only to calculate 1009*1009 different values of aCb where a,b<=1009
How to do it with above constraints.
I cannot make a array of O(m*k) space complexity with given constraints.
Help!
The binominal coefficient of (n, k) is calculated by the formula:
(n, k) = n! / k! / (n - k)!
To make this work for large numbers n and k modulo m observe that:
Factorial of a number modulo m can be calculated step-by-step, in
each step taking the result % m. However, this will be far too slow with n up to 10^18. So there are faster methods where the complexity is bounded by the modulo, and you can use some of those.
The division (a / b) mod m is equal to (a * b^-1) mod m, where b^-1 is the inverse of b modulo m (that is, (b * b^-1 = 1) mod m).
This means that:
(n, k) mod m = (n! * (k!)^-1 * ((n - k)!)^-1) mod m
The inverse of a number can be efficiently found using the Extended Euclidean algorithm. Assuming you have the factorial calculation sorted out, the rest of the algorithm is straightforward, just watch out for integer overflows on multiplication. Here's reference code that works up to n=10^9. To handle for larger numbers the factorial computation should be replaced with a more efficient algorithm and the code should be slightly adapted to avoid integer overflows, but the main idea will remain the same:
#define MOD 1000000007
// Extended Euclidean algorithm
int xGCD(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
int x1, y1, gcd = xGCD(b, a % b, x1, y1);
x = y1;
y = x1 - (long long)(a / b) * y1;
return gcd;
}
// factorial of n modulo MOD
int modfact(int n) {
int result = 1;
while (n > 1) {
result = (long long)result * n % MOD;
n -= 1;
}
return result;
}
// multiply a and b modulo MOD
int modmult(int a, int b) {
return (long long)a * b % MOD;
}
// inverse of a modulo MOD
int inverse(int a) {
int x, y;
xGCD(a, MOD, x, y);
return x;
}
// binomial coefficient nCk modulo MOD
int bc(int n, int k)
{
return modmult(modmult(modfact(n), inverse(modfact(k))), inverse(modfact(n - k)));
}
Just use the fact that
(n, k) = n! / k! / (n - k)! = n*(n-1)*...*(n-k+1)/[k*(k-1)*...*1]
so you actually have just 2*k=2*10^5 factors. For the inverse of a number you can use suggestion of kfx since your m is prime.
First, you don't need to pre-compute and store all the possible aCb values! they can be computed per case.
Second, for the special case when (k < m) and (n < m^2), the Lucas theorem easily reduces to the following result:
(n choose k) mod m = ((n mod m) choose k) mod m
then since (n mod m) < 10^9+7 you can simply use the code proposed by #kfx.
We want to compute nCk (mod p). I'll handle when 0 <= k <= p-2, because Lucas's theorem handles the rest.
Wilson's theorem states that for prime p, (p-1)! = -1 (mod p), or equivalently (p-2)! = 1 (mod p) (by division).
By division: (k!)^(-1) = (p-2)!/(k!) = (p-2)(p-3)...(k+1) (mod p)
Thus, the binomial coefficient is n!/(k!(n-k)!) = n(n-1)...(n-k+1)/(k!) = n(n-1)...(n-k+1)(p-2)(p-3)...(k+1) (mod p)
Voila. You don't have to do any inverse computations or anything like that. It's also fairly easy to code. A couple optimizations to consider: (1) you can replace (p-2)(p-3)... with (-2)(-3)...; (2) nCk is symmetric in the sense that nCk = nC(n-k) so choose the half that requires you to do less computations.

Prolog Assignment

This is the question for one of my assignments:
Write repCount(L, X, N) which is true when N is the number of occurrences of X in list L.
Here's my code where I try to tackle the problem recursively:
repCount([], X, N) :-
N is 0.
repCount([H|T], X, N) :-
count([H|T], X, N).
count([], X, 0).
count([H|T], X, N) :-
count(T, X, N1),
X =:= H,
N is N1 + 1.
And it works when I supply a list full of identical numbers like this:
?- repCount([2,2,2], 2, N).
N = 3.
But if I supply a list with at least one different value:
?- repCount([2,2,22], 2, N).
false.
It returns false. I cannot figure out why this happens or how to change it to 'skip' the non-matching value, rather than declare the whole thing false. Any input is appreciated.
count([H|T], X, N):- count(T, X, N1), X=:=H, N is N1 + 1.
here you declare that N should be N1+1 if X is H; however you do not define what should happen if X is not H (basically missing an else clause)
this should work:
count([H|T], X, N):-
count(T, X, N1),
(X=:=H->
N is N1 + 1
; N is N1).
another way would be:
count([H|T], X, N):- count(T, X, N1), X=:=H, N is N1 + 1.
count([H|T], X, N):- X=\=H, count(T, X, N1), N is N1.
but this is inefficient since count(T,X,N1) will be called twice if X is not H. we can fix this by doing the check in the head of the clause:
count([H|T], H, N):- count(T, X, N1), N is N1 + 1.
count([H|T], X, N):- count(T, X, N1), N is N1.
or simply:
count([H|T], H, N):- count(T, X, N1), N is N1 + 1.
count([H|T], X, N1):- X=\=H, count(T, X, N1).
One maybe interesting addition to what #magus wrote: If you only care about the number of elements instead of the elements themselves, you can use findall/3 like this:
list_elem_num(Ls, E, N) :-
findall(., member(E, Ls), Ds),
length(Ds, N).
Preserve logical-purity—with a little help from
meta-predicate tcount/3 and (=)/3!
The goal tcount(=(X),Es,N) reads "there are N items in list Es that are equal to X".
Sample query:
?- tcount(=(X), [a,b,c,a,b,c,a,b,a], N).
( N = 4, X=a
; N = 3, X=b
; N = 2, X=c
; N = 0, dif(X,a), dif(X,b), dif(X,c)
). % terminates universally
But assuming you aren't allowed to 'cheat', if you want to use recursion, you don't need to do the '==' comparison.. you can use Prolog's variable unification to reach the same end:
% Job done all instances
repCount2([], _, 0).
% Head unifies with X/2nd parameter - ie X found
repCount2([H|T], H, N) :-
repCount2(T, H, NewN),
N is NewN + 1.
% We got here, so X not found, recurse around
repCount2([_|T], X, N) :-
repCount2(T, X, N).
In the second predicate, H is mentioned twice, meaning that if the Head of the list is the same as X, then recurse down, then add 1 to the result of the rest of the recursion (which ends in adding 0 - the base case, which is how the accumulator is built).
Almost there...you need to use an accumulator, thus:
repCount(Xs,Y,N) :-
count(Xs,Y,0,N) % the 3rd argument is the accumulator for the count, which we seed as 0
.
count([],_,N,N). % if the list is empty, unify the accumulator with the result
count([X|Xs],Y,T,N) :- % if the list is non-empty,
X == Y , % and the head of the list (X) is the the desired value (Y),
T1 is T+1 , % then increment the count, and
count(Xs,Y,T1,N) % recurse down, passing the incremented accumulator
. %
count([X|Xs],Y,T,N) :- % if the list is non-empty,
X \== Y , % and the head of the list(X) is not the desired value (Y),
count(Xs,Y,T,N) % simply recurse down
. %
The original question didn't say whether there were constraints on which predicates you could use.
If you are allowed to 'cheat' ie. use higher order predicates like 'findall' that recurse for you Vs you doing the recursion yourself, this can be done in a single predicate:
repCount(L, X, N) :-
findall(X, member(X, L), ListOfX),
length(ListOfX, N).