我如何使coq相信(A/\B)/\C==A/\B/\C?

我如何使coq相信(A/\B)/\C==A/\B/\C?,coq,Coq,在我的证明中,我偶然发现在我的假设中有一个A/\B/\C,我需要证明(A/\B)/\C。这些在逻辑上是完全相同的,但coq不会用假设来解决这些问题。 我一直在应用一个公理来解决这些问题,但是有没有更优雅(正确)的方法来处理这个问题呢?所以我的方法就是定义我的引理 Lemma conj_assoc : forall A B C, A /\ (B /\ C) <-> (A /\ B) /\ C. 引理连接:对于所有A B C,A/\(B/\C)(A/\B)/\C。 这是一个意味着另一

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


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

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

Lemma conj_assoc : forall A B C, A /\ (B /\ C) <-> (A /\ B) /\ C.
引理连接:对于所有A B C,A/\(B/\C)(A/\B)/\C。 这是一个意味着另一个

简介。拆分。
然后将此拆分为两个目标

  • A/\(B/\C)->(A/\B)/\C
  • (A/\B)/\C->A/\(B/\C)
  • 证明每一个都大致相同。第(1)款

    • intro Habc.
      从左侧尺寸中获取假设
    • 将Habc作为[Ha Hbc]销毁。将Hbc分解为[Hb Hc]。
      以获得单独的假设
    • auto
      使用这些假设
    我把它留给你去解决,但它非常相似


    然后
    Qed.

    作为一个一般提示,如果您怀疑有这样明显的问题,请查看标准库。下面是如何:
    Locate”/\“
    为我们生成一个解析
    符号的响应

    Notation            Scope     
    "A /\ B" := and A B  : type_scope
                          (default interpretation)
    
    现在我们可以发出命令,
    SearchAbout and.
    查看范围内的内容,并发现
    和_assoc
    见证了您感兴趣的含义。事实上,你可以从你的直觉中得到提示:
    直觉
    策略可以自己利用这一暗示

    Lemma conj_example : forall A B C D,
      (A /\ B) /\ C -> (A /\ (B /\ C) -> D) -> D.
    Proof. intuition. Qed.
    

    如果你有
    A/\B/\C
    作为假设,并且你的目标是
    (A/\B)/\C
    ,你可以使用策略
    。这种策略解决了命题演算中的所有重言式。还有一种策略
    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(\/\\\\\/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\。您可以使用
    SearchRewrite(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\。不幸的是,这并没有找到我们要找的东西,这是一个形式为
    的引理,对于所有x1…xn,(?a/\?B/\?C)?D
    。工作是什么

    Coq < SearchPattern (_ <-> (_ /\ _ /\ _))
    and_assoc: forall A B C : Prop, (A /\ B) /\ C <-> A /\ B /\ C
    
    Coq
    我想我应该解释一下为什么
    A/\(B/\C)==(A/\B)/\C
    不起作用。你的基本意思是(用建设性的Coq术语)证明
    A/\(B/\C)
    (A/\B)/\C
    相同。从证明(1)和(2)中可以看出,它们不是。在我的公式中,我们说我可以将一个证明转化为另一个。只是一个编程细节:你可以编写
    将Habc分解为[Ha[Hb Hc]]
    这个引理自Coq 8.3以来以
    和_assoc
    的形式存在。你可以用
    tauto
    非常简单地证明这一点。