在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
始终被实例化为不同的类型?
更新(澄清)。实际上,只有当set
和set'
不同时,“法律”才有意义。但是,我必须比较不同类型的两个功能,我认为这是不可能的。由于我在类型类中定义了get / set操作并使用排序约束来确保组合具有某些组件,因此我的gets和sets总是在组件类型上不同。因此问题。
答案 0 :(得分:4)
您可以在Isabelle / HOL中通过使用类型的反映作为术语来表达两种类型。为此,类型必须是可表示的,即实例化类typerep
。 HOL中的大多数类型都是这样做的。然后,你可以写
TYPEREP('a) ~= TYPEREP('b)
表示'a
和'b
只能实例化为不同类型。但是,TYPEREP
通常仅用于内部目的(特别是在代码生成器中),因此没有可用的推理基础结构,我不知道如何利用这样的假设。
无论如何,我想知道你为什么要制定这样的约束。如果用户将两个组件相同的区域设置CompositeAxioms
实例化(并保留set
和set'
的交换法则),则必须显示交换法则的用户。如果他可以,那么set
函数有点奇怪,但健全性不受影响。此外,像TYPEREP('a) ~= TYPEREP('b)
这样的区域设置假设会不必要地限制您的开发的一般性,对set
和get
使用具有不同实例的相同表示类型可能是完全合理的。