在精益中解决 "diamond inheritance" class
Resolving a "diamond inheritance" class in lean
对于精益,我有一个非常基本的循环结构。我为岩浆构造了一个 class,为准群(抵消岩浆)构造了一个 class,为单位岩浆构造了一个 class。从那里开始,环就是既是准群又是单位岩浆的东西。
在 Haskell 中看起来像
class Magma a where
add :: a -> a -> a
class Magma a => Unital a where
unit :: a
class Magma a => Quasigroup a where
left_div :: a -> a -> a
right_div :: a -> a -> a
class (Quasigroup a, Unital a) => Loop a
所以我试着把它翻译成精益:
universe u
class magma (α : Type u) :=
( add : α → α → α )
class unital (α : Type u) extends magma α :=
( unit : α )
( left_id : ∀ a : α, add unit a = a )
( right_id : ∀ a : α, add a unit = a )
class quasigroup (α : Type u) extends magma α :=
( left_div : α → α → α )
( right_div : α → α → α )
( left_cancel : ∀ a b : α, add a (left_div a b) = b )
( right_cancel : ∀ a b : α, add (right_div b a) a = b )
class loop (α : Type u) extends quasigroup α, unital α
但是 lean 抱怨说:
invalid 'structure' header, field 'to_magma' from 'unital' has already been declared
这很神秘,但如果我们尝试一下,就会发现这是类似于钻石继承的某种问题。它不喜欢我们从 loop
到 magma
的两条路径。
如何判断 lean 这些是相同的岩浆并解决这个问题?
在 Lean 3.35.1 上,您有几种可能的解决方案。对于类似 Haskell 的记录合并,有 old_structure_cmd
:
universe u
class magma (α : Type u) :=
(add : α → α → α)
class unital (α : Type u) extends magma α :=
(unit : α)
(left_id : ∀ a : α, add unit a = a)
(right_id : ∀ a : α, add a unit = a)
class quasigroup (α : Type u) extends magma α :=
(left_div : α → α → α)
(right_div : α → α → α)
(left_cancel : ∀ a b : α, add a (left_div a b) = b)
(right_cancel : ∀ a b : α, add (right_div b a) a = b)
set_option old_structure_cmd true
class loop (α : Type u) extends quasigroup α, unital α.
这将如您所愿。然而,old_structure_cmd
的缺点是结构都被“扁平化”并变大了。 “新”方式是拥有结构的主要“主干”,并创建分支继承:
universe u
class magma (α : Type u) :=
(add : α → α → α)
class unital (α : Type u) extends magma α :=
(unit : α)
(left_id : ∀ a : α, add unit a = a)
(right_id : ∀ a : α, add a unit = a)
class quasigroup (α : Type u) extends magma α :=
(left_div : α → α → α)
(right_div : α → α → α)
(left_cancel : ∀ a b : α, add a (left_div a b) = b)
(right_cancel : ∀ a b : α, add (right_div b a) a = b)
class loop (α : Type u) extends quasigroup α :=
(unit : α)
(left_id : ∀ a : α, add unit a = a)
(right_id : ∀ a : α, add a unit = a)
instance loop.to_unital {α : Type u} [h : loop α] : unital α :=
{ ..h }
对于精益,我有一个非常基本的循环结构。我为岩浆构造了一个 class,为准群(抵消岩浆)构造了一个 class,为单位岩浆构造了一个 class。从那里开始,环就是既是准群又是单位岩浆的东西。
在 Haskell 中看起来像
class Magma a where
add :: a -> a -> a
class Magma a => Unital a where
unit :: a
class Magma a => Quasigroup a where
left_div :: a -> a -> a
right_div :: a -> a -> a
class (Quasigroup a, Unital a) => Loop a
所以我试着把它翻译成精益:
universe u
class magma (α : Type u) :=
( add : α → α → α )
class unital (α : Type u) extends magma α :=
( unit : α )
( left_id : ∀ a : α, add unit a = a )
( right_id : ∀ a : α, add a unit = a )
class quasigroup (α : Type u) extends magma α :=
( left_div : α → α → α )
( right_div : α → α → α )
( left_cancel : ∀ a b : α, add a (left_div a b) = b )
( right_cancel : ∀ a b : α, add (right_div b a) a = b )
class loop (α : Type u) extends quasigroup α, unital α
但是 lean 抱怨说:
invalid 'structure' header, field 'to_magma' from 'unital' has already been declared
这很神秘,但如果我们尝试一下,就会发现这是类似于钻石继承的某种问题。它不喜欢我们从 loop
到 magma
的两条路径。
如何判断 lean 这些是相同的岩浆并解决这个问题?
在 Lean 3.35.1 上,您有几种可能的解决方案。对于类似 Haskell 的记录合并,有 old_structure_cmd
:
universe u
class magma (α : Type u) :=
(add : α → α → α)
class unital (α : Type u) extends magma α :=
(unit : α)
(left_id : ∀ a : α, add unit a = a)
(right_id : ∀ a : α, add a unit = a)
class quasigroup (α : Type u) extends magma α :=
(left_div : α → α → α)
(right_div : α → α → α)
(left_cancel : ∀ a b : α, add a (left_div a b) = b)
(right_cancel : ∀ a b : α, add (right_div b a) a = b)
set_option old_structure_cmd true
class loop (α : Type u) extends quasigroup α, unital α.
这将如您所愿。然而,old_structure_cmd
的缺点是结构都被“扁平化”并变大了。 “新”方式是拥有结构的主要“主干”,并创建分支继承:
universe u
class magma (α : Type u) :=
(add : α → α → α)
class unital (α : Type u) extends magma α :=
(unit : α)
(left_id : ∀ a : α, add unit a = a)
(right_id : ∀ a : α, add a unit = a)
class quasigroup (α : Type u) extends magma α :=
(left_div : α → α → α)
(right_div : α → α → α)
(left_cancel : ∀ a b : α, add a (left_div a b) = b)
(right_cancel : ∀ a b : α, add (right_div b a) a = b)
class loop (α : Type u) extends quasigroup α :=
(unit : α)
(left_id : ∀ a : α, add unit a = a)
(right_id : ∀ a : α, add a unit = a)
instance loop.to_unital {α : Type u} [h : loop α] : unital α :=
{ ..h }