如何在Coq中证明证明定义

时间:2016-01-23 15:16:39

标签: types pattern-matching definition coq proof

我目前正在与Coq合作,我遇到了一个我不知道如何解决的问题。

我们说我们正在使用给定的类型,我会以nat为例,我想使用可能失败的函数f。为了弥补失败,我们将f定义为nat -> option nat类型。

现在我有一个假设H: nat -> bool,其中f不会失败,我甚至证明了引理

Lemma no_error_in_f : forall (n:nat), H n = true -> exists (u:nat), f n = Some u.

我想定义一个函数g: nat->nat,如果f满足,则n的结果为H n,否则只给n。这个功能应该很好定义,但我不知道如何正确定义它。 如果我尝试一些幼稚的东西 Definition g (n:nat) := if H n then f n else n.,打字系统出现问题。

有谁知道如何收集所有元素并告诉系统该定义是合法的?

3 个答案:

答案 0 :(得分:1)

我在这里给出的解决方案与问题中给出的假设相同。

Axiom f : nat -> option nat.
Axiom H : nat -> bool.
Axiom no_error_in_f : forall n,
  H n = true -> exists u, f n = Some u.

Lemma no_error_in_f_bis : forall n,
  H n = true -> f n <> None.
Proof.
  intros. apply no_error_in_f in H0. destruct H0. rewrite H0. discriminate.
Qed.

Definition g n :=
  match H n as b return H n = b -> _ with
  | true => fun H =>
    match f n as f0 return f n = f0 -> _ with
    | Some n0 => fun _ => n0
    | None => fun H0 => match no_error_in_f_bis n H H0 with end
    end eq_refl
  | false => fun _ => n
  end eq_refl.

我使用另一个引理而不是no_error_in_f,这更便于证明False。 请注意,此函数的两个概念(使用return的{​​{1}}构造,破坏match的证明以显示分支无法访问)在此处解释:{{3} }。

答案 1 :(得分:0)

您的开发中存在两个问题。一个是你不能使用no_error_in_f来定义Coq中的g而不假设其他公理,因为Coq不允许从证明中提取计算信息(检查here以获取更多细节)。另一个问题是,您无法在H表达式中使用if,因为它会返回Prop而不是bool(请检查this answer更多细节)。

答案 2 :(得分:0)

我找到了一种方法,如果有人有兴趣,这是我的解决方案:

Definition g (n:nat) :nat := (match (H n) as a return a = H n -> nat with | true => (fun H_true => (match (f n) as b return b = f n -> nat with | Some u => (fun _ => u) | None => (fun H1 => False_rec _ (no_error_in_f H_true H1)) end) (eq_refl f n)) | false => n end) (eq_refl H n).

对于那些想知道它意味着什么的人,False_rec将第二个参数作为False的证明,并证明匹配是不可能的。

一词

(match (f n) as b return b = f n -> nat with | Some u => (fun _ => u) | None => (fun H1 => False_rec _ (no_error_in_f H_true H1)) end) (eq_refl f n)) 类型为f n = f n-> nat,当我将其应用于证明eq_refl (f n)时(证明f n = f n,因此键入f n = f n),我得到nat。 这个技巧允许我获得H1,这是f n = None使用相等的反射和模式匹配获得的证明,并且我将在{{1}的证明中使用}。

另一场比赛也是如此。