Checking for items in a MiniZinc array - minizinc

I want to create two arrays in MiniZinc with the same items, not necessarily in the same order. Here, every item in A0 should also be in A1:
array[1..3] of var int:A0;
array[1..3] of var int:A1;
constraint forall(A2 in A0)(
(A2 in A1) /\ A2 < 5
);
But here, there seems to be a type error:
MiniZinc: type error: type error in operator application for `'in''. No matching operator found with left-hand side type `var int' and right-hand side type `array[int] of var int'
How is it possible to check if an array contains the same item that is in another array?

Edit: There is an array2set in the file builtins.mzn but it is not documented in https://www.minizinc.org/doc-2.4.2/ .
The following model works for most FlatZinc solvers such as Gecode, Google-OR-tools, Choco, PicatSAT, and JaCoP, but not for Chuffed (see below). Note the include of "nosets.mzn" so that solvers without innate support for set variables can run the model. Also, I added a smaller domain of A0 and A1 for easier testing.
include "nosets.mzn"; % Support for set variables for all solvers
array[1..3] of var 0..10: A0;
array[1..3] of var 0..10: A1;
constraint
forall(A2 in A0)(
A2 in array2set(A1) /\ A2 < 5
)
/\
forall(A2 in A1)(
A2 in array2set(A0) /\ A2 < 5
);
solve satisfy;
output [ "A0: \(A0) A1: \(A1)\n" ];
However, some solvers don't like this:
Chuffed: Throws "Error: Registry: Constraint bool_lin_eq not found in line no. 101"
Even later note: If the domains is var int (instead of my var 0..10) then MiniZinc croaks with a weird (and long) error:
...
in array comprehension expression
comprehension iterates over an infinite set
So array2set seems to require that the variable domains must be bounded.
This is the first answer
Here is an approach that seems to work, i.e. using exists and check for element equality:
constraint forall(A2 in A0)(
exists(i in 1..3) ( A2 = A1[i] /\ A2 < 5)
);
Note: This constraint only ensures that the elements in A0 is in A1. Thus there might be elements in A1 that is not in A0. E.g.
A0: [1,1,4]
A1: [1,4,3]
I guess that you also want the converse i.e. that all elements in A1 is in A0 as well:
constraint forall(A2 in A1) (
exists(i in 1..3) ( A2 = A0[i] /\ A2 < 5)
);
Note: The following DOES NOT work but would be nice to have. Both yield the error MiniZinc: internal error: var set comprehensions not supported yet.
% idea 1
constraint forall(A2 in A0)(
A2 in {A1[i] | i in 1..3} /\ A2 < 5
);
% idea 2
constraint forall(A2 in A0) (
A2 in {a | a in A1} /\ A2 < 5
);

Related

Good way of testing a class in Coq

Is there a good way to test the implementation of a class in Coq ?
For example, if I have the following very simple Class:
Theorem chekc_modulo (c: nat): {c mod 2 = 0} + {c mod 2 <> 0} .
Admitted.
Definition update(n: nat):= add n one.
Class test :={
f: R -> nat;
g: R -> nat;
counting: nat;
init: counting = zero /\ f 0 = 0 /\ g 0 = 0;
output: forall t, t >= 0 ->
match chekc_modulo counting with
|left _ => f t = 1 /\ g t = 0 /\ update counting
|right _ => g t = 1 /\ g t = 0 /\ update counting
end
}.
I would like to find a way to test this class, so basically to check that f and g have the required values after processing the output.
What I did so far: I manually implemented f and g by giving them the values I expect they will have at a given t, after processing in output. And now I try to create an instance of the Class test to see what happens with the output.
I am a bit stuck because i do not see how to get the actual output and therefore how to check that the implementation is actually correct.
Does anyone have a tip ? In general, is there a better way to test code in Coq, especially Classes ?
EDIT:
In my testing strategy, I have defined the expected behavior of f and g:
Definition f': nat -> nat :=
fun t =>
match chekc_modulo t with
|left _ => 1
|right _ => 0
end.
Definition g': nat -> nat :=
fun t =>
match chekc_modulo t with
|left _ => 0
|right _ => 1
end.
So the next step, would be to check that this behavior is indeed the same as what happens after output is processed.
For testing Coq code, you might find the QuickChick plugin useful. It allows you to write properties that your definitions should satisfy, and generates random test cases to check if they hold. In principle, it should work fine with type classes as well.
However, given your code snippet, I have the impression that there is some misunderstanding about what classes in Coq are. For instance, the assertion counting = counting + 1 suggests that you are trying to update the value of counting somehow. In Coq, it is not possible to update the value of a variable: the assertion counting = counting + 1 means that the number counting equals its successor, which is impossible.
I don't know if this helps, but classes in Coq are closer to type classes in Haskell than to classes in object-oriented languages such as Java, and an "instance" of a class is more similar to a class that implements a Java interface than an object that is an instance of a class.
Perhaps we could provide more help if you gave us more context about what you are trying to do.

Notations in Coq

