得出关于模式匹配的事实

时间:2018-01-16 07:51:31

标签: coq coq-tactic

考虑以下计划

Definition useGt0 (n: nat) (witness: n > 0) : nat :=
  10.


Definition createGt0(n: nat) : nat :=
  match n with
  | O => 42
  | S(n') => useGt0 n  (#???)
  end.

显然,n > 0有人居住,因为n = S n'。但是,如何访问n = S n'的证明?从n = S n'开始,我们可以推导出n > 0

一般来说,我希望了解:如何从模式匹配中提取信息

1 个答案:

答案 0 :(得分:1)

定义createGt0函数的标准方法是使用convoy模式(您可以在Stackoverflow上使用[coq] [convoy-pattern]搜索查询找到几个解释)。标准链接是A. Chlipala的CPDT书。

这是一个解决方案:

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.

另一个选择是使用Program机制,它允许您以非依赖类型的方式编程,将证明义务推迟到以后的时间:

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.

最后,您可以使用策略来构建您的功能:

Definition createGt0 (n : nat) : nat.
Proof.
  destruct n eqn:E.
  - exact 42.
  - refine (useGt0 n _).
    rewrite E.
    apply gt_Sn_O.
Defined.

如果您使用Qed结束您的功能,Coq会认为它不透明并且不会减少。尝试使用QedDefined结束该函数并执行以下命令:

Compute createGt0 0.