在Isabelle中使用参数定义子类
(第3.5节)通过提供缺失公理的证明,解释了如何定义“事实之后”的附加子类关系。当子类在公理之外添加参数时,有没有办法做到这一点 例如,假设我有以下类:在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"
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
asetoid
的任何实例,但必须手动执行。对于每个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"})
*}