考虑以下计划
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
。
一般来说,我希望了解:如何从模式匹配中提取信息?
答案 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会认为它不透明并且不会减少。尝试使用Qed
和Defined
结束该函数并执行以下命令:
Compute createGt0 0.