MiniZinc: syntax error: syntax error, unexpected if, expecting end of file - minizinc

I don't know why my code doesn't work in Minizinc... Can you help me?
This is the error but i think there are another errors:
MiniZinc: syntax error: syntax error, unexpected if, expecting end of file
array [1..n, 1..2] of 1..n: cards;
var int: M1;
var int: M2;
var int: m1;
include "globals.mzn";
constraint(M1 < m1);
constraint(M2 > m1);
constraint(M2 - M1 > d);
constraint alldifferent ( [cards[v,1] | v in 1..n]);
constraint forall(v in 1..M1) if v!=0 then (cards[v,2] > cards[v-1,2]) endif;
constraint forall(v in M1+1..m1)(cards[v,2] < cards[v-1,2]);
constraint forall(v in m1+1..M2)(cards[v,2] > cards[v-1,2]);
constraint forall(v in m1+1..n) if v!=n then (cards[v,2] < cards[v-1,2]) endif;
solve satisfy;
output
["Cards (" ++ show(cards[v1,v2]) ++ ")" ++ "/n" | v1 in 1..n, v2 in 1..2];

The first problem is that forall is looking for its expression clause, from the Minizinc documentation <ident-or-quoted-op> "(" <comp-tail> ")" "(" <expr> ")", wrap the whole if in parenthesis, like this constraint forall(v in m1+1..n)(if v!=n then (cards[v,2] < cards[v-1,2]) endif);
Upon fixing that you will find that the model still fails, MiniZinc: evaluation error: comprehension iterates over an infinite set, because the variables M1, m1, M2 have no bounds given by their definitions and their constraints don't restrict the domains, so M2 > m1 > M1 and M2 - M1 < d, gives no upper bound for M2 or lower for M1, and makes Minizinc try all the values in the domain of int for one of the variables and test the other with values within a gap of d (check variable-bounds), try bounding the variables from their definition, something like var 1..x, where x might be the maximum value any of those variables could take in a solution that still makes sense, from the forall definitions it seems like you consider that m1+1 <= n, so maybe use n as the upper bound.
From constraint forall(v in 1..M1) if v!=0 then (cards[v,2] > cards[v-1,2]) endif; you can eliminate if v!=0 if M1 > 0, because v will never take that value, and rightly so, because if M1 < 0 the model will access out of the bounds of the array (if the model compiles at all), because all the indices of cards are positive [1..n, 1..2]. And if all of that applies, also (v in 1..M1) will make another array access out of bounds when v=1 at cards[v-1,2], perhaps your model still makes sense to you using constraint forall(v in 2..M1)(cards[v,2] > cards[v-1,2]);
Finally, you have cards in an alldifferent constraint, but cards is not declared as a variable, if cards really is a decision variable use array [1..n, 1..2] of var 1..n: cards;
I tested this modified version of you model and got a feasible solution.
int: n = 5;
int: d = 3;
array [1..n, 1..2] of var 1..n: cards;
var 1..n: M1;
var 1..n: M2;
var 1..n: m1;
include "globals.mzn";
constraint(M1 < m1);
constraint(M2 > m1);
constraint(M2 - M1 > d);
constraint alldifferent ( [cards[v,1] | v in 1..n]);
constraint forall(v in 2..M1)(cards[v,2] > cards[v-1,2]);
constraint forall(v in M1+1..m1)(cards[v,2] < cards[v-1,2]);
constraint forall(v in m1+1..M2)(cards[v,2] > cards[v-1,2]);
constraint forall(v in m1+1..n)(if v!=n then (cards[v,2] < cards[v-1,2]) endif);
solve satisfy;
output
["Cards (" ++ show(cards[v1,v2]) ++ ")" ++ if v2 != 2 then ", " else "\n" endif | v1 in 1..n, v2 in 1..2];
Cards (5), Cards (4)
Cards (4), Cards (3)
Cards (3), Cards (2)
Cards (2), Cards (1)
Cards (1), Cards (2)

Related

MiniZinc: build a connectivity matrix

