I am working with the math-classes library in Coq. This library makes a clever use of type classes to overload notations, like this.
(* From math-classes *)
Class Equiv A := equiv : relation A.
Infix "=" := equiv : type_scope.
(* My code *)
Definition MyDataType : Type := ...
Definition MyEquality (x y : MyDataType) : Prop := ...
Instance MyEq_equiv : Equiv MyDataType := MyEquality.
I can define such instances for many different datatypes, and x = y will
be understood as the equality I have registered for the type of x and y thanks to the instance resolution mechanism.
However, dealing with these equalities in proofs is a bit annoying because I have to unfold many successive definitions:
Lemma MyEquality_refl : forall x : MyDataType, x = x.
Proof.
intro.
unfold equiv, MyEq_equiv, MyEquality.
...
Qed.
Is there a more efficient way to do this unfold?
(1) You could use a custom tactic:
(* unfolds only in the goal *)
Ltac unfold_equiv := unfold equiv, MyEq_equiv, MyEquality.
(* unfolds in the goal and in the context *)
Ltac unfold_equiv_everywhere := unfold equiv, MyEq_equiv, MyEquality in *.
Lemma MyEquality_refl : forall x : MyDataType, x = x.
Proof.
intro.
unfold_equiv. (* or `unfold_equiv_everywhere.` *)
...
Qed.
(2) You could use the hint databases. Just add your definitions with Hint Unfold to the databases.
Hint Unfold equiv MyEq_equiv MyEquality.
(* a couple more convenient pseudonyms *)
Ltac unfold_selected := repeat autounfold with *.
Ltac unfold_selected_everywhere := repeat autounfold with * in *.
Lemma MyEquality_refl : forall x : MyDataType, x = x.
Proof.
intro.
unfold_selected. (* or just literally `repeat autounfold with *.` *)
...
Qed.
Related
Suppose I have the following type system:
Type :=
A ; type of A
B ; type of B
C ; type of C
Int ; type of int
Real ; type of real
v :=
abc ; value of abc
real ; value of real
int ; value of int
t :=
v ; values can be mapped to terms
<abc_0, abc_1,... abc_n> = break abc' into int ; this will break abc' into real parts (think of this as a generic partitioning or division operation.
abc = op abc' for int ;
+ ; math plus operator, assume this "works" for types A|B|C, and works as expected for Int|Real
Suppose that the body of op and break is as such:
; op return type could, maximally, be the union of x, y, z, or minimally be the union types of x, y or x, z
op(x, y): ; recall, x:{A|B|C} and y:{A|B|C}
A z;
while([some condition]):
if ([another condition]):
x += y
else:
x += z
return x
break(x, y):
; For simplicity, this can just return an array of y-size, whose type is that of x
; in implementation this is much more complicated than this, but for simplicity this suffices to articulate the concept.
return array[y];
Now I'm given this program, with dynamic typing:
a = ... ; this is of {A|B|C}
x = 5 ; typeof Int
b = op a for x
c = break b into x
I need to prove the satisfiability of this program, using Z3.
I'm really not sure how to represent this program in z3. The union typing, I think can be handled by the custom datatypes below. But I am unclear how to handle loops/conditionals. Just as in sentential logic, do they translate to forall or there exists at least one quantifiers?
(declare-datatypes () ((Type A B C)))
(define-sort Set (T) (Array T Type))
(declare-fun break_func (Type Real) (Set Type))
; not sure if this is correct or not...
(declare-fun op_func (Type Real) (Set Type))
(declare-const a Type)
(declare-const x Int)
; not quite sure what to put my for asserts....
; should I assert that the size of the break_func matches the input? If so, how
; I don't understand how to type check the output for op_func
(check-sat)
(get-model)
My main questions, aside from "is this correct" is that:
The Z3 implementation of this isn't a full representation of the program, but I don't understand what asserts I should be using for my Z3 implementation for this use-case
I don't understand how to account for union typing in Z3?
I am trying to define two instances of a type class, one of which will use the other's instance. However, unless I bind the function's name outside of the second definition Coq is unable to determine it should use the type class instance from bexp (take a look at the comment for dirty hack). Is there a way to avoid this sort of hack in Coq?
Class Compilable ( A : Type ) := { compile : A -> bool }.
Inductive cexp : Type :=
| CAnd : cexp -> cexp -> cexp
| COr : cexp -> cexp -> cexp
| CProp : bexp -> cexp.
Instance: Compilable bexp :=
{ compile :=
fix compile b :=
match b with
(* elided *)
end
}.
Definition compile2 := compile.
Instance: Compilable cexp :=
{ compile :=
fix compile c :=
match c with
| CAnd x y => (compile x) && (compile y)
| COr x y => (compile x) || (compile y)
| CProp e => (compile2 e) (* <-- dirty hack *)
end
}.
This can be fixed if we replace compile with some other name (rec) like so:
Instance: Compilable cexp :=
{ compile :=
fix rec c :=
match c with
| CAnd x y => (rec x) && (rec y)
| COr x y => (rec x) || (rec y)
| CProp e => (compile e)
end
}.
In this comment the OP pointed out that Haskell easily deals with this situation. To understand the reason why Coq does not do it let us take a look at the type of compile:
About compile.
compile : forall A : Type, Compilable A -> A -> bool
Arguments A, Compilable are implicit and maximally inserted
We can see that Coq is more explicit about how typeclasses work. When you call compile e Coq sort of inserts placeholders standing for the implicit arguments like so #compile _ _ e (see these slides, pages 21-25 for more detail). But with fix compile c you shadowed the previous binding, hence the type error.
I have a list
data List (X : Set) : Set where
<> : List X
_,_ : X -> List X -> List X
a definition for equality
data _==_ {l}{X : Set l}(x : X) : X -> Set l where
refl : x == x
and congruence
cong : forall {k l}{X : Set k}{Y : Set l}(f : X -> Y){x y} -> x == y -> f x == f y
cong f refl = refl
I am trying to prove
propFlatten2 : {X : Set } ( xs0 : List X ) (x : X) (xs1 : List X) (xs2 : List X)
-> ( xs0 ++ x , xs1 ) ++ xs2 == xs0 ++ (x , xs1 ++ xs2 )
propFlatten2 <> x xs1 xs2 = refl
propFlatten2 (x , xs0) x₁ xs1 xs2 = cong (λ l -> x , l) {!!}
Is there a better way to use directly the constructor _,_ other than through a lambda in the last line ?
Agda doesn't have any special syntax for partial application of operators. You can, however, use the operators in their usual prefix version:
x + y = _+_ x y
This is convenient when you need to partially apply leftmost argument(s):
_+_ 1 = λ x → 1 + x
When you need to partially apply arguments going from the right, your options are more limited. As mentioned in the comments, you could use one of the convenience functions such as flip (found in Function):
flip f x y = f y x -- Type omitted for brevity.
And then simply flip the arguments of _+_:
flip _+_ 1 = λ x → x + 1
Sometimes you find operators whose only purpose is to make the code a bit nicer. Best example I can think of is probably Data.Product.,_. When you write a dependent pair (Data.Product.Σ), sometimes the first part of the pair can be filled in automatically. Instead of writing:
_ , x
You can just write:
, x
It's hard to say when writing a specialized operator such as the one above is actually worth it; if your only use case is using it with congruence, I'd just stick with the lambda since it makes it very clear what's going on.
I want to describe the integers:
data Integer : Set where
Z : Integer
Succ : Integer -> Integer
Pred : Integer -> Integer
?? what else
The above does not define the Integers. We need Succ (Pred x) = x and Pred (Succ x) = x. However,
spReduce : (m : Integer) -> Succ (Pred m) = m
psReduce : (m : Integer) -> Pred (Succ m) = m
Can't be added to the data type. A better definition of the integers is most certainly,
data Integers : Set where
Pos : Nat -> Integers
Neg : Nat -> Integers
But I am curious if there is a way to add equations to a datatype.
I'd go about it by defining a record:
record Integer (A : Set) : Set where
constructor integer
field
z : A
succ : A -> A
pred : A -> A
spInv : (x : A) -> succ (pred x) == x
psInv : (x : A) -> pred (succ x) == x
This record can be used as a proof that a certain type A behaves like an Integer should.
It seems that what you'd like to do is define your Integers type as a quotient type by the equivalence relation that identifies Succ (Pred m) with m, etc. Agda doesn't support that anymore -- there was an experimental library that tried to do that (by forcing all functions over a quotient type to be defined via a helper function that requires proof of representational invariance), but then someone discovered that the implementation wasn't watertight enough and so could lead to inconsistencies (basically by accessing one of its postulates that was supposed to be inaccessible from the outside), for the details you can see this message:
We were not sure if this hack was sound or not. Now, thanks to Dan
Doel, I know that it isn't.
[...]
Given these observations it is easy to prove that the postulate above
is unsound:
I think your best bet at the moment (if you want to/need to stick to a loose representation with an equivalency to tighten it up) is to define a Setoid for your type..
I am currently experimenting with F#. The articles found on the internet are helpful, but as a C# programmer, I sometimes run into situations where I thought my solution would help, but it did not or just partially helped.
So my lack of knowledge of F# (and most likely, how the compiler works) is probably the reason why I am totally flabbergasted sometimes.
For example, I wrote a C# program to determine perfect numbers. It uses the known form of Euclids proof, that a perfect number can be formed from a Mersenne Prime 2p−1(2p−1) (where 2p-1 is a prime, and p is denoted as the power of).
Since the help of F# states that '**' can be used to calculate a power, but uses floating points, I tried to create a simple function with a bitshift operator (<<<) (note that I've edit this code for pointing out the need):
let PowBitShift (y:int32) = 1 <<< y;;
However, when running a test, and looking for performance improvements, I also tried a form which I remember from using Miranda (a functional programming language also), which uses recursion and a pattern matcher to calculate the power. The main benefit is that I can use the variable y as a 64-bit Integer, which is not possible with the standard bitshift operator.
let rec Pow (x : int64) (y : int64) =
match y with
| 0L -> 1L
| y -> x * Pow x (y - 1L);;
It turns out that this function is actually faster, but I cannot (yet) understand the reason why. Perhaps it is a less intellectual question, but I am still curious.
The seconds question then would be, that when calculating perfect numbers, you run into the fact that the int64 cannot display the big numbers crossing after finding the 9th perfectnumber (which is formed from the power of 31). I am trying to find out if you can use the BigInteger object (or bigint type) then, but here my knowledge of F# is blocking me a bit. Is it possible to create a powerfunction which accepts both arguments to be bigints?
I currently have this:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| bigint.Zero -> 1I
| y -> x * Pow x (y - 1I);;
But it throws an error that bigint.Zero is not defined. So I am doing something wrong there as well. 0I is not accepted as a replacement, since it gives this error:
Non-primitive numeric literal constants cannot be used in pattern matches because they
can be mapped to multiple different types through the use of a NumericLiteral module.
Consider using replacing with a variable, and use 'when <variable> = <constant>' at the
end of the match clause.
But a pattern matcher cannot use a 'when' statement. Is there another solution to do this?
Thanks in advance, and please forgive my long post. I am only trying to express my 'challenges' as clear as I can.
I failed to understand why you need y to be an int64 or a bigint. According to this link, the biggest known Mersenne number is the one with p = 43112609, where p is indeed inside the range of int.
Having y as an integer, you can use the standard operator pown : ^T -> int -> ^T instead because:
let Pow (x : int64) y = pown x y
let PowBigInt (x: bigint) y = pown x y
Regarding your question of pattern matching bigint, the error message indicates quite clearly that you can use pattern matching via when guards:
let rec PowBigInt x y =
match y with
| _ when y = 0I -> 1I
| _ -> x * PowBigInt x (y - 1I)
I think the easiest way to define PowBigInt is to use if instead of pattern matching:
let rec PowBigInt (x : bigint) (y : bigint) =
if y = 0I then 1I
else x * PowBigInt x (y - 1I)
The problem is that bigint.Zero is a static property that returns the value, but patterns can only contain (constant) literals or F# active patterns. They can't directly contain property (or other) calls. However, you can write additional constraints in where clause if you still prefer match:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| y when y = bigint.Zero -> 1I
| y -> x * PowBigInt x (y - 1I)
As a side-note, you can probably make the function more efficent using tail-recursion (the idea is that if a function makes recursive call as the last thing, then it can be compiled more efficiently):
let PowBigInt (x : bigint) (y : bigint) =
// Recursive helper function that stores the result calculated so far
// in 'acc' and recursively loops until 'y = 0I'
let rec PowBigIntHelper (y : bigint) (acc : bigint) =
if y = 0I then acc
else PowBigIntHelper (y - 1I) (x * acc)
// Start with the given value of 'y' and '1I' as the result so far
PowBigIntHelper y 1I
Regarding the PowBitShift function - I'm not sure why it is slower, but it definitely doesn't do what you need. Using bit shifting to implement power only works when the base is 2.
You don't need to create the Pow function.
The (**) operator has an overload for bigint -> int -> bigint.
Only the second parameter should be an integer, but I don't think that's a problem for your case.
Just try
bigint 10 ** 32 ;;
val it : System.Numerics.BigInteger =
100000000000000000000000000000000 {IsEven = true;
IsOne = false;
IsPowerOfTwo = false;
IsZero = false;
Sign = 1;}
Another option is to inline your function so it works with all numeric types (that support the required operators: (*), (-), get_One, and get_Zero).
let rec inline PowBigInt (x:^a) (y:^a) : ^a =
let zero = LanguagePrimitives.GenericZero
let one = LanguagePrimitives.GenericOne
if y = zero then one
else x * PowBigInt x (y - one)
let x = PowBigInt 10 32 //int
let y = PowBigInt 10I 32I //bigint
let z = PowBigInt 10.0 32.0 //float
I'd probably recommend making it tail-recursive, as Tomas suggested.