Transforming a inductive value into an inductive value of another type - coq

In database theory, one assumes the existence of two disjoint sets containing variables and constants.
I want to make the distinction between variables and constants at the type level of my values, using the two following inductive types:
Inductive variable :=
| var : string -> variable.
Inductive constant :=
| con : string -> constant.
I then would like to define a function mapping a variable to a constant using the same string internally.
I can reach this objective using the following definition:
Definition variable_to_constant : variable -> constant.
intros.
destruct H.
apply (con s).
Defined.
Check test.
test
: variable -> constant
Eval compute in (variable_to_constant (var "hello")).
= con "hello"
: constant
My question is: Is there a more elegant solution to define this function ? (I mean, not using the "Defined." keyword, maybe ...)
This is my first development using Coq, so if you think that my way of achieving this is wrong, please let me know :-)
Have a nice day !
Fabian Pijcke

You can simply write the code of the function directly rather than building it interactively using tactics:
Definition variable_to_constant : variable -> constant :=
fun v => match v with var str => con str end.
Or even the lighter:
Definition variable_to_constant (v : variable) : constant :=
match v with var str => con str end.

Related

Forcing evaluation of terms before extraction, or other ways to test extracted functions?

In many parts of the standard library, there are a bunch of OCaml-native functions with no Coq counterpart. I implemented a Coq version of some of them (with added proofs to show that the Coq versions behave as I think they ought to), but now how do I check that this actually matches the OCaml version's behavior?
The easiest / most "obvious" way I can think of would be to take a test input x, compute f x in Coq, and extract a comparison f x = [[f x]] (where [[…]] marks evaluation in Coq), then repeat for some number of test cases. Unfortunately, I can't find a way to force evaluation in Coq.
Is there a trick to make this possible? Or is there some other standard way for testing behavior across extraction? (Manually going Compute (f x). and plugging the resulting terms as literals back into the sanity checks would be an ugly fallback… Unfortunately, those won't update automatically when the function is changed, and it would also be a lot of manual work that doesn't exactly encourage exhaustive tests…)
Minimal sample:
Definition foo (b : bool) : bool :=
match b with | true => false | false => true end.
Extract Inlined Constant foo => "not".
Extract Inlined Constant bool_eq => "(=)".
Definition foo_true := foo true.
Definition foo_false := foo false.
Definition foo_test : bool :=
andb (bool_eq (foo true) foo_true) (bool_eq (foo false) foo_false).
Recursive Extraction foo_test.
results in
(** val foo_true : bool **)
let foo_true = not true
(** val foo_false : bool **)
let foo_false = not false
(** val foo_test : bool **)
let foo_test = (&&) ((=) (not true) foo_true) ((=) (not false) foo_false)
which is unhelpful. All the ways I could think of to change the definition of foo_true/foo_false to try and have them pre-evaluated didn't work. I can't find any flag in the extraction mechanism to force evaluation… Both the reference manual's attribute index and the flags/options/tables index didn't contain anything that looks useful. Is there anything that I missed?
Starting a definition with Eval compute in evaluates it before registering the definition.
Definition foo_true := Eval compute in foo true.
Definition foo_false := Eval compute in foo false.
Definition foo_test : bool :=
andb (bool_eq (foo true) foo_true) (bool_eq (foo false) foo_false).
Recursive Extraction foo_test.

What does the `with` keyword without the `match` do inside a inductive type in Coq?

What does the with keyword without the match do inside a inductive type in Coq?, example:
Inductive Block : Type :=
| EmptyBlk : Block
| Blk : Statement -> Block
with Statement : Type :=
| Assignment : string -> AExp -> Statement
| Seq : Statement -> Statement -> Statement
| IfElse : BExp -> Block -> Block -> Statement
| While : BExp -> Block -> Statement.
I tried checking the type of Statement and it seems its not of type block or something...So what is the point of defining it inside another inductive type rather than by itself. At least checking the type of Statement gives Set the same as for Block...
It is used to specify mutually recursive definitions. For example, consider the following two functions:
Fixpoint even (n : nat) : bool :=
match n with
| O => true
| S n => odd n
end
with odd (n : nat) : bool :=
match n with
| O => false
| S n => even n
end.
Here, you cannot define even first because it needs odd to be defined. You cannot define odd first either because it needs even. You need to be able to define both at the same time - and you do that by using the with keyword.
Your example is similar but defines inductive datatype rather than recursive function - Statement uses Block in its definition and Block uses Statement. Hence, with to define them both at the same time.
Note that this with is completely different keyword than with from the match expressions. In fact, they belong to two different languages: the former one is part of Vernacular whereas the latter is part of Gallina.