In MiniZinc, I have an array of boolean representing an oriented connection between nodes of a graph:
array[Variants,Variants] of bool : VariantIsDirectlyUpwardOf;
VariantIsDirectlyUpwardOf[v1,v2] = true if there is an oriented arc "v1 -> v2".
now I want to build
array[Variants,Variants] of bool VariantIsUpwardOf;
where VariantIsUpwardOf[v1,v2] = true if there is an oriented path "v1 -> ... -> v2" where "..." is a sequence of nodes defining an oriented path of any length going from v1 to v2.
My first try was to define a transitive kind of constraint
array[Variants,Variants] of var bool : VariantIsUpwardOf;
constraint forall (v1 in Variants, v2 in Variants)(VariantIsDirectlyUpwardOf[v1,v2]->VariantIsUpwardOf[v1,v2]);
constraint forall (v1 in Variants, v2 in Variants, v3 in Variants)( VariantIsUpwardOf[v1,v2] /\ VariantIsUpwardOf[v2,v3] -> VariantIsUpwardOf[v1,v3]);
but I think this is incorrect because if all values of VariantIsUpwardOf[v1,v2] were true, then my constraints would be satisfied and the result would be incorrect.
Following the comment (thanks Axel), I made a second unsuccessful test using predicate dpath, here is my very basic test calling dpath::
include "path.mzn";
enum MyNodes={N1,N2};
array [int] of MyNodes: EdgeFrom=[N1];
array [int] of MyNodes: EdgeTo= [N2];
array [MyNodes] of bool: NodesInSubGraph = [true, true];
array [int] of bool: EdgesInSubGraph = [true];
var bool : MyTest = dpath(EdgeFrom,EdgeTo,N1,N2,NodesInSubGraph,EdgesInSubGraph);
output [show(MyTest)];
it produces the following error:
Running MiniTest.mzn
221msec
fzn_dpath_enum_reif:3.3-52
in call 'abort'
MiniZinc: evaluation error: Abort: Reified dpath constraint is not supported
Process finished with non-zero exit code 1.
Finished in 221msec.
The following MiniZinc model demonstrates the usage of the dpath() predicate to find a directed path in a graph.
I took the directed graph from Wikipedia as example:
The model:
include "globals.mzn";
int: Nodes = 4;
bool: T = true; % abbreviate typing
bool: F = false;
set of int: Variants = 1..Nodes;
% VariantIsDirectlyUpwardOf[v1,v2] = true if there is an oriented arc "v1 -> v2".
% Example from https://en.wikipedia.org/wiki/Directed_graph
array[Variants,Variants] of bool : VariantIsDirectlyUpwardOf =
[| F, T, T, F,
| F, F, F, F,
| F, T, F, T,
| F, F, T, F |];
% count the number of Edges as 2D array sum
int: NoOfEdges = sum(VariantIsDirectlyUpwardOf);
set of int: Edges = 1..NoOfEdges;
% for dpath(), the graph has to be represented as two
% 'from' 'to' arrays of Nodes
% cf. https://www.minizinc.org/doc-2.6.4/en/lib-globals-graph.html
array[Edges] of Variants: fromNodes =
[row | row in Variants, col in Variants
where VariantIsDirectlyUpwardOf[row, col]];
array[Edges] of Variants: toNodes =
[col | row in Variants, col in Variants
where VariantIsDirectlyUpwardOf[row, col]];
% arbitrary choice of Nodes to be connected by a directed path
Variants: sourceNode = 4;
Variants: destNode = 2;
% decision variables as result of the path search
array[Variants] of var bool: nodesInPath;
array[Edges] of var bool: edgesInPath;
constraint dpath(fromNodes, toNodes, sourceNode, destNode, nodesInPath, edgesInPath);
% determine next node after nd in path
function int: successor(int: nd) =
min([s | s in Variants, e in Edges where
fix(nodesInPath[s]) /\ fix(edgesInPath[e]) /\
(fromNodes[e] = nd) /\ (toNodes[e] = s)]);
function string: showPath(int: nd) =
if nd = destNode then "\(nd)" else "\(nd)->" ++ showPath(successor(nd)) endif;
output [showPath(sourceNode)];
Resulting output:
4->3->2

Dafny no terms to trigger on predicate

