在尝试通过归纳来证明关于延续传递风格的函数的引理时,我遇到了自由类型变量的问题。在我的归纳假设中,continuation是原理图变量,但其类型涉及 free 类型变量。因此,当我尝试应用i.h时,Isabelle无法将类型变量与具体类型统一起来。我已经做了这个最小的例子:
SORTKEY
在"抱歉步骤"中,原理图变量fun add_k :: "nat ⇒ nat ⇒ (nat ⇒ 'a) ⇒ 'a" where
"add_k 0 m k = k m" |
"add_k (Suc n) m k = add_k n m (λn'. k (Suc n'))"
lemma add_k_cps: "∀k. add_k n m k = k (add_k n m id)"
proof(rule, induction n)
case 0 show ?case by simp
next
case (Suc n)
have "add_k (Suc n) m k = add_k n m (λn'. k (Suc n'))" by simp
also have "… = k (Suc (add_k n m id))"
using Suc[where k="(λn'. k (Suc n'))"] by metis
also have "… = k (add_k n m (λn'. Suc n'))"
using Suc[where k="(λn'. Suc n')"] sorry (* Type unification failed *)
also have "… = k (add_k (Suc n) m id)" by simp
finally show ?case .
qed
的显式实例化失败,
?k
因为Type unification failed
Failed to meet type constraint:
Term: Suc :: nat ⇒ nat
Type: nat ⇒ 'a
是免费的而不是原理图。没有实例化,简化器无论如何都会失败,我找不到其他可行的方法。
由于我无法对类型进行量化,因此我不知道如何在证明中制作'a
示意图。当一个术语变量在一个证明中局部地变成示意图时,为什么这种情况的变量也不是这种情况呢?在引理被证明之后,它们无论如何都成为理论层面的示意图。这看起来很有限。可以在将来实施这样做的选项还是存在一些固有的限制?或者,有没有一种方法可以避免这个问题,并且仍然在已证明的引理中保持连续性的示意性多态?
答案 0 :(得分:3)
这是HOL中感应如何工作的固有限制。归纳是HOL的一个规则,因此不可能在归纳假设中概括任何类型。
针对您的问题的专业解决方案是首先证明
lemma add_k_cps_nat: "add_k n m k = k (n + m)"
by (induction n arbitrary: m k) auto
然后证明add_k_cps
。
一般方法是:首先证明固定类型的实例,感应起作用。在示例中,是nat
的归纳。然后得出一个在类型本身中推广的证明。
答案 1 :(得分:3)
当定理从已修复类型变量的块导出时,自由类型变量在定理中成为示意图。特别是,您无法量化块中的类型变量,然后在块中实例化类型变量,就像您在归纳中尝试的那样。对类型的任意量化导致HOL不一致,因此几乎没有希望可以改变它。
幸运的是,有一种方法可以在没有类型量化的情况下证明您的CPS风格的引理。问题是你的陈述不够通用,因为它包含id
。如果你推广它,那么证明就可以了:
lemma add_k_cps: "add_k n m (k ∘ f) = k (add_k n m f)"
proof(induction n arbitrary: f)
case 0 show ?case by simp
next
case (Suc n)
have "add_k (Suc n) m (k ∘ f) = add_k n m (k ∘ (λn'. f (Suc n')))" by(simp add: o_def)
also have "… = k (add_k n m (λn'. f (Suc n')))"
using Suc.IH[where f="(λn'. f (Suc n'))"] by metis
also have "… = k (add_k (Suc n) m f)" by simp
finally show ?case .
qed
如果选择f = id
,则会得到原始定理。