如何声明一个不尊重排序约束的引理(使用OFCLASS)
我该如何声明Isabelle/HOL中不遵守排序约束的引理?如何声明一个不尊重排序约束的引理(使用OFCLASS)
要解释为什么这是有道理的,请看下面的例子理论:
theory Test
imports Main
begin
class embeddable =
fixes embedding::"'a ⇒ nat"
assumes "inj embedding"
lemma OFCLASS_I:
assumes "inj (embedding::'a⇒_)"
shows "OFCLASS('a::type,embeddable_class)"
apply intro_classes by (fact assms)
instantiation nat :: embeddable begin
definition "embedding = id"
instance
apply (rule OFCLASS_I) unfolding embedding_nat_def by simp
end
end
这种理论定义了一个类型的类“嵌入”用一个类型参数“嵌入”。 (基本上,可嵌入类通过明确枚举来表征可数数字,但我选择这只是一个非常简单的例子。)
为了简化类型类的实例验证,理论指出了一个辅助引理OFCLASS_I
,它显示目标的形式OFCLASS(...,embeddable)
。这个引理可以用来解决instance
产生的证明义务。
首先,我为什么要这么做? (在本理论,apply (rule OFCLASS_I)
确实相同内建apply intro_classes
,因此是无用的。)在更复杂的情况下,有两个原因这样的引理:
- 该引理可以给替代标准的一个实例类型的类,使后续的证明更简单。
- 引理可用于自动化(ML级)实例。这里使用
intro_classes
是有问题的,因为intro_classes
的子目标数量可能会根据之前执行的实例证明而有所不同。 (A引理如OFCLASS_I
具有稳定的,良好控制的子目标。)
然而,上述理论没有在伊莎贝尔/ HOL(均未2015或2016-RC1)工作,因为引理不类型检查。排序约束“embedding ::(_ :: embeddable => _)”不满足。然而,这种类型的限制并不是逻辑必然性(它不是由逻辑内核强制执行,而是由更高级别执行)。
那么,有没有一种清楚的陈述上述理论的方法? (我在答案中给出了一个稍微难看的解决方案,但我正在寻找更清洁的东西。)
以下是一个不同的解决方案,在证明引理之后不需要“清理”(this answer需要“修复”之后的排序约束)。
的思想是定义一个新的常数(embedding_UNCONSTRAINED
在我的例子),其的一个副本的原始排序约束常数(embedding
),除了没有排序约束(使用下面的local_setup
命令)。然后引理使用embedding_UNCONSTRAINED
而不是embedding
陈述。但通过添加属性[unfolded embedding_UNCONSTRAINED_def]
实际存储的引理使用常量embedding
没有排序约束。
这种方法的缺点是,在引理的证明过程中,我们永远不能明确地写出包含embedding
的任何术语(因为这会增加不需要的排序约束)。但是如果我们需要声明一个包含embedding
的子目标,我们可以始终使用embedding_UNCONSTRAINED
来表示它,然后使用例如unfolding embedding_UNCONSTRAINED
将其转换为embedding
。
theory Test
imports Main
begin
class embeddable =
fixes embedding::"'a ⇒ nat"
assumes "inj embedding"
(* This does roughly:
definition "embedding_UNCONSTRAINED == (embedding::('a::type)=>nat)" *)
local_setup {*
Local_Theory.define ((@{binding embedding_UNCONSTRAINED},NoSyn),((@{binding embedding_UNCONSTRAINED_def},[]),
Const(@{const_name embedding},@{typ "'a ⇒ nat"}))) #> snd
*}
lemma OFCLASS_I [unfolded embedding_UNCONSTRAINED_def]:
assumes "inj (embedding_UNCONSTRAINED::'a⇒_)"
shows "OFCLASS('a::type,embeddable_class)"
apply intro_classes by (fact assms[unfolded embedding_UNCONSTRAINED_def])
thm OFCLASS_I (* The theorem now uses "embedding", but without sort "embeddable" *)
instantiation nat :: embeddable begin
definition "embedding = id"
instance
apply (rule OFCLASS_I) unfolding embedding_nat_def by simp
end
end
可以在ML级别暂时禁用排序约束的检查,然后再重新激活。 (请参阅下面的完整示例。)但是,该解决方案看起来非常像黑客。我们必须改变上下文中的排序约束,并记住在之后恢复它们。
theory Test
imports Main
begin
class embeddable =
fixes embedding::"'a ⇒ nat"
assumes "inj embedding"
ML {*
val consts_to_unconstrain = [@{const_name embedding}]
val consts_orig_constraints = map (Sign.the_const_constraint
@{theory}) consts_to_unconstrain
*}
setup {*
fold (fn c => fn thy => Sign.add_const_constraint (c,NONE) thy) consts_to_unconstrain
*}
lemma OFCLASS_I:
assumes "inj (embedding::'a⇒_)"
shows "OFCLASS('a::type,embeddable_class)"
apply intro_classes by (fact assms)
(* Recover stored type constraints *)
setup {*
fold2 (fn c => fn T => fn thy => Sign.add_const_constraint
(c,SOME (Logic.unvarifyT_global T)) thy)
consts_to_unconstrain consts_orig_constraints
*}
instantiation nat :: embeddable begin
definition "embedding = id"
instance
apply (rule OFCLASS_I) unfolding embedding_nat_def by simp
end
end
这个理论被Isabelle/HOL接受。该方法在更复杂的设置中工作(我已经使用过几次),但我更喜欢更优雅的设置。