I have the following snippet Dafny code for a tic tac toe game to check if player 1 has a winning row on the board:
predicate isWinRowForPlayer1(board: array2<int>)
reads board
requires board.Length0 == board.Length1 == 3 && isValidBoard(board)
{
exists i :: 0 <= i < board.Length0 ==> (forall j :: 0 <= j < board.Length1 ==> board[i, j] == 1)
}
Currently I am getting a /!\ No terms found to trigger on. error on the body of this predicate and all other predicates I have in my program (for winColumn, winDiag, ... etc)
Would appreciate if someone can help me to fix this
Here is one way to do it: introduce a helper function to hold the forall quantifier. Dafny will then use this helper function as the trigger for the outer exists quantifier, fixing the warning.
predicate RowIsWinRowForPlayer1(board: array2<int>, row: int)
reads board
requires 0 <= row < board.Length0
{
forall j :: 0 <= j < board.Length1 ==> board[row, j] == 1
}
predicate isWinRowForPlayer1(board: array2<int>)
reads board
requires board.Length0 == board.Length1 == 3 && isValidBoard(board)
{
exists i :: 0 <= i < board.Length0 ==> RowIsWinRowForPlayer1(board, i)
}
See this answer for more information about triggers.

Reduce length of the pseudo-encrypt function ouput

i have a question about the pseudo-encrypt function for postgres.
Is there any way that I can reduce the output to 6? I really like this function and want to use it, but only need a output between 1 and 999999.
This question is related to my last question. I want to use it to created unqiue numbers between 1 and 999999.
Thank you.
Use mod on the generated value to generate number in range from start_value to end_value:
select start_value + mod(pseudo_encrypt(number), end_value - start_value + 1);
For your case this will be look like:
select 1 + mod(pseudo_encrypt(23452), 999999);
It's not quite straightforward to set an upper bound of 999999, as the algorithm operates on blocks of bits, so it's hard to get away from powers of two.
You can work around this by cycle walking - just try encrypt(n), encrypt(encrypt(n)), encrypt(encrypt(encrypt(n)))... until you end up with a result in the range [1,999999]. In the interest of keeping the number of iterations to a minimum, you want to adjust the block size to get you as close to this range as possible.
This version will let you specify a range for the input/output:
CREATE OR REPLACE FUNCTION pseudo_encrypt(
value INT8,
min INT8 DEFAULT 0,
max INT8 DEFAULT (2^62::NUMERIC)-1
) RETURNS INT8 AS
$$
DECLARE
rounds CONSTANT INT = 3;
L INT8[];
R INT8[];
i INT;
blocksize INT;
blockmask INT8;
result INT8;
BEGIN
max = max - min;
value = value - min;
IF NOT ((value BETWEEN 0 AND max) AND (max BETWEEN 0 AND 2^62::NUMERIC-1)) THEN
RAISE 'Input out of range';
END IF;
blocksize = ceil(char_length(ltrim(max::BIT(64)::TEXT,'0'))/2.0);
blockmask = (2^blocksize::NUMERIC-1)::INT8;
result = value;
LOOP
L[1] = (result >> blocksize) & blockmask;
R[1] = result & blockmask;
FOR i IN 1..rounds LOOP
L[i+1] = R[i];
R[i+1] = L[i] # ((941083981*R[i] + 768614336404564651) & blockmask);
END LOOP;
result = (L[rounds]::INT8 << blocksize) | R[rounds];
IF result <= max THEN
RETURN result + min;
END IF;
END LOOP;
END;
$$
LANGUAGE plpgsql STRICT IMMUTABLE;
I can't guarantee its correctness, but you can easily show that it maps [1,999999] back to [1,999999]:
SELECT i FROM generate_series(1,999999) s(i)
EXCEPT
SELECT pseudo_encrypt(i,1,999999) FROM generate_series(1,999999) s(i)

Got "Boolean" expected "LongInt" pascal

