File: Mathlib/Algebra/Quandle.lean

full_name: Shelf.self_distrib
code: /-- A *Shelf* is a structure with a self-distributive binary operation.
The binary operation is regarded as a left action of the type on itself.
-/
class Shelf (α : Type u) where
  /-- The action of the `Shelf` over `α`-/
  act : α → α → α
  /-- A verification that `act` is self-distributive-/
  self_distrib : ∀ {x y z : α}, act x (act y z) = act (act x y) (act x z)
goal: x ◃ y ◃ z = (x ◃ y) ◃ x ◃ z

full_name: Shelf
code: /-- A *Shelf* is a structure with a self-distributive binary operation.
The binary operation is regarded as a left action of the type on itself.
-/
class Shelf (α : Type u) where
  /-- The action of the `Shelf` over `α`-/
  act : α → α → α
  /-- A verification that `act` is self-distributive-/
  self_distrib : ∀ {x y z : α}, act x (act y z) = act (act x y) (act x z)
goal: Type u

full_name: Shelf.act
code: /-- A *Shelf* is a structure with a self-distributive binary operation.
The binary operation is regarded as a left action of the type on itself.
-/
class Shelf (α : Type u) where
  /-- The action of the `Shelf` over `α`-/
  act : α → α → α
  /-- A verification that `act` is self-distributive-/
  self_distrib : ∀ {x y z : α}, act x (act y z) = act (act x y) (act x z)
goal: α → α → α

full_name: UnitalShelf
code: /--
A *unital shelf* is a shelf equipped with an element `1` such that, for all elements `x`,
we have both `x ◃ 1` and `1 ◃ x` equal `x`.
-/
class UnitalShelf (α : Type u) extends Shelf α, One α :=
(one_act : ∀ a : α, act 1 a = a)
(act_one : ∀ a : α, act a 1 = a)
goal: Type u

full_name: UnitalShelf.one_act
code: /--
A *unital shelf* is a shelf equipped with an element `1` such that, for all elements `x`,
we have both `x ◃ 1` and `1 ◃ x` equal `x`.
-/
class UnitalShelf (α : Type u) extends Shelf α, One α :=
(one_act : ∀ a : α, act 1 a = a)
(act_one : ∀ a : α, act a 1 = a)
goal: 1 ◃ a = a

full_name: UnitalShelf.act_one
code: /--
A *unital shelf* is a shelf equipped with an element `1` such that, for all elements `x`,
we have both `x ◃ 1` and `1 ◃ x` equal `x`.
-/
class UnitalShelf (α : Type u) extends Shelf α, One α :=
(one_act : ∀ a : α, act 1 a = a)
(act_one : ∀ a : α, act a 1 = a)
goal: a ◃ 1 = a

full_name: ShelfHom.toFun
code: /-- The type of homomorphisms between shelves.
This is also the notion of rack and quandle homomorphisms.
-/
@[ext]
structure ShelfHom (S₁ : Type*) (S₂ : Type*) [Shelf S₁] [Shelf S₂] where
  /-- The function under the Shelf Homomorphism -/
  toFun : S₁ → S₂
  /-- The homomorphism property of a Shelf Homomorphism-/
  map_act' : ∀ {x y : S₁}, toFun (Shelf.act x y) = Shelf.act (toFun x) (toFun y)
goal: S₁ → S₂

full_name: ShelfHom.map_act'
code: /-- The type of homomorphisms between shelves.
This is also the notion of rack and quandle homomorphisms.
-/
@[ext]
structure ShelfHom (S₁ : Type*) (S₂ : Type*) [Shelf S₁] [Shelf S₂] where
  /-- The function under the Shelf Homomorphism -/
  toFun : S₁ → S₂
  /-- The homomorphism property of a Shelf Homomorphism-/
  map_act' : ∀ {x y : S₁}, toFun (Shelf.act x y) = Shelf.act (toFun x) (toFun y)
goal: self.toFun (x ◃ y) = self.toFun x ◃ self.toFun y

full_name: ShelfHom
code: /-- The type of homomorphisms between shelves.
This is also the notion of rack and quandle homomorphisms.
-/
@[ext]
structure ShelfHom (S₁ : Type*) (S₂ : Type*) [Shelf S₁] [Shelf S₂] where
  /-- The function under the Shelf Homomorphism -/
  toFun : S₁ → S₂
  /-- The homomorphism property of a Shelf Homomorphism-/
  map_act' : ∀ {x y : S₁}, toFun (Shelf.act x y) = Shelf.act (toFun x) (toFun y)
