Proofs about constructors matched with _
Question
Assume I have the following Set:
Inductive Many : Set :=
| aa : Many
| bb : Many
| cc : Many
(* | ... many more constructors *)
.
How can I proof in the _ match, that y <> aa?
match x with
| aa => true
| _ as y => (* how can I proof that y <> aa ? *)
Answer
Unfortunately, it does not seem possible to get such a proof without some more work in pure Gallina. What you would like to write is:
Definition foo (x : Many) : bool :=
match x with
| aa => true
| y =>
let yNOTaa : y <> aa :=
fun yaa =>
eq_ind y (fun e => match e with aa => False | _ => True end) I aa yaa
in false
end.
But that does not work quite well in Gallina, as it does not expand the wildcard into all possible cases, leaving y abstract in the eq_ind invocation. It does however work in tactic mode:
refine ( match x with | aa => true | y => let yNOTaa : y <> aa := fun yaa => eq_ind y (fun e => match e with aa => False | _ => True end) I aa yaa in false end).x: Manybool
But it actually builds the expanded term with all the branches.
I just found out that there is a way to have the Vernacular build the same term that the refine tactic would build. To do so, you have to force a return annotation mentioning the discriminee, like so:
Definition foo (x : Many) : bool :=
match x return (fun _ => bool) x with
| aa => true
| y =>
let yNOTaa : y <> aa :=
fun yaa : y = aa =>
@eq_ind Many y (fun e => match e with aa => False | _ => True end) I aa yaa
in false
end.
My guess is that the term elaboration differs whether the match is dependent or not...