在我的证明中,我偶然发现了我的假设中存在A /\ B /\ C
的问题,我需要证明(A /\ B) /\ C
。这些在逻辑上完全相同,但是coq不会用assumption.
来解决这些问题。
我一直在通过应用公理来解决这些问题,但是有更优雅(和正确)的方法来解决这个问题吗?
答案 0 :(得分:5)
所以我的方法是定义我的引理,
Lemma conj_assoc : forall A B C, A /\ (B /\ C) <-> (A /\ B) /\ C.
这是另一个意味着另一个。
然后 intros. split.
会将此分为两个目标。
A /\ (B /\ C) -> (A /\ B) /\ C
(A /\ B) /\ C -> A /\ (B /\ C)
证明这些中的每一个大致相同。对于(1),
intro Habc.
从左手大小得到假设。destruct Habc as [Ha Hbc]. destruct Hbc as [Hb Hc].
获取个人假设。auto
使用这些假设。我留给你锻炼(2),但它非常相似。
然后Qed.
答案 1 :(得分:5)
如果您假设A /\ B /\ C
,并且目标是(A /\ B) /\ C
,则可以使用 tauto
这样的策略。这种策略解决了命题演算中的所有重言式。还有一种策略firstorder
可以用量词解决一些公式。
如果你有A /\ B /\ C
,并且想要将(A /\ B) /\ C
作为参数传递给引理,那么你需要多做一些工作。一种方法是将(A /\ B) /\ C
设置为中间目标并证明:
assert ((A /\ B) /\ C). tauto.
如果A
,B
和C
是大型表达式,您可以使用复合策略来匹配假设H : A /\ B /\ C
并对其应用tauto策略。这是一种严厉的方法,在这种情况下过度杀伤,但在更复杂的情况下非常有用,在这种情况下,您希望自动化具有许多类似案例的证据。
match type of H with ?x /\ ?y /\ ?z =>
assert (x /\ (y /\ z)); [tauto | clear H]
end.
有一种更简单的方法,即应用一个执行转换的已知引理。
apply and_assoc in H.
您可以通过浏览库文档找到该引理。你也可以搜索它。这不是最容易搜索的因素,因为它是等价的,搜索工具适用于影响和平等。您可以使用SearchPattern (_ /\ _ /\ _).
查找forall x1 … xn, ?A /\ ?B /\ ?C
形式的词条(其中?A
,?B
和?C
可以是任何表达式)。您可以使用SearchRewrite (_ /\ _ /\ _)
查找forall x1 … xn, (?A /\ ?B /\ ?C) = ?D
形式的引理。不幸的是,这并没有找到我们所追求的东西,这是forall x1 … xn, (?A /\ ?B /\ ?C) <-> ?D
形式的引理。工作是什么
Coq < SearchPattern (_ <-> (_ /\ _ /\ _))
and_assoc: forall A B C : Prop, (A /\ B) /\ C <-> A /\ B /\ C
答案 2 :(得分:3)
作为一般性提示,如果你有类似的东西,你怀疑是显而易见的,请检查标准库。方法如下:Locate "/\".
生成一个回复,为我们解析Notation
,
Notation Scope
"A /\ B" := and A B : type_scope
(default interpretation)
现在我们可以发出命令SearchAbout and.
以查看范围内的内容,并发现and_assoc
见证了您感兴趣的含义。实际上,您可以从中获取提示你的直觉:intuition
策略可以自己利用这个含义。
Lemma conj_example : forall A B C D,
(A /\ B) /\ C -> (A /\ (B /\ C) -> D) -> D.
Proof. intuition. Qed.