goal: Type (max u_1 u_2)

full_name: Rack.left_inv
code: /-- A *rack* is an automorphic set (a set with an action on itself by
bijections) that is self-distributive.  It is a shelf such that each
element's action is invertible.

The notations `x ◃ y` and `x ◃⁻¹ y` denote the action and the
inverse action, respectively, and they are right associative.
-/
class Rack (α : Type u) extends Shelf α where
  /-- The inverse actions of the elements -/
  invAct : α → α → α
  /-- Proof of left inverse -/
  left_inv : ∀ x, Function.LeftInverse (invAct x) (act x)
  /-- Proof of right inverse -/
  right_inv : ∀ x, Function.RightInverse (invAct x) (act x)
goal: Function.LeftInverse (Rack.invAct x) (Shelf.act x)

full_name: Rack.invAct
code: /-- A *rack* is an automorphic set (a set with an action on itself by
bijections) that is self-distributive.  It is a shelf such that each
element's action is invertible.

The notations `x ◃ y` and `x ◃⁻¹ y` denote the action and the
inverse action, respectively, and they are right associative.
-/
class Rack (α : Type u) extends Shelf α where
  /-- The inverse actions of the elements -/
  invAct : α → α → α
  /-- Proof of left inverse -/
  left_inv : ∀ x, Function.LeftInverse (invAct x) (act x)
  /-- Proof of right inverse -/
  right_inv : ∀ x, Function.RightInverse (invAct x) (act x)
goal: α → α → α

full_name: Rack.right_inv
code: /-- A *rack* is an automorphic set (a set with an action on itself by
bijections) that is self-distributive.  It is a shelf such that each
element's action is invertible.

The notations `x ◃ y` and `x ◃⁻¹ y` denote the action and the
inverse action, respectively, and they are right associative.
-/
class Rack (α : Type u) extends Shelf α where
  /-- The inverse actions of the elements -/
  invAct : α → α → α
  /-- Proof of left inverse -/
  left_inv : ∀ x, Function.LeftInverse (invAct x) (act x)
  /-- Proof of right inverse -/
  right_inv : ∀ x, Function.RightInverse (invAct x) (act x)
goal: Function.RightInverse (Rack.invAct x) (Shelf.act x)

full_name: Rack
code: /-- A *rack* is an automorphic set (a set with an action on itself by
bijections) that is self-distributive.  It is a shelf such that each
element's action is invertible.

The notations `x ◃ y` and `x ◃⁻¹ y` denote the action and the
inverse action, respectively, and they are right associative.
-/
class Rack (α : Type u) extends Shelf α where
  /-- The inverse actions of the elements -/
  invAct : α → α → α
  /-- Proof of left inverse -/
  left_inv : ∀ x, Function.LeftInverse (invAct x) (act x)
  /-- Proof of right inverse -/
  right_inv : ∀ x, Function.RightInverse (invAct x) (act x)
goal: Type u

full_name: Quandles._aux_Mathlib_Algebra_Quandle___unexpand_Shelf_act_1
code: /-- Action of a Shelf-/
scoped[Quandles] infixr:65 " ◃ " => Shelf.act
goal: Lean.PrettyPrinter.Unexpander

full_name: Quandles.«_aux_Mathlib_Algebra_Quandle___macroRules_Quandles_term_◃__1»
code: /-- Action of a Shelf-/
scoped[Quandles] infixr:65 " ◃ " => Shelf.act
goal: Lean.Macro

full_name: Quandles.«_aux_Mathlib_Algebra_Quandle___macroRules_Quandles_term_◃⁻¹__1»
code: /-- Inverse Action of a Rack-/
scoped[Quandles] infixr:65 " ◃⁻¹ " => Rack.invAct
goal: Lean.Macro

full_name: Quandles._aux_Mathlib_Algebra_Quandle___unexpand_Rack_invAct_1
code: /-- Inverse Action of a Rack-/
scoped[Quandles] infixr:65 " ◃⁻¹ " => Rack.invAct
goal: Lean.PrettyPrinter.Unexpander

full_name: Quandles.«_aux_Mathlib_Algebra_Quandle___macroRules_Quandles_term_→◃__1»
code: /-- Shelf Homomorphism-/
scoped[Quandles] infixr:25 " →◃ " => ShelfHom
goal: Lean.Macro

