如何保证类型变量的实例化是不同的
How to ensure that instantiations of type variables are different
在 Isabelle 中,有没有办法确保在语言环境或命题中两个类型变量的实例化是不同的?
举一个具体的例子,我想在不承诺特定表示的情况下对复合实体进行推理。为此,我定义了一个 class 组件,并对其进行了一些操作:
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'
不同时,'law' 才有意义。但是我将不得不比较不同类型的两个函数,我认为这是不可能的。由于我在 classes 类型中定义了 get/set 操作,并使用排序约束来确保组合具有某些组件,所以我的 gets 和 set 总是在组件类型上不同。因此问题。
你可以在Isabelle/HOL中用类型的反射作为术语来表达两种类型的不同。为此,类型必须是可表示的,即实例化 class typerep
。 HOL 中的大多数类型都这样做。然后,你可以写
TYPEREP('a) ~= TYPEREP('b)
表示'a
和'b
只能实例化为不同的类型。但是,TYPEREP
通常仅用于内部目的(尤其是在代码生成器中),因此没有可用的推理基础设施,我不知道如何利用这样的假设。
无论如何,我想知道你为什么要制定这样一个约束条件。如果用户实例化您的语言环境 CompositeAxioms
并且两个组件相同(并保留 set
和 set'
的交换法则),则必须由用户显示交换法则.如果他可以,那么 set
功能有点奇怪,但不影响健全性。此外,像 TYPEREP('a) ~= TYPEREP('b)
这样的语言环境假设会不必要地限制您开发的通用性,对于 set
和 get
.[= 使用具有不同实例的相同表示类型可能是完全明智的吗? 22=]
在 Isabelle 中,有没有办法确保在语言环境或命题中两个类型变量的实例化是不同的?
举一个具体的例子,我想在不承诺特定表示的情况下对复合实体进行推理。为此,我定义了一个 class 组件,并对其进行了一些操作:
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'
不同时,'law' 才有意义。但是我将不得不比较不同类型的两个函数,我认为这是不可能的。由于我在 classes 类型中定义了 get/set 操作,并使用排序约束来确保组合具有某些组件,所以我的 gets 和 set 总是在组件类型上不同。因此问题。
你可以在Isabelle/HOL中用类型的反射作为术语来表达两种类型的不同。为此,类型必须是可表示的,即实例化 class typerep
。 HOL 中的大多数类型都这样做。然后,你可以写
TYPEREP('a) ~= TYPEREP('b)
表示'a
和'b
只能实例化为不同的类型。但是,TYPEREP
通常仅用于内部目的(尤其是在代码生成器中),因此没有可用的推理基础设施,我不知道如何利用这样的假设。
无论如何,我想知道你为什么要制定这样一个约束条件。如果用户实例化您的语言环境 CompositeAxioms
并且两个组件相同(并保留 set
和 set'
的交换法则),则必须由用户显示交换法则.如果他可以,那么 set
功能有点奇怪,但不影响健全性。此外,像 TYPEREP('a) ~= TYPEREP('b)
这样的语言环境假设会不必要地限制您开发的通用性,对于 set
和 get
.[= 使用具有不同实例的相同表示类型可能是完全明智的吗? 22=]