Isabelle 加强数据类型的区分性

Isabelle 加强数据类型的区分性,isabelle,Isabelle,我在Isabelle中定义了以下数据类型 datatype bc_t = B | C 不知道如何证明下面的基本引理 lemma "∀ x::bc_t . (x=B ⟶ x≠C)" 假设B≠C证据经过: lemma "⟦B≠C; x=B⟧ ⟹ x≠C" by metis 在没有明确假设B和C是不同的情况下,有没有办法证明引理 更新:正如Manuel Eberl在对答案的评论中所建议的那样,问题是由错误的简化规则(带有[simp]属性的引理,此处省略)导致简化过程循环,从而忽略自动生成的简

我在Isabelle中定义了以下数据类型

datatype bc_t =  B | C
不知道如何证明下面的基本引理

lemma "∀ x::bc_t . (x=B ⟶ x≠C)"
假设
B≠C
证据经过:

lemma "⟦B≠C; x=B⟧ ⟹ x≠C"
by metis 
在没有明确假设
B
C
是不同的情况下,有没有办法证明引理


更新:正如Manuel Eberl在对答案的评论中所建议的那样,问题是由错误的简化规则(带有
[simp]
属性的引理,此处省略)导致简化过程循环,从而忽略自动生成的简化规则
B≠C
C≠B
(如Chris在其回答中指出的,可在
bs_t.simps
中找到)。正如gc44的回答一样,
simp
足以证明正常情况下的引理

你可以让自动工具给你一个大的起点。要告诉你从自动工具获得反馈的多种方法,我需要做的工作比证明这个定理要多得多

datatype bc_t =  B | C

lemma "∀ x::bc_t . (x = B ⟶ x ~= C)"
try0
using[[simp_trace]] 
using [[simp_trace_depth_limit=100]]
apply(simp)
done

lemma "∀ x::bc_t . (x = B ⟶ x ~= C)"
sledgehammer
by (metis bc_t.distinct(1))
我使用了
try0
,因为我在“pluginoptions/Isabelle/General”中没有选中
Auto方法。在选项中,我多次选中除Sledgehammer之外的所有自动工具框

您可以使用我在这里展示的
sledgehammer
,也可以在PIDE的sledgehammer面板中使用它。使用
simp\u trace
,当您将光标放在带有
apply(simp)
的行上时,您可以了解
simp
方法是如何证明它的,它将基于替换规则

更新140108_1305

自动工具对于帮助我们快速工作很重要,但有时理解证据的基本逻辑也很重要。这就是
simp\u trace
simp
方法的其他属性可能有用的地方。阅读
tutorial.pdf
prog prove.pdf
isar-ref.pdf
了解有关使用
simp
的一些详细信息和课程

控制
simp
方法的三个这样的属性是
add
del
only

在您的示例中,我想使用
simp_trace
,以及
only
,以明确使用了哪些规则,从而帮助我理解逻辑

用大锤进行的
metis
证明表明
simp
可能只使用了一些规则。我查看
simp
跟踪,让
simp
只使用我可以从控制面板剪切和粘贴的规则。我数了4条命名规则,但这并不是真正值得做的事情,尽管我必须找出答案

[Update140101\u 0745:为了避免过度分析情况,我最终使用了
del
,因为我只使用
only
的宏伟计划没有成功。下面用
simp only
代替
simp del
apply
方法失败并出现错误,这意味着它无法简化目标只有这四条规则。
auto-simp only
而不是
simp only
auto
方法不受
simp
的限制,它可能会做很多它不会告诉你的事情,比如调用
blast

lemma "∀ x::bc_t . (x = B ⟶ x ~= C)"    
using[[simp_trace]] 
using [[simp_trace_depth_limit=100]]
apply(simp del: 
    bc_t.distinct(1)
    simp_thms(8)
    simp_thms(17)
    simp_thms(35)
    ) 
oops
好吧,现在当我看最新的
simp
trace时,有很多
simp
规则。简化器有超过1块石头可以杀死这只鸟,所以我放弃了

需要记住的一点是,可以将
simp
auto
fastforce
等方法一起使用,比如
apply(auto-simp-add:stufferThm)
。特别是使用
auto
,如果
simp
规则不足以证明一个定理,它可能会求助于使用
blast
,而这不会出现在
simp
跟踪中。当只使用
时,这一点很重要,因此您不会觉得
simp
规则就是所有这些需要一个由
auto
找到的证明

下面我就你的评论发表一些评论

<> > <代码> SIMP < /代码>保持紫色很长,它必须做大量的简化,或者它是在一个非终止循环中,正如E伯尔提到的。要么是坏的。我不认为40秒<代码> SIMP < /代码>证明是一个很好的证明。

基本上,在循环中获取
simp
或调用
simp
的任何其他方法都非常容易,特别是当您定义自己的
simp
规则时。当
simp
方法起作用时很容易。当它不起作用时,您可能需要为自己的逻辑工作

使用
try0
,当找不到证明时,它会给你一个自动证明方法的列表,比如
force
fastforce
auto
,等等。如果
simp
使用
auto
循环,你可以使用
fastforce
尝试。实验次数很多

另一件需要记住的重要事情是展开不是
simp
规则的定义。大锤有时可以找到定义,但有时最简单的定理无法证明,因为定义尚未展开

[更新140109\u 0750:进行归纳总是有风险的。展开定义会多次阻止Sledgehammer找到证明。Sledgehammer通过匹配高级定理工作得很好,因此一个无望扩展的公式将多次注定失败。即使是一个巨大扩展的公式也可能导致其他自动方法无法找到证明。然而,对于基于方程的计算性质的事物,扩展定义可以让
simp
完全简化一个庞大而复杂的表达式。你必须知道什么时候持有它们,什么时候展开它们。最棒的是,可以很容易地尝试大量的推理
definition stuffTrue :: "bool" where
  "stuffTrue = True"

theorem "stuffTrue"
  apply(unfold stuffTrue_def)
  by(simp)
datatype bc_t =  B | C
thm bc_t.simps

B ≠ C
C ≠ B
(case B of B ⇒ ?f1.0 | C ⇒ ?f2.0) = ?f1.0
(case C of B ⇒ ?f1.0 | C ⇒ ?f2.0) = ?f2.0
bc_t_rec ?f1.0 ?f2.0 B = ?f1.0
bc_t_rec ?f1.0 ?f2.0 C = ?f2.