I get this error on my insertion sort algorithm:
insertionsort.lpr(19,17) Error: Incompatible types: got "Boolean" expected "LongInt"
Here's the line 19 of my code
while j > 0 and A[j]>key do
I have tried googling all over the internet but i couldn't find any syntax errors or anything.
Here's the full code if it helps :
program instert;
uses crt;
const
N = 5;
var
i:integer;
j:integer;
key:integer;
A : Array[1..N] of Integer;
procedure insertionsort;
begin
for i := 2 to N do
begin
key := A[1];
j:= i - 1;
while j > 0 and A[j]>key do
begin
A[j+1] := A[j] ;
j := j-1;
end;
A[j+1] := key ;
end;
end;
begin
A[1]:= 9;
A[2]:= 6;
A[3]:= 7;
A[4]:= 1;
A[5]:= 2;
insertionsort;
end.
I also get the same error on the bubble sort algorithm i did. Here's the error line
bubblesort.lpr(26,14) Error: Incompatible types: got "Boolean" expected "LongInt"
Here's line 26 of my algorithm:
until flag = false or N = 1 ;
Here's the full code:
program bubblesort;
uses crt;
var
flag:boolean;
count:integer;
temp:integer;
N:integer;
A : Array[1..N] of Integer;
procedure bubblesort ;
begin
Repeat
flag:=false;
for count:=1 to (N-1) do
begin
if A[count] > A[count + 1] then
begin
temp := A[count];
A[count] := A[count + 1];
A[count] := temp;
flag := true;
end;
end;
N := N - 1;
until flag = false or N = 1 ;
end;
begin
A[1]:= 9;
A[2]:= 6;
A[3]:= 7;
A[4]:= 1;
A[5]:= 2;
N := 5;
bubblesort;
end.
In Pascal, boolean operators and and or have higher precedence than the comparison operators >, =, etc. So in the expression:
while j > 0 and A[j] > key do
Given that and has higher precedence, Pascal sees this as:
while (j > (0 and A[j])) > key do
0 and A[j] are evaluated as a bitwise and (since the arguments are integers) resulting in an integer. Then the comparison, j > (0 and A[j]) is evaluated as a boolean result, leaving a check of that with > key, which is boolean > longint. You then get the error that a longint is expected instead of the boolean for the arithmetic comparison.
The way to fix it is to parenthesize:
while (j > 0) and (A[j] > key) do ...
The same issue applies with this statement:
until flag = false or N = 1 ;
which yields an error because or is higher precedence than =. So you can parenthesize:
until (flag = false) or (N = 1);
Or, more canonical for booleans:
until not flag or (N = 1); // NOTE: 'not' is higher precedence than 'or'
When in doubt about the precedence of operators, parenthesizing is a good idea, as it removes the doubt about what order operations are going to occur.

How to convert a Maple expression x*y to Matlab for the result x.*y?

A Maple expression (for example, x^3+x*y) can be converted to Matlab by
with(CodeGeneration):
Matlab(x^3+x*y);
However, in Matlab, there are two kinds of product: A*B and A.*B. The above way will give x^3+x*y. Is there a convenient way to get the result x.^3+x.*y?
The language definition for Maple's CodeGeneration[Matlab] can be extended to handle various instances of the elementwise tilde (~) operator.
Since 'x*~y' seems to automatically simplify to `~`[`*`](x, ` $`, y), and since there appears to be a hard-coded error emitted by the presence of the name " $", then that name is substituted by NULL in the usage code below.
> restart:
> with(CodeGeneration): with(LanguageDefinition):
> LanguageDefinition:-Define("NewMatlab", extend="Matlab",
> AddFunction("`~`[`^`]", [Vector,integer]::Vector,
> proc(X,Y)
> Printer:-Print(X,".^",Y)
> end proc,
> numeric=double),
> AddFunction("`~`[`*`]", [Vector,integer]::Vector,
> proc(X,Y)
> Printer:-Print(X,".*",Y)
> end proc,
> numeric=double));
> expr:=''x^~y + x^~3 + x*~y'':
> Translate(subs(` $`=NULL, expr ), language="NewMatlab");
cg = x.^y + x.^3 + x.*y;
> p := proc(x,y)
> x^~y + x^~3 + x*~y;
> end proc:
> f := subs(` $`=NULL, eval(p) ):
> Translate(f, language="NewMatlab");
function freturn = f(x, y)
freturn = x.^y + x.^3 + x.*y;
For whatever it's worth, Maple 2015 can do this translation directly, without the extra help kindly provided by acer:
> f := (x,y)->x^~y + x^~3 + x*~y:
> CodeGeneration:-Matlab(f);
function freturn = f(x, y)
freturn = x .^ y + x .^ 3 + x .* y;
If the Matlab(x^3+x*y) expression gives out the code x^3+x*y in written format, then you can simply convert it into x.^3+x.y , just by using "Find & Replace" option of any notepad application. Just find all "" and "^" , and then replace them with ".*" and ".^" .
Hope this helps.