Coq: How to refer to the types generated by a specific constructor?

For example, if I define a function from nat to nat, it would be
Definition plusfive(a:nat): nat := a + 5.
However, I would like to define a function whose arguments are nats constructed using the "S" constructor (i.e. nonzero) is that possible to directly specify as a type? something like
Definition plusfive(a: nat.S): nat := a + 5.
(I know that for this case I could also add an argument with a proof that a is nonzero, but I am wondering if it is possible to directly name the type based on the 'S' constructor).
Functions have to be complete, so you will have to use some subtype instead of nat, or add an argument that reduces input space, for instance (H: a<>0)
Definition plusfive(a:nat) (H:a<>0) :=
match a as e return a=e -> _ with
| S _ => fun _ => a + 5
| _ => fun H0 => match (H H0) with end
end eq_refl.
However, these kinds of tricks have been discovered to be very cumbersome to work with in large developments, and often one instead uses complete functions on the base type that return dummy values for bad input values, and prove that the function is called with correct arguments separately from the function definition. See for example how division is defined in the standard library.
Require Import Nat.
Print div.
div =
fun x y : nat => match y with
| 0 => y
| S y' => fst (divmod x y' 0 y')
end
: nat -> nat -> nat
So Compute (div 1 0). gives you 0.
The nice thing is that you can use div in expressions directly, without having to interleave proofs that the denominator is non-zero. Proving that an expression is correct is then done after it has been defined, not at the same time.

Are Coercions allowed within polymorphic datatypes in coq?

I'm using a lot of pairs with types that would normally be coerced freely. However, the notation doesn't explicitly provide the types for the pairs, even though the context does. The following code provides a simple MWE of the principle:
Coercion nat_to_bool (n : nat) : bool :=
match n with
| 0 => false
| _ => true
end.
Inductive newtype : Type :=
| firstconstr : bool -> newtype
| secondconstr : (bool * bool) -> newtype.
Check (3 : bool).
Check (firstconstr 3).
Fail Check (secondconstr (3, true)).
Check (secondconstr (#pair bool bool 3 true)).
The failure message is The term "(3, true)" has type "(nat * bool)%type" while it is expected to have type "(bool * bool)%type". Obviously the type system can figure out the type that it is supposed to be, but can't decide to coerce the value properly.
Is there a way to declare the coercion in such a way that tuples (and other polymorphic data types with inferred types) are coerced properly?
Maybe you can make a notation that desugars to an annotation so the coercion goes through, assuming the pair is always constructed explicitly (that seems fair for a typing judgement G |- x : T where x : T is a pair, although I think the whole judgement is more commonly seen as a triple).
Here's a PoC with the minimal example:
Notation "'secondconstr'' ( x , y )" := (secondconstr (x : bool, y)).
Check (secondconstr' (3, true)).
And in the context of your types judgement, it might look like this:
Notation "Gamma |- v : T" := (types Gamma (v : value, T))
(at level 100).

How do I provide implicit arguments explicitly in Coq?

Suppose I have a definition f : x -> y -> z where x can be easily inferred.
I therefore choose to make x an implicit argument using Arguments.
Consider the following example:
Definition id : forall (S : Set), S -> S :=
fun S s => s.
Arguments id {_} s.
Check (id 1).
Clearly S = nat can be and is inferred by Coq, and Coq replies:
id 1
: nat
However, at a later time, I want to make the implicit argument explicit, say, for readability.
In other words, I would like something like:
Definition foo :=
id {nat} 1. (* We want to make it clear that the 2nd argument is nat*)
Is this possible at all?
If so, what is the appropriate syntax?
You can prepend the name with # to remove all implicits and provide them explicitly:
Check #id nat 1.
You can also use (a:=v) to pass an implicit argument by name. This can both clarify what argument is being passed and also allows you to pass some implicits without passing _ for the others:
Check id (S:=nat) 1.
Definition third {A B C:Type} (a:A) (b:B) (c:C) := c.
Check third (B:=nat) (A:=unit) tt 1 2.
One possible way is by prepending # to the definition.
For example:
Definition id : forall (S : Set), S -> S :=
fun S s => s.
Arguments id {_} s.
Check #id nat 1.
Which results in:
id 1
: nat