我有一个数据类型和一个归纳谓词(实际上是一些转换系统的小步骤语义):
datatype dtype = E | A | B dtype
inductive dsem :: "dtype ⇒ dtype ⇒ bool" where
"dsem A E"
| "dsem (B E) E"
| "dsem d d' ⟹ dsem (B d) (B d')"
以及通过区分计算的函数:
fun f :: "dtype ⇒ nat" where
"f E = 0"
| "f A = 1"
| "f (B _) = 2"
我试图证明关于归纳谓词的一些属性,并且假设还涉及计算不参与归纳的f
的值。
lemma
assumes d: "dsem s s'"
and h: "h s v"
and v: "v = f s"
shows "P v"
using d h
proof (induct rule: dsem.induct)
对于第3个语义规则,Isabelle计算子目标
⋀d d'. dsem d d' ⟹ (h d v ⟹ P v) ⟹ h (B d) v ⟹ P v
s
的值丢失,因此无法计算值v
。
我既不能将v
纳入归纳假设,因为Isabelle会生成子目标
⋀d d'. dsem d d' ⟹ (h d v ⟹ v = f d ⟹ P v) ⟹ h (B d) v ⟹ v = f (B d) ⟹ P v
在这种情况下,归纳假设显示v = f d
,因为v = f (B d)
以来不正确。我也无法将v
放入arbitrary: ...
,因为v
的值必须在整个证明中得到修复。
在生成的子目标中有一个显式绑定s = B d
会很好;不幸的是,规则dsem.induct
没有提供它。
在这种情况下,是否有人知道计算值v
的解决方法?
答案 0 :(得分:1)
对我来说,v
应该同时修复并从s
开始计算,这就是chris在评论中所说的内容,这似乎很奇怪。
如果评论中提供的解决方案Brian符合您的要求,则可能会复制表达式f s
,这可能很大(并且多次使用s
),也许是重点假设v = f s
是为了避免这种情况。
第一个解决方法(可能是Brian隐含提出的)是让Isabelle做unfolding
:
lemma
assumes d: "dsem s s'"
and h: "h s v"
and v: "v = big_f s s"
shows "P v"
using d h
unfolding v -- {* <<<< *}
proof (induct rule: dsem.induct)
第二种解决方法可能是缩写big_f
而不是big_f s s
:
lemma
assumes d: "dsem s s'"
and h: "h s (f s)"
and v: "f = (λs. big_f s s)" -- {* <<<< *}
shows "P (f s)"
using d h
proof (induct rule: dsem.induct)