如何确保类型变量的实例化是不同的

时间:2015-07-20 15:39:18

标签: isabelle

在Isabelle中,有没有办法确保区域设置或命题中两个类型变量的实例化不同?

对于一个具体的例子,我想推断一个复合实体而不提交特定的表示。为此,我定义了一类组件,对它们进行了一些操作:

class Component = fixes oper :: "'a ⇒ 'a"

我还定义了一个具有相同操作的Composite,通过为组件应用组件和选择器来解除它们:

class Composite = Component (* + ... *)

locale ComponentAccess = 
  fixes set :: "'c :: Composite ⇒ 'a :: Component ⇒ 'c"
  and get :: "'c ⇒ 'a"
  assumes (* e.g. *) "get (set c a) = a"
  and "set c (get c) = c"
  and "oper (set c1 a1) = set (oper c1) (oper a2)"

现在我想说明成对复合的一些公理,例如:

locale CompositeAxioms =
  a: ComponentAccess set get + b: ComponentAccess set' get'
  for set :: "'c :: Composite ⇒ 'a1 :: Component ⇒ 'c"
  and get :: "'c ⇒ 'a1"
  and set' :: "'c ⇒ 'a2 :: Component ⇒ 'c" 
  and get' :: "'c ⇒ 'a2" +
  assumes set_disj_commut: "set' (set c a1) a2 = set (set' c a2) a1"

但是,如果将'a1'a2实例化为不同类型,则上述法律才有意义。否则,我们会轻而易举地产生不必要的后果,例如恢复组件设置:

lemma 
  fixes set get
  assumes "CompositeAxioms set get set get"
  shows "set (set c a1) a2 = set (set c a2) a1"
using assms CompositeAxioms.set_disj_commut by blast

在上面的语言环境中假设,有没有办法确保'a1'a2始终被实例化为不同的类型?

更新(澄清)。实际上,只有当setset'不同时,“法律”才有意义。但是,我必须比较不同类型的两个功能,我认为这是不可能的。由于我在类型类中定义了get / set操作并使用排序约束来确保组合具有某些组件,因此我的gets和sets总是在组件类型上不同。因此问题。

1 个答案:

答案 0 :(得分:4)

您可以在Isabelle / HOL中通过使用类型的反映作为术语来表达两种类型。为此,类型必须是可表示的,即实例化类typerep。 HOL中的大多数类型都是这样做的。然后,你可以写

TYPEREP('a) ~= TYPEREP('b)

表示'a'b只能实例化为不同类型。但是,TYPEREP通常仅用于内部目的(特别是在代码生成器中),因此没有可用的推理基础结构,我不知道如何利用这样的假设。

无论如何,我想知道你为什么要制定这样的约束。如果用户将两个组件相同的区域设置CompositeAxioms实例化(并保留setset'的交换法则),则必须显示交换法则的用户。如果他可以,那么set函数有点奇怪,但健全性不受影响。此外,像TYPEREP('a) ~= TYPEREP('b)这样的区域设置假设会不必要地限制您的开发的一般性,对setget使用具有不同实例的相同表示类型可能是完全合理的。