我如何使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)
从左侧尺寸中获取假设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
非常简单地证明这一点。