【发布时间】:2014-12-24 13:50:15
【问题描述】:
我正在尝试学习 Coq,但我发现很难从 Software Foundations 和 Certified Programming with Dependent Types 中阅读的内容飞跃到我自己的用例。
特别是,我想我会尝试在列表中创建 nth 函数的验证版本。我设法写了这个:
Require Import Arith.
Require Import List.
Import ListNotations.
Lemma zltz: 0 < 0 -> False.
Proof.
intros. contradict H. apply Lt.lt_irrefl.
Qed.
Lemma nltz: forall n: nat, n < 0 -> False.
Proof.
intros. contradict H. apply Lt.lt_n_0.
Qed.
Lemma predecessor_proof: forall {X: Type} (n: nat) (x: X) (xs: list X),
S n < length (x::xs) -> n < length xs.
Proof.
intros. simpl in H. apply Lt.lt_S_n. assumption.
Qed.
Fixpoint safe_nth {X: Type} (n: nat) (xs: list X): n < length xs -> X :=
match n, xs with
| 0, [] => fun pf: 0 < length [] => match zltz pf with end
| S n', [] => fun pf: S n' < length [] => match nltz (S n') pf with end
| 0, x::_ => fun _ => x
| S n', x::xs' => fun pf: S n' < length (x::xs') => safe_nth n' xs' (predecessor_proof n' x xs' pf)
end.
这可行,但它提出了两个问题:
- 有经验的 Coq 用户会如何写这个?这三个引理真的有必要吗?这是
{ | }类型的用例吗? - 如何从其他代码调用此函数,即如何提供所需的证明?
我试过这个:
Require Import NPeano.
Eval compute in if ltb 2 (length [1; 2; 3]) then safe_nth 2 [1; 2; 3] ??? else 0.
但是,在我弄清楚要为??? 部分写什么之前,这当然是行不通的。我尝试将(2 < length [1; 2; 3]) 放在那里,但它的类型为Prop 而不是2 < length [1; 2; 3]。我可以编写并证明该特定类型的引理,并且有效。但是一般的解决方案是什么?
【问题讨论】:
标签: coq