在Isabelle中使用参数定义子类

在Isabelle中使用参数定义子类,isabelle,Isabelle,(第3.5节)通过提供缺失公理的证明,解释了如何定义“事实之后”的附加子类关系。当子类在公理之外添加参数时,有没有办法做到这一点 例如,假设我有以下类: class setoid = fixes eq :: "'a ⇒ 'a ⇒ bool" (infix "≈" 50) assumes eq_refl : "∀x. x ≈ x" and eq_symm : "∀x y. x ≈ y ⟶ y ≈ x" and eq_trans : "∀x y z. x ≈ y ⟶ y ≈ z ⟶ x ≈ z"

(第3.5节)通过提供缺失公理的证明,解释了如何定义“事实之后”的附加子类关系。当子类在公理之外添加参数时,有没有办法做到这一点

例如,假设我有以下类:

class setoid =
fixes eq :: "'a ⇒ 'a ⇒ bool" (infix "≈" 50)
assumes eq_refl : "∀x. x ≈ x"
and eq_symm : "∀x y. x ≈ y ⟶ y ≈ x"
and eq_trans : "∀x y z. x ≈ y ⟶ y ≈ z ⟶ x ≈ z"

class preorder =
fixes le :: "'a ⇒ 'a ⇒ bool" (infix "≲" 50)
assumes le_refl : "∀x. x ≲ x"
and le_trans : "∀x y z. x ≲ y ⟶ y ≲ z ⟶ x ≲ z"
当我们对称化其不等式时,每个前序都应该是一个集形:

definition (in preorder) peq :: "'a ⇒ 'a ⇒ bool"
where "peq x y ≡ (x ≲ y) ∧ (y ≲ x)"
但是,以下操作失败:

subclass (in preorder) setoid
引发错误
异常类型:类预订单缺少setoid的参数“setoid\u Class.eq”。但是我想不出一个语法来告诉Isabelle这个缺少的参数应该是我定义的关系
peq

如果我选择locale而不是typeclasses(为简洁起见省略了证明),我就可以做到这一点:


但这不允许我将
预排序
用作
setoid
,即
解释
不像
子类
实例化
。我想要的是能够将一个类型实例化为一个前序,然后通过不等式的对称化,自动地使用关于该类型上集合集的定义和定理。如何实现这一点?

这是对Isabelle中类型类实现方式的限制。我不确定以下解决方案是否尽可能短,但它确实有效:

class eq =
  fixes eq :: "'a ⇒ 'a ⇒ bool" (infix "≈" 50)

class setoid = eq +
  assumes eq_refl : "∀x. x ≈ x"
    and eq_symm : "∀x y. x ≈ y ⟶ y ≈ x"
    and eq_trans : "∀x y z. x ≈ y ⟶ y ≈ z ⟶ x ≈ z"

class preorder =
  fixes le :: "'a ⇒ 'a ⇒ bool" (infix "≲" 50)
  assumes le_refl : "∀x. x ≲ x"
    and le_trans : "∀x y z. x ≲ y ⟶ y ≲ z ⟶ x ≲ z"

class preorder_setoid = preorder + eq +
  assumes eq_def: "x ≈ y ⟷ (x ≲ y) ∧ (y ≲ x)"

subclass (in preorder_setoid) setoid
  apply standard
  unfolding eq_def
  using le_refl le_trans by auto
缺点是您仍然无法自动生成
preorder
a
setoid
的任何实例,但必须手动执行。对于每个
preorder
实例,您可以添加一个
preorder\u setoid
实例。所有这些看起来都一样;他们必须根据
eq_def
定义
eq
。然后自动进行校对

更新正如评论中指出的那样,
eq
常量将始终在
eq
类的上下文中解释;i、 例如,如果没有进一步的类型注释,就无法证明任何有趣的东西。可以告诉类型推断做得更好:

setup {*
  Sign.add_const_constraint (@{const_name "eq"}, SOME @{typ "'a::setoid ⇒ 'a ⇒ bool"})
*}

谢谢我的经验表明,这种方法的另一个缺点是符号
不是附加到
setoid
类,而是附加到
eq
类,因此Isabelle不会自动推断应用它的变量必须属于类
setoid
的类型。是这样吗?这是正确的,但有一些技巧。我将相应地更新我的答案。在给出
setup
类型推断指令后,是否可以注释
eq
的特定用法,以“关闭”其参数属于setoid的假设?特别是,在发出
setup
命令后,是否有方法定义类
preorder\u setoid
?(例如,如果setoid和preorder是在不同的理论中定义的,那么在setoid文件中给出
setup
命令是很自然的,然后由preorder理论导入。)您可以在定义
setoid
之后立即发出
setup
声明。但是,当您定义
preorder\u setoid
时,首先必须使用另一个
setup
声明删除额外的排序约束,然后再次添加它。与原始
setup
声明相同,但不是将
setoid
作为排序约束,而是提供其他约束(如
eq
)。
setup {*
  Sign.add_const_constraint (@{const_name "eq"}, SOME @{typ "'a::setoid ⇒ 'a ⇒ bool"})
*}