Coq Index Relation
Question
I'm defining an indexed inductive type in Coq:
Module Typ. (* My index -- a t is a `t H` or a `t Z`. *) Inductive hz : Set := H | Z. (* I'd like to use this relation to constrain Cursor and Arrow. *) (* E.g. one specialized Cursor has type `t H -> t Z -> t Z` *) Inductive maxHZ : hz -> hz -> hz -> Type := | HZ : maxHZ H Z Z | ZH : maxHZ Z H Z | HH : maxHZ H H H. Inductive t : hz -> Type := | Num : t H | Hole : t H | Cursor : t H -> t Z | Arrow : forall a b c, t a -> t b -> t c | Sum : forall a b c, t a -> t b -> t c. End Typ.
How can I constrain my Arrow / Sum indices to be the same shape as the maxHZ relation (short of creating more constructors, like ArrowHZ : t H -> t Z -> t Z).
A: Depending on your final use case, you could either create a subtype of t and make Arrow satisfy the maxHZ predicate, or alternatively, you could add the relation to the constructor Arrow : forall a b c, maxHZ a b c -> t a -> t b -> t c. In all cases, you want to make maxHZ irrelevant so it doesn't bug you in proofs. Making it a boolean is likely a good idea.
Answer
One approach:
(* Bring the coercion is_true into scope *) From Coq Require Import ssreflect ssrfun ssrbool. Module Typ. (* My index -- a t is a `t H` or a `t Z`. *) Inductive hz : Set := H | Z. (* I'd like to use this relation to constrain Cursor and Arrow. *) (* E.g. one specialized Cursor has type `t H -> t Z -> t Z` *) Definition maxHZ (x y z : hz) : bool := match x, y, z with | H, Z, Z | Z, H, Z | H, H, H => true | _, _, _ => false end. Inductive t : hz -> Type := | Num : t H | Hole : t H | Cursor : t H -> t Z | Arrow : forall a b c, maxHZ a b c -> t a -> t b -> t c | Sum : forall a b c, maxHZ a b c -> t a -> t b -> t c.
the other:
Inductive t : hz -> Type := | Num : t H | Hole : t H | Cursor : t H -> t Z | Arrow : forall a b c, t a -> t b -> t c | Sum : forall a b c, t a -> t b -> t c. Definition t_wf x (m : t x) : bool := match m with | Arrow a b c _ _ => maxHZ a b c | Sum a b c _ _ => maxHZ a b c | _ => true end. Definition t' x := { m : t x | t_wf x m }. (* This is automatically a subtype. *) End Typ.
Q: Why do you redefine maxHZ as a function to bool instead of keeping it like it is and having the constraint maxHZ a b c in the Arrow constructor?
A: To get irrelevance for free, I don't want equality on t to depend on the concrete shape / proof of the relation.