分号之间的Coq执行差异&引用;和句号&引用;
使用分号之间的Coq执行差异&引用;和句号&引用;,coq,coq-tactic,Coq,Coq Tactic,使用给出有效的Coq证明战术,是否有一个通用公式将其转换为有效的等价证明,并用替换 许多Coq证明使用或战术排序。作为一个初学者,我想观看各个步骤的执行,所以我想用代替,但令我惊讶的是,我发现这可能会打破证据 关于的文档是稀疏的,我还没有在任何地方找到关于的明确讨论。我确实看到了一个表示t1的非正式含义的例子;t2是 将t2应用于当前证明上下文中执行t1产生的每个子目标 我想知道是否只对当前子目标起作用,这就解释了不同的行为?但我特别想知道,如果用代替,是否有一种修复破损的通用方法tac1的语义
给出有效的Coq证明代码>战术,是否有一个通用公式将其转换为有效的等价证明,并用
替换代码>
许多Coq证明使用代码>或战术排序。作为一个初学者,我想观看各个步骤的执行,所以我想用
代替代码>,但令我惊讶的是,我发现这可能会打破证据
关于的文档
是稀疏的,我还没有在任何地方找到关于
的明确讨论。我确实看到了一个表示t1的非正式含义的例子;t2是
将t2
应用于当前证明上下文中执行t1
产生的每个子目标
我想知道
是否只对当前子目标起作用,这就解释了不同的行为?但我特别想知道,如果用
代替,是否有一种修复破损的通用方法
tac1的语义;tac2
是运行tac1
,然后对tac1
创建的所有子目标运行tac2
。因此,您可能面临多种情况:
运行tac1
如果在运行tac1
后没有剩余目标,那么tac2
将永远不会运行,Coq将自动成功。例如,在第一个派生中,我们有一个无用的;(有效)证明末尾的简介
:
如果我们孤立它,那么我们会得到一个错误:没有这样的目标。
因为我们试图在没有任何证据的情况下运行一种战术
Goal forall (A : Prop), A -> (A /\ A /\ A /\ A /\ A).
intros ; repeat split ; assumption.
intros. (* Error! *)
运行tac1
后,只剩下一个目标。
如果在运行tac1
之后只剩下一个目标,那么tac1;tac2的行为有点像tac1。tac2
。主要区别在于,如果tac2
失败,那么整个tac1也会失败;tac2
因为两种战术的顺序被视为一个整体,可以整体成功,也可以整体失败。但是如果tac2
成功,那么它几乎是等效的
例如,以下证明是有效的:
Goal forall (A : Prop), A -> (A /\ A /\ A /\ A /\ A).
intros.
repeat split ; assumption.
Qed.
运行tac1
会生成多个目标。
最后,如果通过运行tac1
生成多个目标,则tac2
将应用于所有生成的子目标。在我们的跑步示例中,我们可以观察到,如果我们在重复split
之后切断战术序列,那么我们就有5个目标。这意味着我们需要复制/粘贴假设
五次,以复制前面使用给出的证明代码>:
Goal forall (A : Prop), A -> (A /\ A /\ A /\ A /\ A).
intros ; repeat split.
assumption.
assumption.
assumption.
assumption.
assumption.
Qed.
谢谢你的案例分析!这很有帮助。@ChristopherBrinkley这篇文章回答了你的问题,如果你把它作为答案,那就太好了。我要指出的是,除了在每个分支中应用策略外,最重要的区别可能是Coq将回溯到代码>。例如,即使tac1
只生成一个目标,如果有多种方法可以实现(一个重要的例子是constructor
),那么tac1。tac2
将承诺第一次成功,并在其上运行tac2
<编码>tac1;tac2
将使tac1
尝试一件事,然后再尝试tac2
,如果失败,尝试另一种方法tac1
,然后再尝试tac2
,如果失败,尝试另一种方法,以此类推。
Goal forall (A : Prop), A -> (A /\ A /\ A /\ A /\ A).
intros ; repeat split.
assumption.
assumption.
assumption.
assumption.
assumption.
Qed.