Haskell 支持(多)子类型化/子类化的定理证明器/证明助手

Haskell 支持(多)子类型化/子类化的定理证明器/证明助手,haskell,coq,isabelle,agda,theorem-proving,Haskell,Coq,Isabelle,Agda,Theorem Proving,简而言之,我正在寻找一个定理证明器,它的底层逻辑支持多个子类型/子类型化机制(我尝试使用Isabelle,但它似乎没有为子类型提供一流的支持) 我想定义几个类型,其中一些是其他类型的子类/子类型。此外,每个类型可能是多个类型的子类型。例如: Type A Type B Type C Type E Type F C is subtype of A C is also subtype of B E and F are subtypes of B record Monoid (A : Set)

简而言之,我正在寻找一个定理证明器,它的底层逻辑支持多个子类型/子类型化机制(我尝试使用Isabelle,但它似乎没有为子类型提供一流的支持)

我想定义几个类型,其中一些是其他类型的子类/子类型。此外,每个类型可能是多个类型的子类型。例如:

Type A
Type B
Type C
Type E
Type F

C is subtype of A
C is also subtype of B
E and F are subtypes of B
  record Monoid (A : Set) : Set where
    constructor monoid
    field
      z   : A
      m+  : A -> A -> A
      xz  : (x : A) -> m+ x z == x
      zx  : (x : A) -> m+ z x == x
      assoc : (x : A) -> (y : A) -> (z : A) -> m+ (m+ x y) z == m+ x (m+ y z)
  open Monoid public
附言: 我再次编辑这个问题是为了更具体(因为有人抱怨这是一个主题!):我正在寻找一个定理证明者/证明帮助,我可以用一种直接的方式定义上面的结构(而不是使用变通方法,因为这里有一些值得尊敬的答案很好地描述了它)。如果我把这些类型当作类,那么上面的子类型可以是<强> > < <强> > C++!因此,我正在寻找一个正式的系统/工具,我可以在那里定义这样一个子类型结构,我可以推理


非常感谢在
agda
中有很多方法可以实现这一点

  • 将与一个“类型”相关的功能分组到
    record
  • 为所需类型构造此类
    记录的实例
  • 把记录传给需要的证据
例如:

Type A
Type B
Type C
Type E
Type F

C is subtype of A
C is also subtype of B
E and F are subtypes of B
  record Monoid (A : Set) : Set where
    constructor monoid
    field
      z   : A
      m+  : A -> A -> A
      xz  : (x : A) -> m+ x z == x
      zx  : (x : A) -> m+ z x == x
      assoc : (x : A) -> (y : A) -> (z : A) -> m+ (m+ x y) z == m+ x (m+ y z)
  open Monoid public

现在,
list is monoid=monoid Nil(++)引理append Nil引理Nil append引理append assoc
实例化(证明)一个
list
是一个
monoid
(给出了
Nil
是一个中性元素的证明和一个关联性证明)。

你包括了'isabelle'标记,碰巧根据,伊莎贝尔提供了一种形式的子类型,“强制子类型”,尽管正如安德烈亚斯·洛赫比勒所解释的,伊莎贝尔并没有你想要的(以及其他人想要的)子类型

然而,你说的是模糊的概括性,所以我很容易提供一个符合你的5种类型要求的人为的例子。虽然这是人为的,但正如我在下面解释的那样,这并不是毫无意义的

(*The 5 types.*)
  datatype tA = tA_con int rat real
  type_synonym tB = "(nat * int)"
  type_synonym tC = int
  type_synonym tE = rat
  type_synonym tF = real

(*The small amount of code required to automatically coerce from tC to tB.*)
  fun coerce_C_to_B :: "tC => tB" where "coerce_C_to_B i = (0, i)"
  declare [[coercion coerce_C_to_B]]

(*I can use type tC anywhere I can use type tB.*)
  term "(2::tC)::tB"
  value "(2::tC)::tB"
在上面的示例中,可以看到类型
tC
tE
tF
自然且容易地被强制为类型
tA
tB

这种类型的强制在伊莎贝尔身上做得相当多。例如,类型
nat
用于定义
int
,而
int
用于定义
rat
。因此,
nat
会自动强制为
int
,尽管
int
不会强制为
rat

Wrap I(您没有使用过规范HOL):
  • 在前面的问题示例中,您一直在使用
    typedecl
    引入新类型,而这通常并不反映人们如何定义新类型。
    • typedecl
      定义的类型几乎总是基本的和公理化的,例如在Nat.thy中用
      ind
    • 请参见此处:isabelle.in.tum.de/repos/isabelle/file/8f4a332500e4/src/HOL/Nat.thy#l21
  • 关键字
    datatype\u new
    是在Isabelle/HOL中定义新类型的主要自动方法之一。
    • datatype\u new
      (和
      datatype
      )的部分功能是用于定义递归类型,以及与
      fun
      一起使用,例如与模式匹配
    • 与其他证明助手相比,我假设
      datatype\u new
      的新功能并非微不足道。例如,类型和ZFC集之间的一个区别在于ZFC集可以嵌套任意深。现在,使用
      datatype\u new
      ,可以定义一种可以嵌套任意深度的可数集或有限集
  • 您可以使用标准类型(如元组、列表和记录)来定义新类型,然后可以将其与强制一起使用,如上面的示例所示
Wrap II(但是,是的,那会很好): 我本可以继续上面的列表,但我从列表中分离出另外两个关键字来定义新类型,
typedef
quotient\u type

我把这两个分开是因为,现在,我们进入了你抱怨的领域,伊莎贝尔/荷尔的逻辑在很多时候都不容易定义类型/子类型关系

我知道的不多,现在我知道我应该只使用
typedef
作为最后手段。它实际上在HOL源代码中使用了很多,但是,开发人员随后必须做大量工作,使用它定义的类型易于使用,例如使用
fset

Wrap III(然而,在这个不完美的世界中,没有一个是完美的): 您列出了可能拥有最大市场份额的3个证明助手,Coq、Isabelle和Agda

使用证明助手,我们定义您的优先级,进行研究,然后选择一个,但这与编程语言类似。我们不会和他们中的任何一个一起得到一切

对我来说,数学语法和结构化证明非常重要。伊莎贝尔似乎足够强大,所以我选择了它。当然,这不是一个完美的世界

Wrap IV(Haskell、Isabelle和type类): 事实上,Isabelle确实有一种非常强大的子类化形式,“类型类”

嗯,它很强大,但也有局限性,因为在定义类型类时只能使用一个类型变量

如果您查看Groups.thy,您将看到一个又一个类的介绍,以创建类的层次结构

  • isabelle.in.tum.de/repos/isabelle/file/8f4a332500e4/src/HOL/Groups.thy
您还包括“haskell”标签。Isabelle/HOL的函数式编程属性及其
数据类型和类型类有助于将Isabelle/HOL的使用与Haskell的使用联系起来,Isabelle代码生成器生成