full_name: Quandles._aux_Mathlib_Algebra_Quandle___unexpand_ShelfHom_1
code: /-- Shelf Homomorphism-/
scoped[Quandles] infixr:25 " →◃ " => ShelfHom
goal: Lean.PrettyPrinter.Unexpander

full_name: UnitalShelf.act_act_self_eq
code: /--
A monoid is *graphic* if, for all `x` and `y`, the *graphic identity*
`(x * y) * x = x * y` holds.  For a unital shelf, this graphic
identity holds.
-/
lemma act_act_self_eq (x y : S) : (x ◃ y) ◃ x = x ◃ y 
goal: (x ◃ y) ◃ x = x ◃ y

full_name: UnitalShelf.act_idem
code: lemma act_idem (x : S) : (x ◃ x) = x 
goal: x ◃ x = x

full_name: UnitalShelf.act_self_act_eq
code: lemma act_self_act_eq (x y : S) : x ◃ (x ◃ y) = x ◃ y 
goal: x ◃ x ◃ y = x ◃ y

full_name: UnitalShelf.assoc
code: /--
The associativity of a unital shelf comes for free.
-/
lemma assoc (x y z : S) : (x ◃ y) ◃ z = x ◃ y ◃ z 
goal: (x ◃ y) ◃ z = x ◃ y ◃ z

full_name: Rack.act'
code: /-- A rack acts on itself by equivalences.
-/
def act' (x : R) : R ≃ R 
goal: R ≃ R

