我试图证明关于以下函数的命题:
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
中进行案例分析?为什么我不能像通常用其他函数那样展开除法的定义?
谢谢。
答案 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.Wf
或fix_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_irrelevance
和functional_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
但它似乎做了同样的事情。