Coq案例分析证明

时间:2015-11-22 15:45:26

标签: coq proof

我试图证明关于以下函数的命题:

Program Fixpoint division (m:nat) (n:nat) {measure m} : nat :=
match lt_nat 0 n with
  | false => 0
  | true => match leq_nat n m with
      | false => 0
      | true => S (division (menos m n) n)
  end
end.

menos是自然减法。

我试图证明涉及分裂的一些事实。我写下了一个非正式的证据,我首先考虑了lt_nat 0 n中的案例分析,然后在lt_nat为真的情况下,在leq_nat n m中进行了进一步的案例分析。这是为了减少分裂的定义。

但我无法找到如何在Coq中表达此案例分析。我试过destruct (leq_nat n m),但它没有做任何事情。我期待Coq产生两个子目标:一个我需要证明我的命题假设leq_nat n m = false而另一个假设leq_nat n m = true

此外,我无法在我的证明中展开除法的定义!当我尝试unfold division时,我得到:division_func (existT (fun _ : nat => nat) m n)

如何在leq_nat n m中进行案例分析?为什么我不能像通常用其他函数那样展开除法的定义?

谢谢。

1 个答案:

答案 0 :(得分:2)

由于Program Fixpoint,所有内容都比平常更复杂,因为它需要找到一种结构递归的定义方法,因为它没有像经典Fixpoint那样定义你的函数。 division实际上是division_func隐藏的内容。

因此,要操纵你的功能,你需要证明基本的引理,包括说明你的功能可以由它的身体代替的引理。

Lemma division_eq : forall m n, division m n = match lt_nat 0 n with
| false => 0
  | true => match leq_nat n m with
      | false => 0
      | true => S (division (menos m n) n)
  end
end.

现在,问题是如何证明这一结果。这是我所知道的唯一解决方案,我认为这种解决方案确实令人不满意。

我使用位于fix_sub_eq中的策略Program.Wffix_sub_eq_ext中的Program.Wf.WfExtensionality

这就是:

Proof.
  intros.
  unfold division. unfold division_func at 1.
  rewrite fix_sub_eq; repeat fold division_func.
  - simpl. destruct (lt_nat 0 n) eqn:H.
    destruct (leq_nat n m) eqn:H0. reflexivity.
    reflexivity. reflexivity.

但第二个目标非常复杂。解决它的简单而通用的方法是使用公理proof_irrelevancefunctional_extensionality。应该可以在没有任何公理的情况下证明这个特定的子目标,但我没有找到正确的方法来做到这一点。您可以使用直接调用它们的第二种策略fix_sub_eq_ext,而不是手动应用公理,只留下一个目标。

Proof.
  intros.
  unfold division. unfold division_func at 1.
  rewrite fix_sub_eq_ext; repeat fold division_func.
  simpl. destruct (lt_nat 0 n) eqn:H.
  destruct (leq_nat n m) eqn:H0. reflexivity.
  reflexivity. reflexivity.
Qed.

我没有找到更好的方法来使用Program Fixpoint,这就是为什么我更喜欢使用Function,它有其他默认值,但直接生成方程式引理。

Require Recdef.
Function division (m:nat) (n:nat) {measure (fun n => n) m} : nat :=
match lt_nat 0 n with
  | false => 0
  | true => match leq_nat n m with
      | false => 0
      | true => S (division (menos m n) n)
  end
end.
Proof.
  intros m n. revert m. induction n; intros.
  - discriminate teq.
  - destruct m. discriminate teq0.
    simpl. destruct n. destruct m; apply le_n.
    transitivity m. apply IHn. reflexivity. assumption. apply le_n.
Qed.

Check division_equation.

现在你有方程式引理,你可以像往常一样重写并推理。

关于destruct的问题,destruct没有展开定义。因此,如果您没有出现您在目标或任何假设中破坏的术语,destruct将不会做任何有趣的事情,除非您保存它产生的等式。您可以使用destruct ... eqn:H来实现此目的。我不知道case_eq但它似乎做了同样的事情。