我想在Isabelle中证明以下内容:
theorem map_fold: "∃h b. (map f xs) = foldr h xs b"
apply (induction xs)
apply auto
done
如何获取h
和b
的实例化值?
答案 0 :(得分:3)
有时可用于此目的的方法是说明示意图:
schematic_lemma "map f xs = foldr ?h xs ?b"
apply (induct xs)
apply simp
...
simp
或rule
等方法可以在证明过程中实例化逻辑示意图变量(统一的结果)。如果您能够完成证明,那么您可以查看结果引理,看看最终的实例是什么。
请注意,原理图变量可能有点棘手:有时simp
会以一种方式实例化一个原理图变量,使当前目标可以证明是可以证明的,但同时使其他子目标无法解析。
在这种特殊情况下,Isabelle能够实例化?b没有问题,但它无法通过统一来确定?h。通常,具有函数类型的逻辑示意图变量要处理起来要复杂得多。
最后,我做了类似Manuel建议的事情:首先,用普通变量(lemma "map f xs = foldr h xs b"
)说明一个引理。然后看看感应证据被卡住的地方,并逐步改进陈述,直到证明为止。
答案 1 :(得分:2)
一种方法是使用SOME
:
h := SOME h. ∃b. map f xs = foldr h xs b
b := SOME b. map f xs = foldr h xs b
使用您的map_fold
定理和一些摆弄someI_ex
,您可以证明使用这些定义,map f xs = foldr h xs b
确实有效。
但是,虽然这在逻辑上为您提供了h
和b
的值,但我希望您不会对它们感到满意,因为您不会实现看 h
和b
是什么;而且(逻辑上)也没办法做到这一点。
在某些情况下,您还可以制定一个定理,说明“有f
,xs
,h
,b
不存在map f xs = foldr h xs b
”并且得到nitpick来找到该语句的反例,但是这种情况对于nitpick来说太复杂了,因为它必须在无限域上找到一个依赖于无限域上的另一个函数的函数。
我认为你没有办法真正从你被证明具体价值的定理中获得存在主义证人h
和b
。您只需通过检查归纳案例自行找到它们,并发现它们是h = λx xs. f x # xs
和b = []
。
这是迄今为止最简单的解决方案。
今天重新阅读这个帖子,我实际上记得Isabelle中确实存在证据提取。它需要为所有定理计算显式证明项,因此您需要使用isabelle jedit -l HOL-Proofs
启动Isabelle。然后你可以这样做:
theorem map_fold: "∃h b. (map f xs) = foldr h xs b"
by (induction xs) auto
extract map_fold
这定义了类型map_fold
的常量('a ⇒ 'b) ⇒ 'a list ⇒ ('a ⇒ 'b list ⇒ 'b list) × 'b list
,即给定映射函数和列表,它为您提供了必须放入foldr
的函数和初始状态为了得到相同的结果。您可以使用thm map_fold_def
查看定义。稍微简化一下,它看起来像这样:
map_fold f xs =
rec_list (λx xa. default, []) (λx xa H. (λa b. f a # map f xa, default)) xs
这有点难以阅读,但您可以看到[]
和f a # map f xa
。
不幸的是,证明条款变得非常大,所以我怀疑这对于玩具示例的其他任何东西都有很大的用处。