1

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?

Siddharth Bhat
  • 823
  • 5
  • 15

1 Answers1

2

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.
Anton Trunov
  • 15,074
  • 2
  • 23
  • 43
  • I am clearly out of my depth here. `eq_ind_r` states that if a property `P` holds for `x`, then `x = y` implies `P y`, correct? – Siddharth Bhat Jan 16 '18 at 12:14
  • 1
    Yes, it is correct. `E` has type `n = S n'`, and `(gt_Sn_O n')` gives us a proof of `S n' > 0`, but we want a proof of `n > 0`, so we use `eq_ind_r` to substitute `n` for `S n'` in that proof of `S n' > 0`. – Anton Trunov Jan 16 '18 at 12:18
  • Thanks! Is there a comprehensive list of how "match" works? In particular, I have seen "match as" here, and "match in" in CPDT – Siddharth Bhat Jan 16 '18 at 12:34
  • 1
    CPDT is comprehensive I would say, however you can take a look at the manual, [chapter 17](https://coq.inria.fr/refman/cases.html#Mult-match-full). – Anton Trunov Jan 16 '18 at 12:36
  • Thanks, much appreciated :) Can I start reading CPDT from the `MoreDep` chapter, or would I have to backtrack for context? – Siddharth Bhat Jan 16 '18 at 12:39
  • 1
    It depends on your background and experience with Coq. if you find yourself in trouble, then you start from the beginning, read (or skim) the first 4 chapters and then head to MoreDep. – Anton Trunov Jan 16 '18 at 12:42