如何声明不考虑排序约束的引理(使用OFCLASS)

时间:2016-01-24 10:46:03

标签: isabelle

我怎样才能说出Isabelle / HOL中不符合排序约束的引理?

要解释为什么这是有意义的,请考虑以下示例理论:

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

该理论定义了一种类型“嵌入式”,其中一种类型参数为“嵌入”。 (基本上,embeddable类使用显式枚举来表示可数数字,但我选择它只是为了得到一个非常简单的例子。)

为了简化类型类的实例证明,该理论陈述了一个辅助引理OFCLASS_I,它显示了OFCLASS(...,embeddable)形式的目标。然后可以使用此引理来解决instance产生的证明义务。

首先,为什么我甚至想要那个? (在目前的理论中,apply (rule OFCLASS_I)与内置apply intro_classes的作用相同,因此没用。)在更复杂的情况下,这种引理有两个原因:

  • 引理可以为类型类的实例化提供替代标准,使后续证明更简单。
  • 引理可用于自动(ML级)实例化。这里使用intro_classes是有问题的,因为intro_classes的子目标数量可能会有所不同,具体取决于先前已执行的实例证明。 (像OFCLASS_I这样的引理有一个稳定的,控制良好的子目标。)

然而,上述理论在Isabelle / HOL(2015或2016-RC1)中均无效,因为引理不进行类型检查。不满足排序约束“embedding ::(_ :: embeddable => _)”。但是,这种类型的约束并不是逻辑必然(它不是由逻辑内核强制执行,而是由更高级别强制执行)。

那么,是否有一种说明上述理论的简洁方法? (我在答案中给出了一个有点丑陋的解决方案,但我正在寻找更清洁的东西。)

2 个答案:

答案 0 :(得分:0)

可以在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接受。该方法适用于更复杂的设置(我已多次使用它),但我更喜欢更优雅的设置。

答案 1 :(得分:0)

以下是一个不同的解决方案,不需要"清理"在证明引理之后(this answer需要"修复"之后的排序约束)。

我的想法是定义一个新的常量(在我的例子中为embedding_UNCONSTRAINED),它是原始排序约束常量(embedding)的副本,除了没有排序约束(使用{{1以下命令)。然后使用local_setup代替embedding_UNCONSTRAINED来说明引理。但是通过添加属性embedding,实际存储的引理使用常量[unfolded embedding_UNCONSTRAINED_def]而没有排序约束。

这种方法的缺点是,在引证的证明期间,我们永远不能明确地写出包含embedding的任何术语(因为这会添加不需要的排序约束)。但是,如果我们需要声明包含embedding的子目标,我们可以始终使用embedding说明它,然后使用embedding_UNCONSTRAINED将其转换为unfolding embedding_UNCONSTRAINED

embedding