Consider the following program
Definition useGt0 (n: nat) (witness: n > 0) : nat :=
10.
Definition createGt0(n: nat) : nat :=
match n with
| O => 42
| S(n') => useGt0 n (#???)
end.
Clearly, n > 0
is inhabited, because n = S n'
. However, how do I get access to the proof that n = S n'
? From n = S n'
, we can derive that n > 0
.
In general, I wish to understand: How do I extract information from a pattern match?
The standard way to define createGt0
function is to use the convoy pattern (you can find several explanations using [coq] [convoy-pattern] search query on Stackoverflow). The standard link is A. Chlipala's CPDT book.
Here is a solution:
Definition createGt0 (n : nat) : nat :=
match n as x return (n = x -> nat) with
| O => fun _ => 42
| S n' => fun E => useGt0 n (eq_ind_r (fun n => n > 0) (gt_Sn_O n') E)
end eq_refl.
Another option is to use Program
mechanism, which lets you program in non-dependently-typed style, deferring proof obligations until a later time:
Require Import Program.
Program Definition createGt0 (n : nat) : nat :=
match n with
| O => 42
| S n' => useGt0 n _
end.
Next Obligation. apply gt_Sn_O. Qed.
At last, you could use tactics to build your function:
Definition createGt0 (n : nat) : nat.
Proof.
destruct n eqn:E.
- exact 42.
- refine (useGt0 n _).
rewrite E.
apply gt_Sn_O.
Defined.
If you end your function with Qed
, Coq will consider it opaque and won't reduce. Try ending the function with both Qed
and Defined
and execute the following command:
Compute createGt0 0.