Logic 如何在Coq中处理感应式案例
我想用Logic 如何在Coq中处理感应式案例,logic,coq,Logic,Coq,我想用destruct策略通过案例来证明一个陈述。我在网上读了几个例子,我很困惑。有人能更好地解释一下吗 下面是一个小示例(有其他方法可以解决此问题,但请尝试使用destruct): 在这种情况下,我得到: 3 subgoals H : zero <> zero /\ zero <> one ______________________________________(1/3) zero = two __________________________________
destruct
策略通过案例来证明一个陈述。我在网上读了几个例子,我很困惑。有人能更好地解释一下吗
下面是一个小示例(有其他方法可以解决此问题,但请尝试使用destruct
):
在这种情况下,我得到:
3 subgoals H : zero <> zero /\ zero <> one
______________________________________(1/3)
zero = two
______________________________________(2/3)
one = two
______________________________________(3/3)
two = two
3个子目标H:zero-zero/\zero-one
______________________________________(1/3)
零=二
______________________________________(2/3)
一=二
______________________________________(3/3)
二=二
所以,我想证明前两个案例是不可能的。但是机器将它们列为子目标,并希望我证明它们。。。这是不可能的
总结:
如何准确地丢弃不可能的案例
我见过一些使用反转的例子,但我不理解这个过程
最后,如果我的引理依赖于几个归纳类型,而我仍然想覆盖所有情况,会发生什么呢?如何丢弃不可能的情况?的确,前两项义务无法证明,但请注意,它们有相互矛盾的假设(0-0
和1-1
)。因此,你将能够用tauto
证明这些目标(如果你感兴趣的话,还有更原始的战术可以做到这一点)
inversion
是更高级的析构函数版本。除了“破坏”电感外,它有时还会产生一些等式(您可能需要)。它本身是归纳法的一个简单版本,它还将为您生成一个归纳假设
如果你的目标中有几种归纳类型,你可以一个接一个地分解/反转它们
更详细的演练:
Inductive three := zero | one | two .
Lemma test : forall a, a <> zero /\ a <> one -> a = two.
Proof.
intros a H.
destruct H. (* to get two parts of conjunction *)
destruct a. (* case analysis on 'a' *)
(* low-level proof *)
compute in H. (* to see through the '<>' notation *)
elimtype False. (* meaning: assumptions are contradictory, I can prove False from them *)
apply H.
reflexivity.
(* can as well be handled with more high-level tactics *)
firstorder.
(* the "proper" case *)
reflexivity.
Qed.
感应三:=零|一|二。
引理检验:对于所有a,一个零/\a一->a=2。
证明。
介绍a H。
析构函数H.(*得到两部分连词*)
破坏a。(*关于“a”的案例分析*)
(*低级证明*)
以H.为单位计算(*以看穿“”符号*)
elimtype为False。(*意思是:假设相互矛盾,我可以从中证明错误*)
应用H。
自反性。
(*也可以用更高层次的战术处理*)
一等货。
(*正确的案例*)
自反性。
Qed。
如果你看到一个不可能的目标,有两种可能性:要么你在证明策略中犯了错误(也许你的引理是错误的),要么假设是矛盾的
如果您认为假设是矛盾的,那么可以将目标设置为False
,以消除一点复杂性<代码>elimtype False实现了这一点。通常,通过证明命题P
及其否定~P
来证明False
;这种策略从P
和~P
中推断出任何目标。如果有一个特别的假设是矛盾的,矛盾H
将目标设置为~H
,或者如果假设是否定的~a
,那么目标将是a
(比~a
更强,但通常更方便)。如果一个特定的假设显然是矛盾的,矛盾H
或仅仅是矛盾
将证明任何目标
有许多策略涉及归纳类型的假设。弄清楚该用哪一个主要取决于经验。以下是主要案例(但您很快就会遇到此处未涉及的案例):
只是将假设分解为几个部分。它会丢失有关依赖项和递归的信息。一个典型的例子是destruct
,其中destructh
是一个连词H
,它将H:A/\B
分为H
和A
两种类型的独立假设;或者双重B
,其中destructh
是一个析取H
,它将证明分成两个不同的子类,一个是假设H:a\/B
,另一个是假设a
B
类似于case_eq
,但保留了该假设与其他假设之间的联系。例如,destruct
其中destruct n
将证明分为两个子类,一个子类用于n:nat
,另一个子类用于n=0
。如果在其他假设中使用了n=sm
(即,你有一个n
),你可能需要记住,你破坏的H:pn
与这些假设中使用的n
是相同的:n
就是这样做的case\u eq n
对假设类型进行案例分析。当反演
会忘记的假设类型中存在依赖项时,它特别有用。您通常会对destruct
中的假设使用集合
(等式相关)和case_eq
对反转
中的假设(具有非常依赖的类型)。Prop
策略留下了大量的等式,之后通常是inversion
,以简化假设。subst
策略是inversion\u clear
但会丢失一点信息inversion的简单替代方案;subst
意味着您将通过对给定假设的归纳法(=递归)来证明目标。例如,归纳法
其中inclusion n
意味着您将执行整数归纳,并证明基本情况(n:nat
替换为n
)和归纳情况(0
替换为n
)m+1
a
的案例分析来证明这一点
Lemma has2b2: forall a:three, a<>zero/\a<>one ->a=two.
Proof. destruct a; tauto. Qed.
这个目标看起来不可能实现。我们可以告诉Coq,在这里它可以自动发现矛盾(zero=zero
is obvi
Inductive three := zero | one | two .
Lemma test : forall a, a <> zero /\ a <> one -> a = two.
Proof.
intros a H.
destruct H. (* to get two parts of conjunction *)
destruct a. (* case analysis on 'a' *)
(* low-level proof *)
compute in H. (* to see through the '<>' notation *)
elimtype False. (* meaning: assumptions are contradictory, I can prove False from them *)
apply H.
reflexivity.
(* can as well be handled with more high-level tactics *)
firstorder.
(* the "proper" case *)
reflexivity.
Qed.
Lemma has2b2: forall a:three, a<>zero/\a<>one ->a=two.
Proof. destruct a; tauto. Qed.
H : zero <> zero /\ zero <> one
============================
zero = two
elimtype False. tauto.
destruct H as [H0 H1].
contradiction H0. reflexivity.
assert (F : False).
apply H0.
reflexivity.
destruct F.