full_name: Rack.act'_apply
code: @[simp]
theorem act'_apply (x y : R) : act' x y = x ◃ y 
goal: (Rack.act' x) y = x ◃ y

full_name: Rack.act'_symm_apply
code: @[simp]
theorem act'_symm_apply (x y : R) : (act' x).symm y = x ◃⁻¹ y 
goal: (Rack.act' x).symm y = x ◃⁻¹ y

full_name: Rack.invAct_apply
code: @[simp]
theorem invAct_apply (x y : R) : (act' x)⁻¹ y = x ◃⁻¹ y 
goal: (Rack.act' x)⁻¹ y = x ◃⁻¹ y

full_name: Rack.invAct_act_eq
code: @[simp]
theorem invAct_act_eq (x y : R) : x ◃⁻¹ x ◃ y = y 
goal: x ◃⁻¹ x ◃ y = y

full_name: Rack.act_invAct_eq
code: @[simp]
theorem act_invAct_eq (x y : R) : x ◃ x ◃⁻¹ y = y 
goal: x ◃ x ◃⁻¹ y = y

full_name: Rack.left_cancel
code: theorem left_cancel (x : R) {y y' : R} : x ◃ y = x ◃ y' ↔ y = y' 
goal: x ◃ y = x ◃ y' ↔ y = y'

full_name: Rack.left_cancel_inv
code: theorem left_cancel_inv (x : R) {y y' : R} : x ◃⁻¹ y = x ◃⁻¹ y' ↔ y = y' 
goal: x ◃⁻¹ y = x ◃⁻¹ y' ↔ y = y'

full_name: Rack.self_distrib_inv
code: theorem self_distrib_inv {x y z : R} : x ◃⁻¹ y ◃⁻¹ z = (x ◃⁻¹ y) ◃⁻¹ x ◃⁻¹ z 
goal: x ◃⁻¹ y ◃⁻¹ z = (x ◃⁻¹ y) ◃⁻¹ x ◃⁻¹ z

full_name: Rack.ad_conj
code: /-- The *adjoint action* of a rack on itself is `op'`, and the adjoint
action of `x ◃ y` is the conjugate of the action of `y` by the action
of `x`. It is another way to understand the self-distributivity axiom.

This is used in the natural rack homomorphism `toConj` from `R` to
`Conj (R ≃ R)` defined by `op'`.
-/
theorem ad_conj {R : Type*} [Rack R] (x y : R) : act' (x ◃ y) = act' x * act' y * (act' x)⁻¹ 
goal: Rack.act' (x ◃ y) = Rack.act' x * Rack.act' y * (Rack.act' x)⁻¹

full_name: Rack.oppositeRack
code: /-- The opposite rack, swapping the roles of `◃` and `◃⁻¹`.
-/
instance oppositeRack : Rack Rᵐᵒᵖ 
goal: Rack Rᵐᵒᵖ

full_name: Rack.op_act_op_eq
code: @[simp]
theorem op_act_op_eq {x y : R} : op x ◃ op y = op (x ◃⁻¹ y) 
goal: MulOpposite.op x ◃ MulOpposite.op y = MulOpposite.op (x ◃⁻¹ y)

full_name: Rack.op_invAct_op_eq
code: @[simp]
theorem op_invAct_op_eq {x y : R} : op x ◃⁻¹ op y = op (x ◃ y) 
goal: MulOpposite.op x ◃⁻¹ MulOpposite.op y = MulOpposite.op (x ◃ y)

full_name: Rack.self_act_act_eq
code: @[simp]
theorem self_act_act_eq {x y : R} : (x ◃ x) ◃ y = x ◃ y 
goal: (x ◃ x) ◃ y = x ◃ y

full_name: Rack.self_invAct_invAct_eq
code: @[simp]
theorem self_invAct_invAct_eq {x y : R} : (x ◃⁻¹ x) ◃⁻¹ y = x ◃⁻¹ y 
goal: (x ◃⁻¹ x) ◃⁻¹ y = x ◃⁻¹ y

full_name: Rack.self_act_invAct_eq
code: @[simp]
theorem self_act_invAct_eq {x y : R} : (x ◃ x) ◃⁻¹ y = x ◃⁻¹ y 
goal: (x ◃ x) ◃⁻¹ y = x ◃⁻¹ y

full_name: Rack.self_invAct_act_eq
code: @[simp]
theorem self_invAct_act_eq {x y : R} : (x ◃⁻¹ x) ◃ y = x ◃ y 
goal: (x ◃⁻¹ x) ◃ y = x ◃ y

full_name: Rack.self_act_eq_iff_eq
code: theorem self_act_eq_iff_eq {x y : R} : x ◃ x = y ◃ y ↔ x = y 
goal: x ◃ x = y ◃ y ↔ x = y

full_name: Rack.self_invAct_eq_iff_eq
code: theorem self_invAct_eq_iff_eq {x y : R} : x ◃⁻¹ x = y ◃⁻¹ y ↔ x = y 
goal: x ◃⁻¹ x = y ◃⁻¹ y ↔ x = y

full_name: Rack.selfApplyEquiv
code: /-- The map `x ↦ x ◃ x` is a bijection.  (This has applications for the
regular isotopy version of the Reidemeister I move for knot diagrams.)
-/
def selfApplyEquiv (R : Type*) [Rack R] : R ≃ R 
goal: R ≃ R

full_name: Rack.IsInvolutory
code: /-- An involutory rack is one for which `Rack.oppositeRack R x` is an involution for every x.
-/
def IsInvolutory (R : Type*) [Rack R] : Prop 
goal: Prop

full_name: Rack.involutory_invAct_eq_act
code: theorem involutory_invAct_eq_act {R : Type*} [Rack R] (h : IsInvolutory R) (x y : R) :
    x ◃⁻¹ y = x ◃ y 
goal: x ◃⁻¹ y = x ◃ y

full_name: Rack.IsAbelian
code: /-- An abelian rack is one for which the mediality axiom holds.
-/
def IsAbelian (R : Type*) [Rack R] : Prop 
goal: Prop

full_name: Rack.assoc_iff_id
code: /-- Associative racks are uninteresting.
-/
theorem assoc_iff_id {R : Type*} [Rack R] {x y z : R} : x ◃ y ◃ z = (x ◃ y) ◃ z ↔ x ◃ z = z 
goal: x ◃ y ◃ z = (x ◃ y) ◃ z ↔ x ◃ z = z

full_name: ShelfHom.instFunLike
code: instance : FunLike (S₁ →◃ S₂) S₁ S₂ 
goal: FunLike (S₁ →◃ S₂) S₁ S₂

full_name: ShelfHom.toFun_eq_coe
code: @[simp] theorem toFun_eq_coe (f : S₁ →◃ S₂) : f.toFun = f 
goal: f.toFun = ⇑f

full_name: ShelfHom.map_act
code: @[simp]
theorem map_act (f : S₁ →◃ S₂) {x y : S₁} : f (x ◃ y) = f x ◃ f y 
goal: f (x ◃ y) = f x ◃ f y

full_name: ShelfHom.id
code: /-- The identity homomorphism -/
def id (S : Type*) [Shelf S] : S →◃ S 
goal: S →◃ S

full_name: ShelfHom.inhabited
code: instance inhabited (S : Type*) [Shelf S] : Inhabited (S →◃ S) 
goal: Inhabited (S →◃ S)

full_name: ShelfHom.comp
code: /-- The composition of shelf homomorphisms -/
def comp (g : S₂ →◃ S₃) (f : S₁ →◃ S₂) : S₁ →◃ S₃ 
goal: S₁ →◃ S₃

full_name: ShelfHom.comp_apply
code: @[simp]
theorem comp_apply (g : S₂ →◃ S₃) (f : S₁ →◃ S₂) (x : S₁) : (g.comp f) x = g (f x) 
goal: (g.comp f) x = g (f x)

full_name: Quandle.fix
code: /-- A quandle is a rack such that each automorphism fixes its corresponding element.
-/
class Quandle (α : Type*) extends Rack α where
  /-- The fixing property of a Quandle -/
  fix : ∀ {x : α}, act x x = x
goal: x ◃ x = x

full_name: Quandle
code: /-- A quandle is a rack such that each automorphism fixes its corresponding element.
-/
class Quandle (α : Type*) extends Rack α where
  /-- The fixing property of a Quandle -/
  fix : ∀ {x : α}, act x x = x
goal: Type u_1

full_name: Quandle.fix_inv
code: @[simp]
theorem fix_inv {x : Q} : x ◃⁻¹ x = x 
goal: x ◃⁻¹ x = x

full_name: Quandle.oppositeQuandle
code: instance oppositeQuandle : Quandle Qᵐᵒᵖ 
goal: Quandle Qᵐᵒᵖ

full_name: Quandle.Conj
code: /-- The conjugation quandle of a group.  Each element of the group acts by
the corresponding inner automorphism.
-/
-- Porting note: no need for `nolint` and added `reducible`
abbrev Conj (G : Type*) 
goal: Type u_2

full_name: Quandle.Conj.quandle
code: instance Conj.quandle (G : Type*) [Group G] : Quandle (Conj G) 
goal: Quandle (Quandle.Conj G)

full_name: Quandle.conj_act_eq_conj
code: @[simp]
theorem conj_act_eq_conj {G : Type*} [Group G] (x y : Conj G) :
    x ◃ y = ((x : G) * (y : G) * (x : G)⁻¹ : G) 
goal: x ◃ y = x * y * x⁻¹

full_name: Quandle.conj_swap
code: theorem conj_swap {G : Type*} [Group G] (x y : Conj G) : x ◃ y = y ↔ y ◃ x = x 
goal: x ◃ y = y ↔ y ◃ x = x

full_name: Quandle.Conj.map
code: /-- `Conj` is functorial
-/
def Conj.map {G : Type*} {H : Type*} [Group G] [Group H] (f : G →* H) : Conj G →◃ Conj H 
goal: Quandle.Conj G →◃ Quandle.Conj H

full_name: Quandle.Dihedral
code: /-- The dihedral quandle. This is the conjugation quandle of the dihedral group restrict to flips.

Used for Fox n-colorings of knots.
-/
-- Porting note: Removed nolint
def Dihedral (n : ℕ) 
goal: Type

full_name: Quandle.dihedralAct
code: /-- The operation for the dihedral quandle.  It does not need to be an equivalence
because it is an involution (see `dihedralAct.inv`).
-/
def dihedralAct (n : ℕ) (a : ZMod n) : ZMod n → ZMod n 
goal: ZMod n → ZMod n

full_name: Quandle.dihedralAct.inv
code: theorem dihedralAct.inv (n : ℕ) (a : ZMod n) : Function.Involutive (dihedralAct n a) 
goal: Function.Involutive (Quandle.dihedralAct n a)

full_name: Quandle.instDihedral
code: instance (n : ℕ) : Quandle (Dihedral n) 
goal: Quandle (Quandle.Dihedral n)

full_name: Rack.toConj
code: /-- This is the natural rack homomorphism to the conjugation quandle of the group `R ≃ R`
that acts on the rack.
-/
def toConj (R : Type*) [Rack R] : R →◃ Quandle.Conj (R ≃ R) 
goal: R →◃ Quandle.Conj (R ≃ R)

full_name: Rack.PreEnvelGroup.inv
code: /-- Free generators of the enveloping group.
-/
inductive PreEnvelGroup (R : Type u) : Type u
  | unit : PreEnvelGroup R
  | incl (x : R) : PreEnvelGroup R
  | mul (a b : PreEnvelGroup R) : PreEnvelGroup R
  | inv (a : PreEnvelGroup R) : PreEnvelGroup R
goal: Rack.PreEnvelGroup R

full_name: Rack.PreEnvelGroup.mul
code: /-- Free generators of the enveloping group.
-/
inductive PreEnvelGroup (R : Type u) : Type u
  | unit : PreEnvelGroup R
  | incl (x : R) : PreEnvelGroup R
  | mul (a b : PreEnvelGroup R) : PreEnvelGroup R
  | inv (a : PreEnvelGroup R) : PreEnvelGroup R
goal: Rack.PreEnvelGroup R

full_name: Rack.PreEnvelGroup.incl
code: /-- Free generators of the enveloping group.
-/
inductive PreEnvelGroup (R : Type u) : Type u
  | unit : PreEnvelGroup R
  | incl (x : R) : PreEnvelGroup R
  | mul (a b : PreEnvelGroup R) : PreEnvelGroup R
  | inv (a : PreEnvelGroup R) : PreEnvelGroup R
goal: Rack.PreEnvelGroup R

full_name: Rack.PreEnvelGroup
code: /-- Free generators of the enveloping group.
-/
inductive PreEnvelGroup (R : Type u) : Type u
  | unit : PreEnvelGroup R
  | incl (x : R) : PreEnvelGroup R
  | mul (a b : PreEnvelGroup R) : PreEnvelGroup R
  | inv (a : PreEnvelGroup R) : PreEnvelGroup R
goal: Type u

full_name: Rack.PreEnvelGroup.unit
code: /-- Free generators of the enveloping group.
-/
inductive PreEnvelGroup (R : Type u) : Type u
  | unit : PreEnvelGroup R
  | incl (x : R) : PreEnvelGroup R
  | mul (a b : PreEnvelGroup R) : PreEnvelGroup R
  | inv (a : PreEnvelGroup R) : PreEnvelGroup R
goal: Rack.PreEnvelGroup R

full_name: Rack.PreEnvelGroup.inhabited
code: instance PreEnvelGroup.inhabited (R : Type u) : Inhabited (PreEnvelGroup R) 
goal: Inhabited (Rack.PreEnvelGroup R)

full_name: Rack.PreEnvelGroupRel'.congr_inv
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroupRel' R a.inv a'.inv

full_name: Rack.PreEnvelGroupRel'.one_mul
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroupRel' R (Rack.PreEnvelGroup.unit.mul a) a

full_name: Rack.PreEnvelGroupRel'.mul_one
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroupRel' R (a.mul Rack.PreEnvelGroup.unit) a

full_name: Rack.PreEnvelGroupRel'.act_incl
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroupRel' R
  (((Rack.PreEnvelGroup.incl x).mul (Rack.PreEnvelGroup.incl y)).mul (Rack.PreEnvelGroup.incl x).inv)
  (Rack.PreEnvelGroup.incl (x ◃ y))

full_name: Rack.PreEnvelGroupRel'
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroup R → Rack.PreEnvelGroup R → Type u

full_name: Rack.PreEnvelGroupRel'.refl
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroupRel' R a a

full_name: Rack.PreEnvelGroupRel'.assoc
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroupRel' R ((a.mul b).mul c) (a.mul (b.mul c))

full_name: Rack.PreEnvelGroupRel'.symm
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroupRel' R b a

full_name: Rack.PreEnvelGroupRel'.congr_mul
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroupRel' R (a.mul b) (a'.mul b')

full_name: Rack.PreEnvelGroupRel'.mul_left_inv
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroupRel' R (a.inv.mul a) Rack.PreEnvelGroup.unit

full_name: Rack.PreEnvelGroupRel'.trans
code: /-- Relations for the enveloping group. This is a type-valued relation because
`toEnvelGroup.mapAux.well_def` inducts on it to show `toEnvelGroup.map`
is well-defined.  The relation `PreEnvelGroupRel` is the `Prop`-valued version,
which is used to define `EnvelGroup` itself.
-/
inductive PreEnvelGroupRel' (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Type u
  | refl {a : PreEnvelGroup R} : PreEnvelGroupRel' R a a
  | symm {a b : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b) : PreEnvelGroupRel' R b a
  | trans {a b c : PreEnvelGroup R} (hab : PreEnvelGroupRel' R a b)
    (hbc : PreEnvelGroupRel' R b c) : PreEnvelGroupRel' R a c
  | congr_mul {a b a' b' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a')
    (hb : PreEnvelGroupRel' R b b') : PreEnvelGroupRel' R (mul a b) (mul a' b')
  | congr_inv {a a' : PreEnvelGroup R} (ha : PreEnvelGroupRel' R a a') :
    PreEnvelGroupRel' R (inv a) (inv a')
  | assoc (a b c : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (mul a b) c) (mul a (mul b c))
  | one_mul (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul unit a) a
  | mul_one (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul a unit) a
  | mul_left_inv (a : PreEnvelGroup R) : PreEnvelGroupRel' R (mul (inv a) a) unit
  | act_incl (x y : R) :
    PreEnvelGroupRel' R (mul (mul (incl x) (incl y)) (inv (incl x))) (incl (x ◃ y))
goal: Rack.PreEnvelGroupRel' R a c

full_name: Rack.PreEnvelGroupRel'.inhabited
code: instance PreEnvelGroupRel'.inhabited (R : Type u) [Rack R] :
    Inhabited (PreEnvelGroupRel' R unit unit) 
goal: Inhabited (Rack.PreEnvelGroupRel' R Rack.PreEnvelGroup.unit Rack.PreEnvelGroup.unit)

full_name: Rack.PreEnvelGroupRel.rel
code: /--
The `PreEnvelGroupRel` relation as a `Prop`.  Used as the relation for `PreEnvelGroup.setoid`.
-/
inductive PreEnvelGroupRel (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Prop
  | rel {a b : PreEnvelGroup R} (r : PreEnvelGroupRel' R a b) : PreEnvelGroupRel R a b
goal: Rack.PreEnvelGroupRel R a b

full_name: Rack.PreEnvelGroupRel
code: /--
The `PreEnvelGroupRel` relation as a `Prop`.  Used as the relation for `PreEnvelGroup.setoid`.
-/
inductive PreEnvelGroupRel (R : Type u) [Rack R] : PreEnvelGroup R → PreEnvelGroup R → Prop
  | rel {a b : PreEnvelGroup R} (r : PreEnvelGroupRel' R a b) : PreEnvelGroupRel R a b
goal: Rack.PreEnvelGroup R → Rack.PreEnvelGroup R → Prop

full_name: Rack.PreEnvelGroupRel'.rel
code: /-- A quick way to convert a `PreEnvelGroupRel'` to a `PreEnvelGroupRel`.
-/
theorem PreEnvelGroupRel'.rel {R : Type u} [Rack R] {a b : PreEnvelGroup R} :
    PreEnvelGroupRel' R a b → PreEnvelGroupRel R a b 
goal: Rack.PreEnvelGroupRel' R a b → Rack.PreEnvelGroupRel R a b

full_name: Rack.PreEnvelGroupRel.refl
code: @[refl]
theorem PreEnvelGroupRel.refl {R : Type u} [Rack R] {a : PreEnvelGroup R} :
    PreEnvelGroupRel R a a 
goal: Rack.PreEnvelGroupRel R a a

full_name: Rack.PreEnvelGroupRel.symm
code: @[symm]
theorem PreEnvelGroupRel.symm {R : Type u} [Rack R] {a b : PreEnvelGroup R} :
    PreEnvelGroupRel R a b → PreEnvelGroupRel R b a
  
goal: Rack.PreEnvelGroupRel R a b → Rack.PreEnvelGroupRel R b a

full_name: Rack.PreEnvelGroupRel.trans
code: @[trans]
theorem PreEnvelGroupRel.trans {R : Type u} [Rack R] {a b c : PreEnvelGroup R} :
    PreEnvelGroupRel R a b → PreEnvelGroupRel R b c → PreEnvelGroupRel R a c
  
goal: Rack.PreEnvelGroupRel R a b → Rack.PreEnvelGroupRel R b c → Rack.PreEnvelGroupRel R a c

full_name: Rack.PreEnvelGroup.setoid
code: instance PreEnvelGroup.setoid (R : Type*) [Rack R] : Setoid (PreEnvelGroup R) 
goal: Setoid (Rack.PreEnvelGroup R)

full_name: Rack.EnvelGroup
code: /-- The universal enveloping group for the rack R.
-/
def EnvelGroup (R : Type*) [Rack R] 
goal: Type u_1

full_name: Rack.instDivInvMonoidEnvelGroup
code: instance (R : Type*) [Rack R] : DivInvMonoid (EnvelGroup R) 
goal: DivInvMonoid (Rack.EnvelGroup R)

full_name: Rack.instGroupEnvelGroup
code: instance (R : Type*) [Rack R] : Group (EnvelGroup R) 
goal: Group (Rack.EnvelGroup R)

full_name: Rack.EnvelGroup.inhabited
code: instance EnvelGroup.inhabited (R : Type*) [Rack R] : Inhabited (EnvelGroup R) 
goal: Inhabited (Rack.EnvelGroup R)

full_name: Rack.toEnvelGroup
code: /-- The canonical homomorphism from a rack to its enveloping group.
Satisfies universal properties given by `toEnvelGroup.map` and `toEnvelGroup.univ`.
-/
def toEnvelGroup (R : Type*) [Rack R] : R →◃ Quandle.Conj (EnvelGroup R) 
goal: R →◃ Quandle.Conj (Rack.EnvelGroup R)

full_name: Rack.toEnvelGroup.mapAux
code: /-- The preliminary definition of the induced map from the enveloping group.
See `toEnvelGroup.map`.
-/
def toEnvelGroup.mapAux {R : Type*} [Rack R] {G : Type*} [Group G] (f : R →◃ Quandle.Conj G) :
    PreEnvelGroup R → G
  
goal: Rack.PreEnvelGroup R → G

full_name: Rack.toEnvelGroup.mapAux.well_def
code: /-- Show that `toEnvelGroup.mapAux` sends equivalent expressions to equal terms.
-/
theorem well_def {R : Type*} [Rack R] {G : Type*} [Group G] (f : R →◃ Quandle.Conj G) :
    ∀ {a b : PreEnvelGroup R},
      PreEnvelGroupRel' R a b → toEnvelGroup.mapAux f a = toEnvelGroup.mapAux f b
  
goal: Rack.PreEnvelGroupRel' R a b → Rack.toEnvelGroup.mapAux f a = Rack.toEnvelGroup.mapAux f b

full_name: Rack.toEnvelGroup.map
code: /-- Given a map from a rack to a group, lift it to being a map from the enveloping group.
More precisely, the `EnvelGroup` functor is left adjoint to `Quandle.Conj`.
-/
def toEnvelGroup.map {R : Type*} [Rack R] {G : Type*} [Group G] :
    (R →◃ Quandle.Conj G) ≃ (EnvelGroup R →* G) 
goal: (R →◃ Quandle.Conj G) ≃ (Rack.EnvelGroup R →* G)

full_name: Rack.toEnvelGroup.univ
code: /-- Given a homomorphism from a rack to a group, it factors through the enveloping group.
-/
theorem toEnvelGroup.univ (R : Type*) [Rack R] (G : Type*) [Group G] (f : R →◃ Quandle.Conj G) :
    (Quandle.Conj.map (toEnvelGroup.map f)).comp (toEnvelGroup R) = f 
goal: (Quandle.Conj.map (Rack.toEnvelGroup.map f)).comp (Rack.toEnvelGroup R) = f

full_name: Rack.toEnvelGroup.univ_uniq
code: /-- The homomorphism `toEnvelGroup.map f` is the unique map that fits into the commutative
triangle in `toEnvelGroup.univ`.
-/
theorem toEnvelGroup.univ_uniq (R : Type*) [Rack R] (G : Type*) [Group G]
    (f : R →◃ Quandle.Conj G) (g : EnvelGroup R →* G)
    (h : f = (Quandle.Conj.map g).comp (toEnvelGroup R)) : g = toEnvelGroup.map f 
goal: g = Rack.toEnvelGroup.map f

full_name: Rack.envelAction
code: /-- The induced group homomorphism from the enveloping group into bijections of the rack,
using `Rack.toConj`. Satisfies the property `envelAction_prop`.

This gives the rack `R` the structure of an augmented rack over `EnvelGroup R`.
-/
def envelAction {R : Type*} [Rack R] : EnvelGroup R →* R ≃ R 
goal: Rack.EnvelGroup R →* R ≃ R

full_name: Rack.envelAction_prop
code: @[simp]
theorem envelAction_prop {R : Type*} [Rack R] (x y : R) :
    envelAction (toEnvelGroup R x) y = x ◃ y 
goal: (Rack.envelAction ((Rack.toEnvelGroup R) x)) y = x ◃ y