我怎么说服coq(A / \ B)/ \ C == A / \ B / \ C?

时间:2012-06-01 09:15:01

标签: coq

在我的证明中,我偶然发现了我的假设中存在A /\ B /\ C的问题,我需要证明(A /\ B) /\ C。这些在逻辑上完全相同,但是coq不会用assumption.来解决这些问题。

我一直在通过应用公理来解决这些问题,但是有更优雅(和正确)的方法来解决这个问题吗?

3 个答案:

答案 0 :(得分:5)

所以我的方法是定义我的引理,

Lemma conj_assoc : forall A B C, A /\ (B /\ C) <-> (A /\ B) /\ C.

这是另一个意味着另一个。

然后

intros. split.会将此分为两个目标。

  1. A /\ (B /\ C) -> (A /\ B) /\ C
  2. (A /\ B) /\ C -> A /\ (B /\ C)
  3. 证明这些中的每一个大致相同。对于(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.

如果ABC是大型表达式,您可以使用复合策略来匹配假设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.