Coq中合取式中非泛化命题的引入及存在性目标证明咨询
嘿,我来帮你搞定这两个Coq证明里的问题,一步步给你讲清楚:
当你有一个合取形式的假设(比如 H : A /\ B),想要单独提取其中的A或者B来用,最直接的方式是用destruct策略拆分这个合取式:
- 执行
destruct H as [HA HB]之后,上下文中就会多出两个独立的假设:HA : A和HB : B,你可以直接用它们来推进证明。
如果只是临时需要合取式的某一部分,也可以用投影函数proj1(取左半部分)和proj2(取右半部分),比如:
- 用
exact (proj1 H)直接把合取式的左半部分作为结论; - 或者用
apply proj1 in H,把原假设H转换成HA : A。
给你举个简单的实例:
Goal forall A B : Prop, A /\ B -> A. Proof. intros A B H. (* 拆分合取式,只保留左半部分 *) destruct H as [HA _]. exact HA. Qed.
用投影函数的简化版本:
Goal forall A B : Prop, A /\ B -> A. Proof. intros A B H. (* 直接取合取式的左半部分作为结论 *) exact (proj1 H). Qed.
exists x:nat, (P /\ Q),假设中的P并未泛化,是否可以使用revert或generalize策略来完成该证明? 首先得明确:假设里的P应该是对应某个具体nat实例的(比如你有上下文n : nat,H : P n),而目标是要找到一个x使得P x /\ Q x。这种情况下,revert和generalize确实可以帮你调整上下文,让证明更顺畅,不过也有更直接的思路,我都给你讲讲:
用revert的场景
假设你的上下文是n : nat、H : P n,目标是exists x, P x /\ Q x:
- 执行
revert H,会把假设H移到目标里,此时目标变成P n -> exists x, P x /\ Q x; - 再用
intro H把它拉回上下文,之后就可以用exists n指定x的取值,把目标拆分成P n /\ Q n,再分别用H和其他假设/引理证明两部分。
实例代码:
Variables (P Q : nat -> Prop). Goal forall n : nat, P n -> exists x, P x /\ Q x. Proof. intros n H. (* 把H移到目标中,调整上下文结构 *) revert H. intro H. (* 指定x为n *) exists n. split. - exact H. (* 用H证明P n *) - (* 这里补充Q n的证明逻辑即可 *) Admitted.
不用revert的直接解法
其实很多时候你不需要特意用revert,直接指定x的取值就行:比如上面的例子,直接exists n,然后split,用H证明P n,再处理Q n就好。
什么时候用generalize?
如果想把某个具体的假设转换成全称量化的形式,可以用generalize。比如你有H : P n,执行generalize n会把n移到目标里,变成forall n : nat, P n -> exists x, P x /\ Q x,这和最开始的目标结构一致;如果是generalize (H),会把上下文里的n和H绑定,生成一个更通用的假设。
总的来说,revert和generalize是调整上下文的工具,能帮你把假设和目标的关系理得更清楚,但这个问题里不一定是必须的,看你的证明路径选择。
内容的提问来源于stack exchange,提问作者Diego Recabarren