I want to use the notations to represent the predicate test as follows:
Variable A B : Type.
Inductive test : A -> B -> A -> B -> Prop :=
| test1 : forall a1 a2 b1 b2,
a1 \ b1 || a2 \ b2
where "c1 '\' st '||' c2 '\' st'" := (test c1 st c2 st')
.
However, the Coq has an error:
Why this notation cannot be accepted in Coq?
The notation is accepted, it's actually that Coq is incorrectly parsing your use of the notation within the definition of test1. To correctly parse this notation you need to adjust the parsing levels of its terms. You can do that with a reserved notation, since these where clauses for notation within an inductive don't support the syntax for configuring the notation:
Variable A B : Type.
Reserved Notation "c1 '\' st '||' c2 '\' st'" (at level 40, st at next level, c2 at next level, no associativity).
Inductive test : A -> B -> A -> B -> Prop :=
| test1 : forall a1 a2 b1 b2,
a1 \ b1 || a2 \ b2
where "c1 '\' st '||' c2 '\' st'" := (test c1 st c2 st')
.
I don't have a good intuition for what parsing levels work well (40 is somewhat arbitrary above), so the best advice I can give is to experiment and if it's parsed incorrectly somewhere then try adjusting the level.

cannot show result from an instance function in haskell

class (Eq k, Ord k, Show k) => KEY k where
keyBuild :: NumId -> NumId -> NumId -> k
keyDummy :: k
keyFromList :: [NumId] -> k
-- keyGenerate :: (DATAPOOL p) => p -> Int -> [k] -- p = Pool k e s
newtype PrimaryKey = PK (NumId, NumId, NumId) deriving (Eq, Ord, Show)
instance KEY PrimaryKey where
keyBuild k0 k1 k2 = PK (k0,k1,k2)
keyDummy = PK (0,0,0)
keyFromList is = keyFromList (take 3 (is ++ (replicate 3 0)))
keyGenerate p cnt = let
ks = keys p
pks = map (\l -> keyFromList (randomize l)) (replicate cnt 3)
in pks
in ghci I do
let k1 = keyBuild 1 2 3
let k2 = PK (1,2,3)
k1 == k2
True
k2
PK (1,2,3)
and get True and the value of k2 as expected, but
k1
231:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘it’
prevents the constraint ‘(KEY a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instance exist:
instance [safe] KEY PrimaryKey -- Defined at Work
Expected PK(1,2,3)
PrimaryKey has deriving (Eq, Ord, Show) so what have I done wrong or missed?
You have not given k1 a fixed type. Because keyBuild can construct a key of any type with the right instance, it has the polymorphic type k1 :: KEY k => k. That's nice because you can then compare k1 to keys of different concrete types... in your case, you've tried it with k2 :: PrimaryKey, but you could just as well do k1 == k3 with k3 :: SomeOtherKeyType, provided SomeOtherKeyType is also an instance of the KEY class – in that case, k1 would simply also “take over” the type SomeOtherKeyType.
The flip side is that k1 has no particular type. It may in fact be any applicable type, but how is the compiler supposed to know which you want? When using == it must be the same type on both sides, so there it's sufficient to have a concrete type on one side, but all by itself k1 is ambiguous.
It so happens that in your module there is only one instance that matches, namely KEY PrimaryKey but in general there would be many (or zero!) such instances. It would be strange if the compiler just picked one arbitrarily, wouldn't it?
So if you want to show k1, you need to manually pick one type. Easy enough to do, just add a local signature:
*Main> let k1 = keyBuild 1 2 3
*Main> :t k1
k1 :: KEY k => k
*Main> k1 :: PrimaryKey
PK (1,2,3)

Implementing an interface for a plain old recursive data type

I'm fighting with Idris syntax, it seems.
module Test
data Nat = Z | S Nat
Eq Nat where
Z == Z = True
S n1 == S n2 = n1 == n2
_ == _ = False
This complains with the following error (v1.1.1):
.\.\Test.idr:5:8: error: expected: "#",
"with", argument expression,
constraint argument,
function right hand side,
implicit function argument,
with pattern
Eq Nat where
^
Type checking .\.\Test.idr
I don't understand why, I basically used the same syntax as the docs.
When I write an Eq implementation for a custom, non-recursive type, such as Bool, it compiles just fine.
You need to wrap S n patterns in parenthesis. After doing that, your will get compiler errors because Nat is already defined in Prelude. So to compile your code just replace Nat with Natural (or anything else). Though, Z and S constructors are also defined in Prelude so you either need to rename everything to be able to test in REPL easily or use %hide directive.
But at least this code compiles:
module Test
data Natural = Z | S Natural
Eq Natural where
Z == Z = True
(S n1) == (S n2) = n1 == n2
_ == _ = False

[AMPL]Impose a sum to be equal to the number of elements

I'm trying to impose a simple constrain that however doesn't work in any way I try. I'd to impose:
subject to myConstrain:
sum { a1 in A, a2 in A } myVar[a1,a2] = *<<<number of elements of the set A>>>*
How can I do that? Is there a function to use? I try in this way but it doesn't work.
subject to myConstrain:
sum { a1 in A, a2 in A } myVar[a1,a2] = sum {a in A} 1;
Thanks
You can write such constraint as follows:
subject to myConstrain:
sum{a1 in A, a2 in A} myVar[a1, a2] = card(A);