👍 001_basicDef

Basic definition

def basicDef : Type :=
  Prop

002_badDef

Mismatched types

def badDef : Prop :=
  Type

👍 003_arrowType

Arrow type (function type)

def arrowType : Type :=
  Prop  Prop

👍 004_dependentType

Dependent type (forall)

def dependentType : Prop :=
   (p : Prop), p

👍 005_constType

Lambda expression

def constType : Type  Type  Type :=
  fun (x y : Type) => x

👍 006_betaReduction

Lambda reduction

Includes: constType

def betaReduction : constType Prop (Prop  Prop) :=
   (p : Prop), p

👍 007_betaReduction2

Lambda reduction under binder

Includes: constType

def betaReduction2 : (p : Prop)  constType Prop (Prop  Prop) :=
  fun (p : Prop) => p

👍 008_forallSortWhnf

The binding domain of a forall may need to be reduce before it is a sort

def id.{u} : {α : Sort u}  (a : α)  α :=
  fun {α : Sort u} (a : α) => a
def forallSortWhnf : Prop :=
   (p : @id.{2} Type Prop) (a : p), p

009_forallSortBad

The binding domain of a forall has to be a sort

Includes: id

def forallSortBad : Prop :=
  (x : @id.{2} Type Prop)  (x : x)  (a : x)  x

010_nonTypeType

The type of a declaration has to be a type, not some other expression

Includes: constType

def nonTypeType : constType :=
  Prop

011_nonTypeAxiom

This applies to axioms as well, which are easy to overlook because they have no value to check the type against. Letting one through is not merely untidy: an axiom whose type is an arbitrary term inhabits whatever that term is later found definitionally equal to, and the eta and proof irrelevance rules are happy to equate a term like this with a great many things.

Includes: constType

axiom nonTypeAxiom : constType

012_nonPropThm

The type of a theorem has to be a proposition

theorem nonPropThm : Prop :=
   (x : Prop), x

👍 013_levelComp1

Some level computation

def levelComp1 : Type :=
  Sort (imax 1 0)

👍 014_levelComp2

Some level computation

def levelComp2 : Type 1 :=
  Sort (imax 0 1)

👍 015_levelComp3

Some level computation

def levelComp3 : Type 2 :=
  Type (max 1 0)

👍 016_levelParams

Level parameters

def levelParamF.{u} : Sort u  Sort u  Sort u :=
  fun (α β : Sort u) => α
def levelParams : levelParamF.{1} Prop (Prop  Prop) :=
   (p : Prop), p

017_tut06_bad01

Duplicate universe parameters

def tut06_bad01.{u, u} : Type :=
  Prop

👍 018_levelComp4

Some level computation

def levelComp4.{u} : Type :=
  Prop

👍 019_levelComp5

Some level computation

def levelComp5.{u} : Type u :=
  Sort u

👍 020_imax1

Type inference for forall using imax

def imax1 : (p : Prop)  Prop :=
  fun (p : Prop) =>  (a : Type), p

👍 021_imax2

Type inference for forall using imax

def imax2 : (α : Type)  Type 1 :=
  fun (α : Type) => Type  α

👍 022_levelMaxComm

Level equality: max is commutative (max u v ≈ max v u).

def levelMaxComm.{u, v} : Type (max v u) :=
  Sort (max u v)

👍 023_levelMaxAssoc

Level equality: max is associative (max (max u v) w ≈ max u (max v w)).

def levelMaxAssoc.{u, v, w} : Type (max u v w) :=
  Sort (max (max u v) w)

👍 024_levelMaxIdem

Level equality: max is idempotent (max u u ≈ u).

def levelMaxIdem.{u} : Type u :=
  Sort (max u u)

👍 025_levelMaxAbsorb

Level equality: max absorption (max u (max u v) ≈ max u v).

def levelMaxAbsorb.{u, v} : Type (max u v) :=
  Sort (max u u v)

👍 026_inferVar

Type inference of local variables

def inferVar :  (f : Prop) (g : f), f :=
  fun (f : Prop) (g : f) => g

👍 027_defEqLambda

Definitional equality between lambdas

def defEqLambda :
     (f : (Prop  Prop)  Prop) (g :  (a : Prop  Prop), f a),
      f fun (p : Prop) => p  p :=
  fun (f : (Prop  Prop)  Prop) (g :  (a : Prop  Prop), f a) =>
    g fun (p : Prop) => p  p

👍 028_peano1

Peano arithmetic: 2 = 2

def PN.{u_1} : Sort (imax (u_1 + 1) u_1) :=
  (α : Sort u_1)  (α  α)  α  α
def PN.succ.{u_1} : PN.{u_1}  PN.{u_1} :=
  fun (n : PN.{u_1}) (α : Sort u_1) (s : α  α) (z : α) => s (n α s z)
def PN.zero.{u_1} : PN.{u_1} :=
  fun (α : Sort u_1) (s : α  α) (z : α) => z
def PN.lit0.{u_1} : PN.{u_1} :=
  PN.zero.{u_1}
def PN.lit1.{u_1} : PN.{u_1} :=
  PN.succ.{u_1} PN.lit0.{u_1}
def PN.lit2.{u_1} : PN.{u_1} :=
  PN.succ.{u_1} PN.lit1.{u_1}
theorem peano1.{u} :
     (t : PN.{u}  Prop) (v :  (n : PN.{u}), t n), t PN.lit2.{u} :=
  fun (t : PN.{u}  Prop) (v :  (n : PN.{u}), t n) => v PN.lit2.{u}

👍 029_peano2

Peano arithmetic: 1 + 1 = 2

Includes: PN, PN.succ, PN.zero, PN.lit0, PN.lit1, PN.lit2

def PN.add.{u_1} : PN.{u_1}  PN.{u_1}  PN.{u_1} :=
  fun (n m : PN.{u_1}) (α : Sort u_1) (s : α  α) (z : α) => n α s (m α s z)
theorem peano2.{u} :
     (t : PN.{u}  Prop) (v :  (n : PN.{u}), t n), t PN.lit2.{u} :=
  fun (t : PN.{u}  Prop) (v :  (n : PN.{u}), t n) =>
    v (PN.add.{u} PN.lit1.{u} PN.lit1.{u})

👍 030_peano3

Peano arithmetic: 2 * 2 = 4

Includes: PN, PN.succ, PN.zero, PN.lit0, PN.lit1, PN.lit2

def PN.lit3.{u_1} : PN.{u_1} :=
  PN.succ.{u_1} PN.lit2.{u_1}
def PN.lit4.{u_1} : PN.{u_1} :=
  PN.succ.{u_1} PN.lit3.{u_1}
def PN.mul.{u_1} : PN.{u_1}  PN.{u_1}  PN.{u_1} :=
  fun (n m : PN.{u_1}) (α : Sort u_1) (s : α  α) (z : α) => n α (m α s) z
theorem peano3.{u} :
     (t : PN.{u}  Prop) (v :  (n : PN.{u}), t n), t PN.lit4.{u} :=
  fun (t : PN.{u}  Prop) (v :  (n : PN.{u}), t n) =>
    v (PN.mul.{u} PN.lit2.{u} PN.lit2.{u})

👍 031_letType

Type checking a non-dependent let

def letType : Type :=
  let x : Type := Prop;
  x

👍 032_letTypeDep

Type checking a dependent let

axiom aDepProp : Type  Prop
axiom mkADepProp :  (t : Type), aDepProp t
def letTypeDep : aDepProp Prop :=
  let x : Type := Prop;
  mkADepProp x

👍 033_letRed

Reducing a let

axiom aProp : Prop
def letRed :
    let x : Type := Prop;
    x :=
  aProp

👍 034_empty

A simple empty inductive type

inductive Empty : Type
def empty : Type :=
  Empty

👍 035_boolType

A simple enumeration inductive type

inductive Bool : Type
constructor Bool.false : Bool
constructor Bool.true : Bool
def boolType : Type :=
  Bool

👍 036_twoBool

A simple product type

Includes: Bool, Bool.false, Bool.true

inductive TwoBool : Type
constructor TwoBool.mk : (b1 b2 : Bool)  TwoBool
def twoBool : Type :=
  TwoBool

👍 037_andType

A parametrized product type (no level parameters)

inductive And (a : Prop) (b : Prop) : Prop
constructor And.intro :  {a b : Prop} (left : a) (right : b), And a b
def andType : (a b : Prop)  Prop :=
  And

👍 038_prodType

A parametrized product type (with level parameters)

inductive Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)
constructor Prod.mk.{u, v} :
    {α : Type u}  {β : Type v}  (fst : α)  (snd : β)  Prod.{u, v} α β
def prodType : Type  Type  Type :=
  Prod.{0, 0}

👍 039_pprodType

A parametrized product type (with more general level parameters)

inductive PProd.{u, v} (α : Sort u) (β : Sort v) : Sort (max (max 1 u) v)
constructor PProd.mk.{u, v} :
    {α : Sort u}  {β : Sort v}  (fst : α)  (snd : β)  PProd.{u, v} α β
def pprodType : Type  Type  Type :=
  PProd.{1, 1}

👍 040_pUnitType

Level-polymorphic unit type

inductive PUnit.{u} : Sort u
constructor PUnit.unit.{u} : PUnit.{u}
def pUnitType : Type :=
  PUnit.{1}

👍 041_eqType

Equality, as an important indexed non-recursive data type

inductive Eq.{u_1} {α : Sort u_1} (a._@._internal._hyg.0 : α) : α  Prop
constructor Eq.refl.{u_1} :  {α : Sort u_1} (a : α), @Eq.{u_1} α a a
def eqType.{u_1} : {α : Sort u_1}  α  α  Prop :=
  @Eq.{u_1}

👍 042_natDef

A recursive inductive data type

inductive N : Type
constructor N.zero : N
constructor N.succ : N  N
def natDef : Type :=
  N

👍 043_rbTreeDef

A recursive indexed data type

Includes: N, N.zero, N.succ

inductive Color : Type
constructor Color.r : Color
constructor Color.b : Color
inductive RBTree.{u} (α : Type u) : Color  N  Type u
constructor RBTree.leaf.{u} : {α : Type u}  RBTree.{u} α Color.b N.zero
constructor RBTree.red.{u} :
    {α : Type u} 
      {n : N} 
        RBTree.{u} α Color.b n 
          α  RBTree.{u} α Color.b n  RBTree.{u} α Color.r n
constructor RBTree.black.{u} :
    {α : Type u} 
      {c1 c2 : Color} 
        {n : N} 
          RBTree.{u} α c1 n 
            α  RBTree.{u} α c2 n  RBTree.{u} α Color.b (N.succ n)
def rbTreeDef.{u} : (α : Type u)  Color  N  Type u :=
  RBTree.{u}

044_inductBadNonSort

An inductive type with a non-sort type

Includes: constType

inductive inductBadNonSort : constType

045_inductBadNonSort2

Another inductive type with a non-sort type

axiom aType : Type
inductive inductBadNonSort2 : aType

046_inductLevelParam

An inductive with duplicate level params

inductive inductLevelParam.{u, u} : Type

047_inductTooFewParams

An inductive with too few parameters in the type

inductive inductTooFewParams (x : Prop) : Prop

048_inductWrongCtorParams

An inductive with a constructor with wrong parameters

Includes: aProp

inductive inductWrongCtorParams (x : Prop) : Type
constructor inductWrongCtorParams.mk : (x : Type)  inductWrongCtorParams aProp

049_inductWrongCtorResParams

An inductive with a constructor with wrong parameters in result (they are swapped)

inductive inductWrongCtorResParams (x : Prop) (y : Prop) : Type
constructor inductWrongCtorResParams.mk :
    (x y : Prop)  inductWrongCtorResParams y x

050_inductWrongCtorResLevel

An inductive with a constructor with wrong level parameters in result (they are swapped)

inductive inductWrongCtorResLevel.{u1, u2} (x : Prop) (y : Prop) : Type
constructor inductWrongCtorResLevel.mk.{u1, u2} :
    (x y : Prop)  inductWrongCtorResLevel.{u2, u1} x y

051_inductInIndex

A constructor with an unexpected occurrence of the type in index position of a return type.

Includes: aProp

inductive inductInIndex : (x : Prop)  Prop
constructor inductInIndex.mk : inductInIndex (inductInIndex aProp)

052_indNeg

The classic example of an inductive with negative recursive occurrence

inductive indNeg : Type
constructor indNeg.mk : (x : (x : indNeg)  indNeg)  indNeg

👍 053_reduceCtorParam.mk

When checking inductives, we expect the kernel to reduce the types of constructor arguments.

Includes: id, constType

inductive reduceCtorParam (a._@._internal._hyg.0 : Type) : Type
constructor reduceCtorParam.mk :
    (α : @id.{3} (Type 1) Type) 
      (x : constType (reduceCtorParam α) (reduceCtorParam α)) 
        reduceCtorParam α

054_reduceCtorType.mk

When checking inductives, we expect the kernel to not reduce the type of the constructor itself; that should be all manifest foralls

Includes: id

inductive reduceCtorType : Type
constructor reduceCtorType.mk : @id.{2} Type reduceCtorType

055_indNegReducible

When checking inductives, we expect the kernel to not reduce the type of the constructor parameters further than head normal form. Recursive occurrences nested inside the head normal form are considered negative occurrences, even if they could be reduced to disappear.

Includes: constType, aType

inductive indNegReducible : Type
constructor indNegReducible.mk :
    (x : (x : constType aType indNegReducible)  indNegReducible) 
      indNegReducible

👍 056_predWithTypeField

An inductive proposition can have constructors with fields of arbitrary level.

inductive PredWithTypeField : Prop
constructor PredWithTypeField.mk :  (α : Type), PredWithTypeField
def predWithTypeField : Prop :=
  PredWithTypeField

👍 057_typeWithTypeField

An inductive type can have fields of level up to that of the inductive.

inductive TypeWithTypeField : Type 1
constructor TypeWithTypeField.mk : (α : Type)  TypeWithTypeField
def typeWithTypeField : Type 1 :=
  TypeWithTypeField

👍 058_typeWithTypeFieldPoly

An inductive type can have fields of level up to that of the inductive (polymorphic variant).

inductive TypeWithTypeFieldPoly.{u} : Type (u + 1)
constructor TypeWithTypeFieldPoly.mk.{u} :
    (α : Type u)  TypeWithTypeFieldPoly.{u}
def typeWithTypeFieldPoly.{u} : Type (u + 1) :=
  TypeWithTypeFieldPoly.{u}

059_typeWithTooHighTypeField.mk

An inductive type can have fields of from higher universes.

inductive typeWithTooHighTypeField : Type
constructor typeWithTooHighTypeField.mk : (x : Type)  typeWithTooHighTypeField

👍 060_emptyRec

Asserting the type of the generated recursor

Includes: Empty

def emptyRec.{u} : (motive : (t : Empty)  Sort u)  (t : Empty)  motive t :=
  Empty.rec.{u}

👍 061_boolRec

Asserting the type of the generated recursor

Includes: Bool, Bool.false, Bool.true

def boolRec.{u} :
    {motive : (t : Bool)  Sort u} 
      (false : motive Bool.false) 
        (true : motive Bool.true)  (t : Bool)  motive t :=
  fun {motive : (t : Bool)  Sort u} (false : motive Bool.false)
      (true : motive Bool.true) (t : Bool) =>
    @Bool.rec.{u} motive false true t

👍 062_twoBoolRec

Asserting the type of the generated recursor

Includes: Bool, Bool.false, Bool.true, TwoBool, TwoBool.mk

def twoBoolRec.{u} :
    {motive : (t : TwoBool)  Sort u} 
      (mk : (b1 b2 : Bool)  motive (TwoBool.mk b1 b2)) 
        (t : TwoBool)  motive t :=
  fun {motive : (t : TwoBool)  Sort u}
      (mk : (b1 b2 : Bool)  motive (TwoBool.mk b1 b2)) (t : TwoBool) =>
    @TwoBool.rec.{u} motive mk t

👍 063_andRec

Asserting the type of the generated recursor

Includes: And, And.intro

def andRec.{u} :
    {a b : Prop} 
      {motive : (t : And a b)  Sort u} 
        (intro :
            (left : a)  (right : b)  motive (@And.intro a b left right)) 
          (t : And a b)  motive t :=
  @And.rec.{u}

👍 064_prodRec

Asserting the type of the generated recursor

Includes: Prod, Prod.mk

def prodRec.{u, v, w} :
    (α : Type u) 
      (β : Type v) 
        {motive : Prod.{u, v} α β  Sort u} 
          (mk : (fst : α)  (snd : β)  motive (@Prod.mk.{u, v} α β fst snd)) 
            (t : Prod.{u, v} α β)  motive t :=
  @Prod.rec.{u, u, v}

👍 065_pprodRec

Asserting the type of the generated recursor

Includes: PProd, PProd.mk

def pprodRec.{u, v, w} :
    (α : Sort u) 
      (β : Sort v) 
        {motive : PProd.{u, v} α β  Sort u} 
          (mk : (fst : α)  (snd : β)  motive (@PProd.mk.{u, v} α β fst snd)) 
            (t : PProd.{u, v} α β)  motive t :=
  @PProd.rec.{u, u, v}

👍 066_punitRec

Asserting the type of the generated recursor

Includes: PUnit, PUnit.unit

def punitRec.{u, w} :
    {motive : PUnit.{u}  Sort w} 
      (unit : motive PUnit.unit.{u})  (t : PUnit.{u})  motive t :=
  @PUnit.rec.{w, u}

👍 067_eqRec

Asserting the type of the generated recursor

Includes: Eq, Eq.refl

def eqRec.{u, u_1} :
    {α : Sort u_1} 
      {a : α} 
        {motive : (a_1 : α)  (t : @Eq.{u_1} α a a_1)  Sort u} 
          (refl : motive a (@Eq.refl.{u_1} α a)) 
            {a_1 : α}  (t : @Eq.{u_1} α a a_1)  motive a_1 t :=
  @Eq.rec.{u, u_1}

👍 068_nRec

Asserting the type of the generated recursor

Includes: N, N.zero, N.succ

def nRec.{u} :
    {motive : (t : N)  Sort u} 
      (zero : motive N.zero) 
        (succ : (a : N)  motive a  motive (N.succ a))  (t : N)  motive t :=
  @N.rec.{u}

👍 069_rbTreeRef

Asserting the type of the generated recursor

Includes: Color, Color.r, Color.b, N, N.zero, N.succ, RBTree, RBTree.leaf, RBTree.red, RBTree.black

def rbTreeRef.{u} :
    {α : Type u} 
      {motive : (a : Color)  (a_1 : N)  RBTree.{u} α a a_1  Sort u} 
        (leaf : motive Color.b N.zero (@RBTree.leaf.{u} α)) 
          (red :
              {n : N} 
                (a : RBTree.{u} α Color.b n) 
                  (a_1 : α) 
                    (a_2 : RBTree.{u} α Color.b n) 
                      motive Color.b n a 
                        motive Color.b n a_2 
                          motive Color.r n (@RBTree.red.{u} α n a a_1 a_2)) 
            (black :
                {c1 c2 : Color} 
                  {n : N} 
                    (a : RBTree.{u} α c1 n) 
                      (a_1 : α) 
                        (a_2 : RBTree.{u} α c2 n) 
                          motive c1 n a 
                            motive c2 n a_2 
                              motive Color.b (N.succ n)
                                (@RBTree.black.{u} α c1 c2 n a a_1 a_2)) 
              {a : Color} 
                {a_1 : N}  (t : RBTree.{u} α a a_1)  motive a a_1 t :=
  @RBTree.rec.{u, u}

👍 070_boolPropRec

Inductive predicates eliminate into Prop if they have more than one constructor.

inductive BoolProp : Prop
constructor BoolProp.a : BoolProp
constructor BoolProp.b : BoolProp
def boolPropRec :
     {motive : (t : BoolProp)  Prop} (a : motive BoolProp.a)
      (b : motive BoolProp.b) (t : BoolProp), motive t :=
  @BoolProp.rec

071_BogusRecursor

A kernel must not blindly trust the recursors it is handed. If we write

inductive BogusRecursor : Type where
  | mk : BogusRecursor

then the recursor BogusRecursor.rec will be correctly derived with type {motive : BogusRecursor → Sort u} → motive .mk → (t : BogusRecursor) → motive t.

This test instead claims that the recursor is a constant of type False, and then uses it to prove bogusRecursorFalse : False. A kernel that validates the recursors it is handed rejects the bogus recursor itself; a kernel that ignores them and derives the recursors anew rejects the proof of False (the derived recursor neither has type False nor zero universe parameters). Either way, this test must be rejected.

inductive False : Prop
inductive BogusRecursor : Type
constructor BogusRecursor.mk : BogusRecursor
theorem bogusRecursorFalse : False :=
  BogusRecursor.rec

👍 072_existsRec

Inductive predicates eliminate into Prop if they have one constructors and it carries data.

inductive Exists.{u} {α : Sort u} (p : α  Prop) : Prop
constructor Exists.intro.{u} :
     {α : Sort u} {p : α  Prop} (w : α) (h : p w), @Exists.{u} α p
def existsRec.{u} :
     {α : Sort u} {p : α  Prop} {motive : (t : @Exists.{u} α p)  Prop}
      (intro :  (w : α) (h : p w), motive (@Exists.intro.{u} α p w h))
      (t : @Exists.{u} α p), motive t :=
  @Exists.rec.{u}

👍 073_typeSingletonRecReduction

Because NewSingleton is a singleton, NewSingleton.rec true x reduces to true even though x is a variable.

Includes: Eq, Eq.refl, Bool, Bool.false, Bool.true

inductive NewSingleton : Type
constructor NewSingleton.mk : NewSingleton
def rfl.{u} :  {α : Sort u} {a : α}, @Eq.{u} α a a :=
  fun {α : Sort u} {a : α} => @Eq.refl.{u} α a
def typeSingletonRecReduction :
     (x : NewSingleton),
      @Eq.{1} Bool
        (@NewSingleton.rec.{1} (fun (x : NewSingleton) => Bool) Bool.true x)
        Bool.true :=
  fun (x : NewSingleton) =>
    @rfl.{1} Bool
      (@NewSingleton.rec.{1} (fun (x : NewSingleton) => Bool) Bool.true x)

👍 074_sortElimPropRec

Inductive predicates eliminate into Sort if they have one constructors and it carries data, but the data is known from the type, e.g. a parameter or an index

Includes: Bool, Bool.false, Bool.true

inductive SortElimProp (b : Bool) : Bool  Bool  Prop
constructor SortElimProp.mk :  {b : Bool} (b1 b2 : Bool), SortElimProp b b2 b1
def sortElimPropRec.{u} :
    {b : Bool} 
      {motive : (a a_1 : Bool)  (t : SortElimProp b a a_1)  Sort u} 
        (mk : (b1 b2 : Bool)  motive b2 b1 (@SortElimProp.mk b b1 b2)) 
          {a a_1 : Bool}  (t : SortElimProp b a a_1)  motive a a_1 t :=
  @SortElimProp.rec.{u}

👍 075_sortElimProp2Rec

Inductive predicates eliminate into Sort if they have one constructors and it carries data, but the data is known from the type, e.g. a parameter or an index. However, it must occur directly in the result type, with no intervening reduction.

Includes: Bool, Bool.false, Bool.true, id

inductive SortElimProp2 (b : Bool) : Bool  Bool  Prop
constructor SortElimProp2.mk :
     {b : Bool} (b1 b2 : Bool), SortElimProp2 b b2 (@id.{1} Bool b1)
def sortElimProp2Rec :
     {b : Bool} {motive : (a a_1 : Bool)  (t : SortElimProp2 b a a_1)  Prop}
      (mk :  (b1 b2 : Bool), motive b2 b1 (@SortElimProp2.mk b b1 b2))
      {a a_1 : Bool} (t : SortElimProp2 b a a_1), motive a a_1 t :=
  @SortElimProp2.rec

👍 076_boolRecEqns

Reduction behavior of Bool.rec

Includes: And, And.intro, Bool, Bool.false, Bool.true, Eq, Eq.refl

theorem boolRecEqns.{u} :
    And
      (∀ {motive : (t : Bool)  Sort u} (falseVal : motive Bool.false)
        (trueVal : motive Bool.true),
        @Eq.{u} (motive Bool.false)
          (@Bool.rec.{u} (fun (x : Bool) => motive x) falseVal trueVal
            Bool.false)
          falseVal)
      (∀ {motive : (t : Bool)  Sort u} (falseVal : motive Bool.false)
        (trueVal : motive Bool.true),
        @Eq.{u} (motive Bool.true)
          (@Bool.rec.{u} (fun (x : Bool) => motive x) falseVal trueVal
            Bool.true)
          trueVal) :=
  @And.intro
    (∀ {motive : (t : Bool)  Sort u} (falseVal : motive Bool.false)
      (trueVal : motive Bool.true),
      @Eq.{u} (motive Bool.false)
        (@Bool.rec.{u} (fun (x : Bool) => motive x) falseVal trueVal Bool.false)
        falseVal)
    (∀ {motive : (t : Bool)  Sort u} (falseVal : motive Bool.false)
      (trueVal : motive Bool.true),
      @Eq.{u} (motive Bool.true)
        (@Bool.rec.{u} (fun (x : Bool) => motive x) falseVal trueVal Bool.true)
        trueVal)
    (fun {motive : (t : Bool)  Sort u} (falseVal : motive Bool.false)
        (trueVal : motive Bool.true) =>
      @Eq.refl.{u} (motive Bool.false)
        (@Bool.rec.{u} (fun (x : Bool) => motive x) falseVal trueVal
          Bool.false))
    fun {motive : (t : Bool)  Sort u} (falseVal : motive Bool.false)
      (trueVal : motive Bool.true) =>
    @Eq.refl.{u} (motive Bool.true)
      (@Bool.rec.{u} (fun (x : Bool) => motive x) falseVal trueVal Bool.true)

👍 077_prodRecEqns

Reduction behavior of Prod.rec

Includes: Prod, Prod.mk, Eq, Eq.refl

theorem prodRecEqns.{u} :
     {α β : Type} {motive : Prod.{0, 0} α β  Sort u}
      (f : (a : α)  (b : β)  motive (@Prod.mk.{0, 0} α β a b)) (a : α)
      (b : β),
      @Eq.{u} (motive (@Prod.mk.{0, 0} α β a b))
        (@Prod.rec.{u, 0, 0} α β (fun (x : Prod.{0, 0} α β) => motive x) f
          (@Prod.mk.{0, 0} α β a b))
        (f a b) :=
  fun {α β : Type} {motive : Prod.{0, 0} α β  Sort u}
      (f : (a : α)  (b : β)  motive (@Prod.mk.{0, 0} α β a b)) (a : α)
      (b : β) =>
    @Eq.refl.{u} (motive (@Prod.mk.{0, 0} α β a b))
      (@Prod.rec.{u, 0, 0} α β (fun (x : Prod.{0, 0} α β) => motive x) f
        (@Prod.mk.{0, 0} α β a b))

👍 078_nRecReduction

A proof relying on the reduction behavior of N.rec

Includes: And, And.intro, N, N.zero, N.succ, Eq, Eq.refl, id

def N.add : N  N  N :=
  fun (t : N) =>
    @N.rec.{1} (fun (x : N) => N  N) (fun (m : N) => m)
      (fun (n : N) (ih : N  N) (m : N) => N.succ (ih m)) t
theorem nRecReduction :
    And (∀ (m : N), @Eq.{1} N (N.add N.zero m) m)
      (∀ (n m : N), @Eq.{1} N (N.add (N.succ n) m) (N.succ (N.add n m))) :=
  @id.{0}
    (And (∀ (m : N), @Eq.{1} N (N.add N.zero m) m)
      (∀ (n m : N), @Eq.{1} N (N.add (N.succ n) m) (N.succ (N.add n m))))
    (@And.intro
      (∀ (m : N),
        @Eq.{1} N
          (@N.rec.{1} (fun (x : N) => N  N) (fun (m : N) => m)
            (fun (n : N) (ih : N  N) (m : N) => N.succ (ih m)) N.zero m)
          m)
      (∀ (n m : N),
        @Eq.{1} N
          (@N.rec.{1} (fun (x : N) => N  N) (fun (m : N) => m)
            (fun (n : N) (ih : N  N) (m : N) => N.succ (ih m)) (N.succ n) m)
          (N.succ
            (@N.rec.{1} (fun (x : N) => N  N) (fun (m : N) => m)
              (fun (n : N) (ih : N  N) (m : N) => N.succ (ih m)) n m)))
      (fun (m : N) =>
        @Eq.refl.{1} N
          (@N.rec.{1} (fun (x : N) => N  N) (fun (m : N) => m)
            (fun (n : N) (ih : N  N) (m : N) => N.succ (ih m)) N.zero m))
      fun (n m : N) =>
      @Eq.refl.{1} N
        (@N.rec.{1} (fun (x : N) => N  N) (fun (m : N) => m)
          (fun (n : N) (ih : N  N) (m : N) => N.succ (ih m)) (N.succ n) m))

👍 079_listRecReduction

Reduction behavior of List.rec

Includes: And, And.intro, Eq, Eq.refl, id

inductive List.{u} (α : Type u) : Type u
constructor List.nil.{u} : {α : Type u}  List.{u} α
constructor List.cons.{u} :
    {α : Type u}  (head : α)  (tail : List.{u} α)  List.{u} α
def List.recOn.{u_1, u} :
    {α : Type u} 
      {motive : (t : List.{u} α)  Sort u_1} 
        (t : List.{u} α) 
          (nil : motive (@List.nil.{u} α)) 
            (cons :
                (head : α) 
                  (tail : List.{u} α) 
                    (tail_ih : motive tail) 
                      motive (@List.cons.{u} α head tail)) 
              motive t :=
  fun {α : Type u} {motive : (t : List.{u} α)  Sort u_1} (t : List.{u} α)
      (nil : motive (@List.nil.{u} α))
      (cons :
        (head : α) 
          (tail : List.{u} α) 
            (tail_ih : motive tail)  motive (@List.cons.{u} α head tail)) =>
    @List.rec.{u_1, u} α motive nil cons t
def myListApped : {α : Type}  (xs ys : List.{0} α)  List.{0} α :=
  fun {α : Type} (xs ys : List.{0} α) =>
    @List.recOn.{1, 0} α (fun (x : List.{0} α) => List.{0} α) xs ys
      fun (x : α) (xs ih : List.{0} α) => @List.cons.{0} α x ih
theorem listRecReduction :
     {α : Type} (xs ys : List.{0} α),
      And (@Eq.{1} (List.{0} α) (@myListApped α (@List.nil.{0} α) ys) ys)
        (∀ (x : α) (xs : List.{0} α),
          @Eq.{1} (List.{0} α) (@myListApped α (@List.cons.{0} α x xs) ys)
            (@List.cons.{0} α x (@myListApped α xs ys))) :=
  fun {α : Type} (xs ys : List.{0} α) =>
    @id.{0}
      (And (@Eq.{1} (List.{0} α) (@myListApped α (@List.nil.{0} α) ys) ys)
        (∀ (x : α) (xs : List.{0} α),
          @Eq.{1} (List.{0} α) (@myListApped α (@List.cons.{0} α x xs) ys)
            (@List.cons.{0} α x (@myListApped α xs ys))))
      (@And.intro
        (@Eq.{1} (List.{0} α)
          (@List.recOn.{1, 0} α (fun (x : List.{0} α) => List.{0} α)
            (@List.nil.{0} α) ys fun (x : α) (xs ih : List.{0} α) =>
            @List.cons.{0} α x ih)
          ys)
        (∀ (x : α) (xs : List.{0} α),
          @Eq.{1} (List.{0} α)
            (@List.recOn.{1, 0} α (fun (x : List.{0} α) => List.{0} α)
              (@List.cons.{0} α x xs) ys fun (x : α) (xs ih : List.{0} α) =>
              @List.cons.{0} α x ih)
            (@List.cons.{0} α x
              (@List.recOn.{1, 0} α (fun (x : List.{0} α) => List.{0} α) xs ys
                fun (x : α) (xs ih : List.{0} α) => @List.cons.{0} α x ih)))
        (@Eq.refl.{1} (List.{0} α)
          (@List.recOn.{1, 0} α (fun (x : List.{0} α) => List.{0} α)
            (@List.nil.{0} α) ys fun (x : α) (xs ih : List.{0} α) =>
            @List.cons.{0} α x ih))
        fun (x : α) (xs : List.{0} α) =>
        @Eq.refl.{1} (List.{0} α)
          (@List.recOn.{1, 0} α (fun (x : List.{0} α) => List.{0} α)
            (@List.cons.{0} α x xs) ys fun (x : α) (xs ih : List.{0} α) =>
            @List.cons.{0} α x ih))

👍 080_RBTree.id_spec

Reduction behavior of RBTree.rec

Includes: Color, Color.r, Color.b, N, N.zero, N.succ, RBTree, RBTree.leaf, RBTree.red, RBTree.black, Eq, Eq.refl, id

def RBTree.id :
    {α : Type} 
      {c : Color}  {n : N}  (t : RBTree.{0} α c n)  RBTree.{0} α c n :=
  fun {α : Type} {c : Color} {n : N} (t : RBTree.{0} α c n) =>
    @RBTree.rec.{1, 0} α
      (fun (x : Color) (x_1 : N) (x_2 : RBTree.{0} α x x_1) =>
        RBTree.{0} α x x_1)
      (@RBTree.leaf.{0} α)
      (fun {n : N} (_t1 : RBTree.{0} α Color.b n) (a : α)
          (_t2 ih1 ih2 : RBTree.{0} α Color.b n) =>
        @RBTree.red.{0} α n ih1 a ih2)
      (fun {c1 c2 : Color} {n : N} (_t1 : RBTree.{0} α c1 n) (a : α)
          (_t2 : RBTree.{0} α c2 n) (ih1 : RBTree.{0} α c1 n)
          (ih2 : RBTree.{0} α c2 n) =>
        @RBTree.black.{0} α c1 c2 n ih1 a ih2)
      c n t
theorem RBTree.id_spec :
     {α : Type} {c : Color} {n : N} (t : RBTree.{0} α c n),
      @Eq.{1} (RBTree.{0} α c n) (@RBTree.id α c n t) t :=
  fun {α : Type} {c : Color} {n : N} (t : RBTree.{0} α c n) =>
    @RBTree.rec.{0, 0} α
      (fun {c : Color} {n : N} (t : RBTree.{0} α c n) =>
        @Eq.{1} (RBTree.{0} α c n) (@RBTree.id α c n t) t)
      (@Eq.refl.{1} (RBTree.{0} α Color.b N.zero)
        (@RBTree.id α Color.b N.zero (@RBTree.leaf.{0} α)))
      (fun {n : N} (a : RBTree.{0} α Color.b n) (a_1 : α)
          (a_2 : RBTree.{0} α Color.b n)
          (a_ih : @Eq.{1} (RBTree.{0} α Color.b n) (@RBTree.id α Color.b n a) a)
          (a_ih_1 :
            @Eq.{1} (RBTree.{0} α Color.b n) (@RBTree.id α Color.b n a_2)
              a_2) =>
        @id.{0}
          (@Eq.{1} (RBTree.{0} α Color.r n)
            (@RBTree.id α Color.r n (@RBTree.red.{0} α n a a_1 a_2))
            (@RBTree.red.{0} α n a a_1 a_2))
          ((@fun {α : Type} {n : N} (a a_3 : RBTree.{0} α Color.b n)
                (e_a : @Eq.{1} (RBTree.{0} α Color.b n) a a_3) =>
              @Eq.rec.{0, 1} (RBTree.{0} α Color.b n) a
                (fun (a_4 : RBTree.{0} α Color.b n)
                    (e_a : @Eq.{1} (RBTree.{0} α Color.b n) a a_4) =>
                   (a_5 a_6 : α),
                    @Eq.{1} α a_5 a_6 
                       (a_7 a_8 : RBTree.{0} α Color.b n),
                        @Eq.{1} (RBTree.{0} α Color.b n) a_7 a_8 
                          @Eq.{1} (RBTree.{0} α Color.r n)
                            (@RBTree.red.{0} α n a a_5 a_7)
                            (@RBTree.red.{0} α n a_4 a_6 a_8))
                (fun (a_4 a_5 : α) (e_a : @Eq.{1} α a_4 a_5) =>
                  @Eq.rec.{0, 1} α a_4
                    (fun (a_6 : α) (e_a : @Eq.{1} α a_4 a_6) =>
                       (a_7 a_8 : RBTree.{0} α Color.b n),
                        @Eq.{1} (RBTree.{0} α Color.b n) a_7 a_8 
                          @Eq.{1} (RBTree.{0} α Color.r n)
                            (@RBTree.red.{0} α n a a_4 a_7)
                            (@RBTree.red.{0} α n a a_6 a_8))
                    (fun (a_6 a_7 : RBTree.{0} α Color.b n)
                        (e_a : @Eq.{1} (RBTree.{0} α Color.b n) a_6 a_7) =>
                      @Eq.rec.{0, 1} (RBTree.{0} α Color.b n) a_6
                        (fun (a_8 : RBTree.{0} α Color.b n)
                            (e_a : @Eq.{1} (RBTree.{0} α Color.b n) a_6 a_8) =>
                          @Eq.{1} (RBTree.{0} α Color.r n)
                            (@RBTree.red.{0} α n a a_4 a_6)
                            (@RBTree.red.{0} α n a a_4 a_8))
                        (@Eq.refl.{1} (RBTree.{0} α Color.r n)
                          (@RBTree.red.{0} α n a a_4 a_6))
                        a_7 e_a)
                    a_5 e_a)
                a_3 e_a)
            α n
            (@RBTree.rec.{1, 0} α
              (fun (x : Color) (x_1 : N) (x_2 : RBTree.{0} α x x_1) =>
                RBTree.{0} α x x_1)
              (@RBTree.leaf.{0} α)
              (fun {n : N} (_t1 : RBTree.{0} α Color.b n) (a : α)
                  (_t2 ih1 ih2 : RBTree.{0} α Color.b n) =>
                @RBTree.red.{0} α n ih1 a ih2)
              (fun {c1 c2 : Color} {n : N} (_t1 : RBTree.{0} α c1 n) (a : α)
                  (_t2 : RBTree.{0} α c2 n) (ih1 : RBTree.{0} α c1 n)
                  (ih2 : RBTree.{0} α c2 n) =>
                @RBTree.black.{0} α c1 c2 n ih1 a ih2)
              Color.b n a)
            a a_ih a_1 a_1 (@Eq.refl.{1} α a_1)
            (@RBTree.rec.{1, 0} α
              (fun (x : Color) (x_1 : N) (x_2 : RBTree.{0} α x x_1) =>
                RBTree.{0} α x x_1)
              (@RBTree.leaf.{0} α)
              (fun {n : N} (_t1 : RBTree.{0} α Color.b n) (a : α)
                  (_t2 ih1 ih2 : RBTree.{0} α Color.b n) =>
                @RBTree.red.{0} α n ih1 a ih2)
              (fun {c1 c2 : Color} {n : N} (_t1 : RBTree.{0} α c1 n) (a : α)
                  (_t2 : RBTree.{0} α c2 n) (ih1 : RBTree.{0} α c1 n)
                  (ih2 : RBTree.{0} α c2 n) =>
                @RBTree.black.{0} α c1 c2 n ih1 a ih2)
              Color.b n a_2)
            a_2 a_ih_1))
      (fun {c1 c2 : Color} {n : N} (a : RBTree.{0} α c1 n) (a_1 : α)
          (a_2 : RBTree.{0} α c2 n)
          (a_ih : @Eq.{1} (RBTree.{0} α c1 n) (@RBTree.id α c1 n a) a)
          (a_ih_1 : @Eq.{1} (RBTree.{0} α c2 n) (@RBTree.id α c2 n a_2) a_2) =>
        @id.{0}
          (@Eq.{1} (RBTree.{0} α Color.b (N.succ n))
            (@RBTree.id α Color.b (N.succ n)
              (@RBTree.black.{0} α c1 c2 n a a_1 a_2))
            (@RBTree.black.{0} α c1 c2 n a a_1 a_2))
          ((@fun {α : Type} {c1 c2 : Color} {n : N} (a a_3 : RBTree.{0} α c1 n)
                (e_a : @Eq.{1} (RBTree.{0} α c1 n) a a_3) =>
              @Eq.rec.{0, 1} (RBTree.{0} α c1 n) a
                (fun (a_4 : RBTree.{0} α c1 n)
                    (e_a : @Eq.{1} (RBTree.{0} α c1 n) a a_4) =>
                   (a_5 a_6 : α),
                    @Eq.{1} α a_5 a_6 
                       (a_7 a_8 : RBTree.{0} α c2 n),
                        @Eq.{1} (RBTree.{0} α c2 n) a_7 a_8 
                          @Eq.{1} (RBTree.{0} α Color.b (N.succ n))
                            (@RBTree.black.{0} α c1 c2 n a a_5 a_7)
                            (@RBTree.black.{0} α c1 c2 n a_4 a_6 a_8))
                (fun (a_4 a_5 : α) (e_a : @Eq.{1} α a_4 a_5) =>
                  @Eq.rec.{0, 1} α a_4
                    (fun (a_6 : α) (e_a : @Eq.{1} α a_4 a_6) =>
                       (a_7 a_8 : RBTree.{0} α c2 n),
                        @Eq.{1} (RBTree.{0} α c2 n) a_7 a_8 
                          @Eq.{1} (RBTree.{0} α Color.b (N.succ n))
                            (@RBTree.black.{0} α c1 c2 n a a_4 a_7)
                            (@RBTree.black.{0} α c1 c2 n a a_6 a_8))
                    (fun (a_6 a_7 : RBTree.{0} α c2 n)
                        (e_a : @Eq.{1} (RBTree.{0} α c2 n) a_6 a_7) =>
                      @Eq.rec.{0, 1} (RBTree.{0} α c2 n) a_6
                        (fun (a_8 : RBTree.{0} α c2 n)
                            (e_a : @Eq.{1} (RBTree.{0} α c2 n) a_6 a_8) =>
                          @Eq.{1} (RBTree.{0} α Color.b (N.succ n))
                            (@RBTree.black.{0} α c1 c2 n a a_4 a_6)
                            (@RBTree.black.{0} α c1 c2 n a a_4 a_8))
                        (@Eq.refl.{1} (RBTree.{0} α Color.b (N.succ n))
                          (@RBTree.black.{0} α c1 c2 n a a_4 a_6))
                        a_7 e_a)
                    a_5 e_a)
                a_3 e_a)
            α c1 c2 n
            (@RBTree.rec.{1, 0} α
              (fun (x : Color) (x_1 : N) (x_2 : RBTree.{0} α x x_1) =>
                RBTree.{0} α x x_1)
              (@RBTree.leaf.{0} α)
              (fun {n : N} (_t1 : RBTree.{0} α Color.b n) (a : α)
                  (_t2 ih1 ih2 : RBTree.{0} α Color.b n) =>
                @RBTree.red.{0} α n ih1 a ih2)
              (fun {c1 c2 : Color} {n : N} (_t1 : RBTree.{0} α c1 n) (a : α)
                  (_t2 : RBTree.{0} α c2 n) (ih1 : RBTree.{0} α c1 n)
                  (ih2 : RBTree.{0} α c2 n) =>
                @RBTree.black.{0} α c1 c2 n ih1 a ih2)
              c1 n a)
            a a_ih a_1 a_1 (@Eq.refl.{1} α a_1)
            (@RBTree.rec.{1, 0} α
              (fun (x : Color) (x_1 : N) (x_2 : RBTree.{0} α x x_1) =>
                RBTree.{0} α x x_1)
              (@RBTree.leaf.{0} α)
              (fun {n : N} (_t1 : RBTree.{0} α Color.b n) (a : α)
                  (_t2 ih1 ih2 : RBTree.{0} α Color.b n) =>
                @RBTree.red.{0} α n ih1 a ih2)
              (fun {c1 c2 : Color} {n : N} (_t1 : RBTree.{0} α c1 n) (a : α)
                  (_t2 : RBTree.{0} α c2 n) (ih1 : RBTree.{0} α c1 n)
                  (ih2 : RBTree.{0} α c2 n) =>
                @RBTree.black.{0} α c1 c2 n ih1 a ih2)
              c2 n a_2)
            a_2 a_ih_1))
      c n t

👍 081_And.right

Type-checking simple projection functions

Includes: And, And.intro

theorem And.left :  {a b : Prop} (self : And a b), a :=
  fun (a b : Prop) (self : And a b) => self.1
theorem And.right :  {a b : Prop} (self : And a b), b :=
  fun (a b : Prop) (self : And a b) => self.2

👍 082_Prod.snd

Type-checking projection functions with parameters

Includes: Prod, Prod.mk

def Prod.fst.{u, v} : {α : Type u}  {β : Type v}  (self : Prod.{u, v} α β)  α :=
  fun (α : Type u) (β : Type v) (self : Prod.{u, v} α β) => self.1
def Prod.snd.{u, v} : {α : Type u}  {β : Type v}  (self : Prod.{u, v} α β)  β :=
  fun (α : Type u) (β : Type v) (self : Prod.{u, v} α β) => self.2

👍 083_PProd.snd

Type-checking projection functions

Includes: PProd, PProd.mk

def PProd.fst.{u, v} :
    {α : Sort u}  {β : Sort v}  (self : PProd.{u, v} α β)  α :=
  fun (α : Sort u) (β : Sort v) (self : PProd.{u, v} α β) => self.1
def PProd.snd.{u, v} :
    {α : Sort u}  {β : Sort v}  (self : PProd.{u, v} α β)  β :=
  fun (α : Sort u) (β : Sort v) (self : PProd.{u, v} α β) => self.2

👍 084_PSigma.snd

Type-checking dependent projection functions

inductive PSigma.{u, v} {α : Sort u} (β : α  Sort v) : Sort (max (max 1 u) v)
constructor PSigma.mk.{u, v} :
    {α : Sort u} 
      {β : α  Sort v}  (fst : α)  (snd : β fst)  @PSigma.{u, v} α β
def PSigma.fst.{u, v} :
    {α : Sort u}  {β : α  Sort v}  (self : @PSigma.{u, v} α β)  α :=
  fun (α : Sort u) (β : α  Sort v) (self : @PSigma.{u, v} α β) => self.1
def PSigma.snd.{u, v} :
    {α : Sort u} 
      {β : α  Sort v} 
        (self : @PSigma.{u, v} α β)  β (@PSigma.fst.{u, v} α β self) :=
  fun (α : Sort u) (β : α  Sort v) (self : @PSigma.{u, v} α β) => self.2

085_projOutOfRange

Out of range projection

Includes: And, And.intro

def projOutOfRange :  (x x_1 : Prop) (x_2 : And x x_1), x :=
  fun (x y : Prop) (z : And x y) => z.3

086_projNotStruct

Projection out something that is not a structure

Includes: N, N.zero, N.succ

def projNotStruct : N  N :=
  fun (x : N) => x.1

👍 087_projProp1

Projecting out of a proposition

The lean kernel allows projections out of propositions if they precede all dependent data fields.

Includes: PUnit, PUnit.unit, Eq, Eq.refl

inductive PropStructure.{u, v} : Prop
constructor PropStructure.mk.{u, v} :
     (aProof : PUnit.{u}) (someData : PUnit.{v}) (aSecondProof : PUnit.{u})
      (someMoreData : PUnit.{v})
      (aProofAboutData : @Eq.{v} PUnit.{v} someMoreData someMoreData)
      (aFinalProof : PUnit.{u}), PropStructure.{u, v}
def projProp1 :  (x : PropStructure.{0, 1}), PUnit.{0} :=
  fun (x : PropStructure.{0, 1}) => x.1

088_projProp2

Projecting out of a proposition

The lean kernel disallows data projections out of propositional structures.

Includes: PUnit, PUnit.unit, Eq, Eq.refl, PropStructure, PropStructure.mk

def projProp2 : (x : PropStructure.{0, 1})  PUnit.{1} :=
  fun (x : PropStructure.{0, 1}) => x.2

👍 089_projProp3

Projecting out of a proposition

The lean kernel allows projections out of propositions if they precede all dependent data fields. Non-dependent data fields are not relevant.

Includes: PUnit, PUnit.unit, Eq, Eq.refl, PropStructure, PropStructure.mk

def projProp3 :  (x : PropStructure.{0, 1}), PUnit.{0} :=
  fun (x : PropStructure.{0, 1}) => x.3

090_projProp4

Projecting out of a proposition

The lean kernel disallows data projections out of propositional structures.

Includes: PUnit, PUnit.unit, Eq, Eq.refl, PropStructure, PropStructure.mk

def projProp4 : (x : PropStructure.{0, 1})  PUnit.{1} :=
  fun (x : PropStructure.{0, 1}) => x.4

091_projProp5

Projecting out of a proposition

The lean kernel disallows proof projections out of propositional structures that depend on data.

Includes: PUnit, PUnit.unit, Eq, Eq.refl, PropStructure, PropStructure.mk

def projProp5 :  (x : PropStructure.{0, 1}), @Eq.{1} PUnit.{1} x.4 x.4 :=
  fun (x : PropStructure.{0, 1}) => x.5

092_projProp6

Projecting out of a proposition.

The lean kernel rejects any projections out of a proposition that come after a dependent data field, even if that is not used by the present projection.

Includes: PUnit, PUnit.unit, Eq, Eq.refl, PropStructure, PropStructure.mk

def projProp6 :  (x : PropStructure.{0, 1}), PUnit.{0} :=
  fun (x : PropStructure.{0, 1}) => x.6

👍 093_projDataIndexRec

The recursor for ProjDataIndex allows elimination into sort.

Includes: N, N.zero, N.succ

inductive True : Prop
constructor True.intro : True
inductive ProjDataIndex (a._@._internal._hyg.0 : N) : Prop
constructor ProjDataIndex.mk :  (n : N) (p : True), ProjDataIndex n
def projDataIndexRec.{u_1} :
    {a : N} 
      {motive : (t : ProjDataIndex a)  Sort u_1} 
        (mk : (p : True)  motive (ProjDataIndex.mk a p)) 
          (t : ProjDataIndex a)  motive t :=
  @ProjDataIndex.rec.{u_1}

094_projIndexData

Projecting out data is not allowed, even if this data appears as an index and the recursor would allow it.

Includes: N, N.zero, N.succ, True, True.intro, ProjDataIndex, ProjDataIndex.mk

def projIndexData : (x : N)  (x : ProjDataIndex x)  N :=
  fun (x : N) (x_1 : ProjDataIndex x) => x_1.1

095_projIndexData2

Projecting out data is not allowed, even if this data appears as an index and the recursor would allow it.

This also forbids projecting out proofs that follow such fields.

Includes: N, N.zero, N.succ, True, True.intro, ProjDataIndex, ProjDataIndex.mk

def projIndexData2 :  (x : N) (x : ProjDataIndex x), True :=
  fun (x : N) (x_1 : ProjDataIndex x) => x_1.2

👍 096_projRed

Projection reductions

Includes: Eq, Eq.refl, Bool, Bool.false, Bool.true, Prod, Prod.mk, Prod.snd, rfl

👍 097_ruleK

Rule k for Eq: The recursor reduces even if the major argument is not a constructor, as long replacing the major argument with a constructor is type correct.

Includes: Eq, Eq.refl, Bool, Bool.false, Bool.true

theorem ruleK :
     (h : @Eq.{1} Bool Bool.true Bool.true) (a : Bool),
      @Eq.{1} Bool
        (@Eq.rec.{1, 1} Bool Bool.true
          (fun (x : Bool) (x_1 : @Eq.{1} Bool Bool.true x) => Bool) a Bool.true
          h)
        a :=
  fun (x : @Eq.{1} Bool Bool.true Bool.true) (a : Bool) => @Eq.refl.{1} Bool a

098_ruleKbad

Rule k for Eq should not fire if the types of the major argument do not match that of the constructor.

Includes: Eq, Eq.refl, Bool, Bool.false, Bool.true

theorem ruleKbad :
     (h : @Eq.{1} Bool Bool.true Bool.false) (a : Bool),
      @Eq.{1} Bool
        (@Eq.rec.{1, 1} Bool Bool.true
          (fun (x : Bool) (x_1 : @Eq.{1} Bool Bool.true x) => Bool) a Bool.false
          h)
        a :=
  fun (x : @Eq.{1} Bool Bool.true Bool.false) (a : Bool) => @Eq.refl.{1} Bool a

099_ruleKAcc

Rule k should not fire for Acc.

Includes: Bool, Bool.false, Bool.true, Eq, Eq.refl

inductive Acc.{u} {α : Sort u} (r : α  α  Prop) : α  Prop
constructor Acc.intro.{u} :
     {α : Sort u} {r : α  α  Prop} (x : α)
      (h :  (y : α), r y x  @Acc.{u} α r y), @Acc.{u} α r x
theorem ruleKAcc.{u} :
     (α : Sort u) (p : α  α  Prop) (x : α) (h : @Acc.{u} α p x) (a : Bool),
      @Eq.{1} Bool
        (@Acc.rec.{1, u} α p (fun (x : α) (x_1 : @Acc.{u} α p x) => Bool)
          (fun (x : α) (x_1 :  (y : α), p y x  @Acc.{u} α p y)
              (x_2 :
                (y : α) 
                  (a : p y x) 
                    (fun (x : α) (x_2 : @Acc.{u} α p x) => Bool) y (x_1 y a)) =>
            a)
          x h)
        a :=
  fun (α : Sort u) (p : α  α  Prop) (x : α) (h : @Acc.{u} α p x) (a : Bool) =>
    @Eq.refl.{1} Bool a

👍 100_aNatLit

Type checking Nat literals

inductive Nat : Type
constructor Nat.zero : Nat
constructor Nat.succ : (n : Nat)  Nat
def aNatLit : Nat :=
  failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)

👍 101_natLitEq

Reducing Nat literals

Includes: Eq, Eq.refl, Nat, Nat.zero, Nat.succ

theorem natLitEq : failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation) :=
  failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)

👍 102_proofIrrelevance

Proof irrelevance: every Prop is a subsingleton, if p : Prop then all elements of p are definitionally equal.

Includes: Eq, Eq.refl, rfl

def proofIrrelevance :  (p : Prop) (h1 h2 : p), @Eq.{0} p h1 h2 :=
  fun (x : Prop) (x_1 x_2 : x) => @rfl.{0} x x_1

103_proofIrrelevanceBad

Proof irrelevance is limited to Prop: if p : Type, then all elements of p are not definitionally equal.

Includes: Eq, Eq.refl, rfl

def proofIrrelevanceBad :  (p : Type) (h1 h2 : p), @Eq.{1} p h1 h2 :=
  fun (p : Type) (h1 h2 : p) => @rfl.{1} p h1

👍 104_proofIrrelevanceWhnf

Proof irrelevance: if p : A and A is definitionally equal to Prop, then all elements of p are still definitionally equal. Just applying proof irrelevance at Sort 0 isn't sufficient.

Includes: id, Eq, Eq.refl, rfl

def proofIrrelevanceWhnf :
     (p : @id.{2} Type Prop) (h1 h2 : p), @Eq.{0} p h1 h2 :=
  fun (x : @id.{2} Type Prop) (x_1 x_2 : x) => @rfl.{0} x x_1

👍 105_unitEta1

Unit eta

Includes: PUnit, PUnit.unit, Eq, Eq.refl, rfl

def Unit : Type :=
  PUnit.{1}
def unitEta1 :  (x y : Unit), @Eq.{1} Unit x y :=
  fun (x x_1 : Unit) => @rfl.{1} Unit x

👍 106_unitEta2

Unit eta

Includes: PUnit, PUnit.unit, Eq, Eq.refl, rfl

def unitEta2.{u} :  (x y : PUnit.{u}), @Eq.{u} PUnit.{u} x y :=
  fun (x x_1 : PUnit.{u}) => @rfl.{u} PUnit.{u} x

👍 107_unitEta3

Unit eta

Includes: PUnit, PUnit.unit, Eq, Eq.refl, rfl

def unitEta3 :  (x y : PUnit.{0}), @Eq.{0} PUnit.{0} x y :=
  fun (x x_1 : PUnit.{0}) => @rfl.{0} PUnit.{0} x

108_indexedUnitEta

The unit-like rule, which makes any two elements of a single-constructor type with no fields definitionally equal, is also restricted to non-recursive structures without indices (is_def_eq_unit_like goes through is_non_rec_structure), so it does not fire for IndexedUnit.

Includes: Bool, Bool.false, Bool.true, Eq, Eq.refl

inductive IndexedUnit : Bool  Type
constructor IndexedUnit.mk : IndexedUnit Bool.true
def indexedUnitEta :
     (x y : IndexedUnit Bool.true), @Eq.{1} (IndexedUnit Bool.true) x y :=
  fun (x y : IndexedUnit Bool.true) => @Eq.refl.{1} (IndexedUnit Bool.true) x

👍 109_structEta

Structure eta

Includes: Prod, Prod.mk, And, And.intro, Eq, Eq.refl, Prod.fst, Prod.snd, rfl

def structEta.{u} :
     (α β : Type u) (x : Prod.{u, u} α β),
      And
        (@Eq.{u + 1} (Prod.{u, u} α β) x
          (@Prod.mk.{u, u} α β (@Prod.fst.{u, u} α β x)
            (@Prod.snd.{u, u} α β x)))
        (@Eq.{u + 1} (Prod.{u, u} α β)
          (@Prod.mk.{u, u} α β (@Prod.fst.{u, u} α β x)
            (@Prod.snd.{u, u} α β x))
          x) :=
  fun (x x_1 : Type u) (x_2 : Prod.{u, u} x x_1) =>
    @And.intro
      (@Eq.{u + 1} (Prod.{u, u} x x_1) x_2
        (@Prod.mk.{u, u} x x_1 (@Prod.fst.{u, u} x x_1 x_2)
          (@Prod.snd.{u, u} x x_1 x_2)))
      (@Eq.{u + 1} (Prod.{u, u} x x_1)
        (@Prod.mk.{u, u} x x_1 (@Prod.fst.{u, u} x x_1 x_2)
          (@Prod.snd.{u, u} x x_1 x_2))
        x_2)
      (@rfl.{u + 1} (Prod.{u, u} x x_1) x_2)
      (@rfl.{u + 1} (Prod.{u, u} x x_1)
        (@Prod.mk.{u, u} x x_1 (@Prod.fst.{u, u} x x_1 x_2)
          (@Prod.snd.{u, u} x x_1 x_2)))

110_indexedStructEta

Structure eta applies only to non-recursive structures without indices: the official kernel's is_non_rec_structure requires nindices == 0, so it does not fire for IndexedSingleton even though that has a single constructor.

Every field of IndexedSingleton.mk is a proof, so a kernel that checks only "has a single constructor" and then compares the fields against projections would have proof irrelevance discharge the remaining goals, and would wrongly accept this.

Includes: Bool, Bool.false, Bool.true, True, True.intro, Eq, Eq.refl

inductive IndexedSingleton : Bool  Type
constructor IndexedSingleton.mk : True  IndexedSingleton Bool.true
def indexedStructEta :
     (x : IndexedSingleton Bool.true),
      @Eq.{1} (IndexedSingleton Bool.true) (IndexedSingleton.mk True.intro) x :=
  fun (x : IndexedSingleton Bool.true) =>
    @Eq.refl.{1} (IndexedSingleton Bool.true) x

👍 111_funEta

Function eta for non-dependent functions.

Includes: Eq, Eq.refl, rfl

theorem funEta :
     (α β : Type) (f : α  β), @Eq.{1} ((x : α)  β) (fun (x : α) => f x) f :=
  fun (x x_1 : Type) (f : x  x_1) =>
    @rfl.{1} ((x : x)  x_1) fun (x : x) => f x

👍 112_funEtaDep

Function eta for dependent functions (pi types).

Includes: Eq, Eq.refl, rfl

theorem funEtaDep :
     (α : Type) (β : α  Type) (f : (a : α)  β a),
      @Eq.{1} ((a : α)  β a) (fun (a : α) => f a) f :=
  fun (x : Type) (x_1 : x  Type) (f : (a : x)  x_1 a) =>
    @rfl.{1} ((a : x)  x_1 a) fun (a : x) => f a

113_funEtaBad

Eta should not identify functions with different bodies.

Includes: Eq, Eq.refl

theorem funEtaBad :
     (α β : Type) (g : α  α) (f : α  β),
      @Eq.{1} ((x : α)  β) (fun (x : α) => f (g x)) f :=
  fun (x x_1 : Type) (x_2 : x  x) (f : x  x_1) =>
    @Eq.refl.{1} ((x : x)  x_1) f

114_etaRuleK

Corner case for function eta: Does a defeq between a partially applied recursor with rule k and a free variable trigger eta expansion?

Taking the official kernel as the specification, the answer is no. See https://github.com/leanprover/lean4/issues/12520 for a discussion.

Includes: Eq, Eq.refl, Bool, Bool.false, Bool.true

115_etaCtor

Corner case for function eta: Does a defeq between a partially applied constructor trigger eta expansion?

Taking the official kernel as the specification, the answer is no. See https://github.com/leanprover/lean4/issues/12520 for a discussion.

Includes: True, True.intro, Bool, Bool.false, Bool.true, Eq, Eq.refl

inductive T : Type
constructor T.mk : (val : Bool)  (proof : True)  T
def T.val : (self : T)  Bool :=
  fun (self : T) => self.1
def etaCtor :
     (x : (proof : True)  T),
      @Eq.{1} ((proof : True)  T) (T.mk (T.val (x True.intro))) x :=
  fun (x : (proof : True)  T) => @Eq.refl.{1} ((proof : True)  T) x

116_reflOccLeft

Rejection: recursive occurrence on the left of an arrow, behind further arrows inside a constructor argument.

The constructor argument is a function type Nat → (I → Nat).

Includes: Nat, Nat.zero, Nat.succ

inductive reflOccLeft : Type
constructor reflOccLeft.mk :
    (x : (x : Nat)  (x : reflOccLeft)  Nat)  reflOccLeft

117_reflOccInIndex

Rejection: recursive occurrence in index position, behind a further arrow.

We build an indexed inductive I : Type → Type with a constructor argument Nat → I (I α), so the recursive occurrence appears as an index argument.

Includes: Nat, Nat.zero, Nat.succ

inductive reflOccInIndex : (α : Type)  Type
constructor reflOccInIndex.mk :
    (α : Type) 
      (x : (x : Nat)  reflOccInIndex (reflOccInIndex x))  reflOccInIndex α

👍 118_reduceCtorParamRefl.mk

When checking inductives, we expect the kernel to reduce the types of constructor arguments in all positive positions.

Includes: id, constType

inductive reduceCtorParamRefl (a._@._internal._hyg.0 : Type) : Type
constructor reduceCtorParamRefl.mk :
    (α : @id.{3} (Type 1) Type) 
      (x :
          (x : α)  constType (reduceCtorParamRefl α) (reduceCtorParamRefl α)) 
        reduceCtorParamRefl α

👍 119_reduceCtorParamRefl2.mk

When checking inductives, we expect the kernel to reduce the types of constructor arguments in all positive positions.

Includes: id, constType

inductive reduceCtorParamRefl2 (a._@._internal._hyg.0 : Type) : Type
constructor reduceCtorParamRefl2.mk :
    (α : @id.{3} (Type 1) Type) 
      (x : (x : α)  constType (reduceCtorParamRefl2 α) α) 
        reduceCtorParamRefl2 α

👍 120_rTreeRec

Asserting the type of the generated recursor.

Includes: Bool, Bool.false, Bool.true

inductive RTree : Type
constructor RTree.leaf : RTree
constructor RTree.node : (children : Bool  RTree)  RTree
def rTreeRec.{u_1} :
    {motive : (t : RTree)  Sort u_1} 
      (leaf : motive RTree.leaf) 
        (node :
            (children : Bool  RTree) 
              (children_ih : (a : Bool)  motive (children a)) 
                motive (RTree.node children)) 
          (t : RTree)  motive t :=
  @RTree.rec.{u_1}

👍 121_rtreeRecReduction

Reduction behavior of RTree.rec on RTree.mk.

Includes: Bool, Bool.false, Bool.true, RTree, RTree.leaf, RTree.node, Eq, Eq.refl, rfl

def RTree.left : (t : RTree)  RTree :=
  fun (t : RTree) =>
    @RTree.rec.{1} (fun (x : RTree) => RTree) RTree.leaf
      (fun (children : Bool  RTree)
          (_ih : (a : Bool)  (fun (x : RTree) => RTree) (children a)) =>
        children Bool.true)
      t
theorem rtreeRecReduction :
     (t1 t2 : RTree),
      @Eq.{1} RTree
        (RTree.left
          (RTree.node fun (t : Bool) =>
            @Bool.rec.{1} (fun (x : Bool) => RTree) t2 t1 t))
        t1 :=
  fun (x x_1 : RTree) =>
    @rfl.{1} RTree
      (RTree.left
        (RTree.node fun (t : Bool) =>
          @Bool.rec.{1} (fun (x : Bool) => RTree) x_1 x t))

👍 122_accRecType

Asserting the type of Acc.rec.

Includes: Acc, Acc.intro

def accRecType.{u_1, u_2} :
    {α : Sort u_1} 
      {r : α  α  Prop} 
        {motive : (a : α)  (t : @Acc.{u_1} α r a)  Sort u_2} 
          (intro :
              (x : α) 
                (h :  (y : α), r y x  @Acc.{u_1} α r y) 
                  (h_ih : (y : α)  (a : r y x)  motive y (h y a)) 
                    motive x (@Acc.intro.{u_1} α r x h)) 
            {a : α}  (t : @Acc.{u_1} α r a)  motive a t :=
  @Acc.rec.{u_2, u_1}

👍 123_accRecReduction

Acc.rec reduces on Acc.intro.

Includes: Acc, Acc.intro, Bool, Bool.false, Bool.true, Eq, Eq.refl

theorem accRecReduction :
     {α : Type} (r : α  α  Prop) (a : α)
      (h :  (b : α), r b a  @Acc.{1} α r b) (p : Bool),
      @Eq.{1} Bool
        (@Acc.rec.{1, 1} α r (fun (x : α) (x_1 : @Acc.{1} α r x) => Bool)
          (fun (x : α) (x_1 :  (y : α), r y x  @Acc.{1} α r y)
              (x_2 :
                (y : α) 
                  (a : r y x) 
                    (fun (x : α) (x_2 : @Acc.{1} α r x) => Bool) y (x_1 y a)) =>
            p)
          a (@Acc.intro.{1} α r a h))
        p :=
  fun {α : Type} (r : α  α  Prop) (a : α)
      (h :  (b : α), r b a  @Acc.{1} α r b) (p : Bool) =>
    @Eq.refl.{1} Bool
      (@Acc.rec.{1, 1} α r (fun (x : α) (x_1 : @Acc.{1} α r x) => Bool)
        (fun (x : α) (x_1 :  (y : α), r y x  @Acc.{1} α r y)
            (x_2 :
              (y : α) 
                (a : r y x) 
                  (fun (x : α) (x_2 : @Acc.{1} α r x) => Bool) y (x_1 y a)) =>
          p)
        a (@Acc.intro.{1} α r a h))

124_accRecNoEta

Acc.rec does not have structure eta.

Includes: Acc, Acc.intro, Bool, Bool.false, Bool.true, Eq, Eq.refl

theorem accRecNoEta :
     {α : Type} (r : α  α  Prop) (a : α) (h : @Acc.{1} α r a) (p : Bool),
      @Eq.{1} Bool
        (@Acc.rec.{1, 1} α r (fun (x : α) (x_1 : @Acc.{1} α r x) => Bool)
          (fun (x : α) (x_1 :  (y : α), r y x  @Acc.{1} α r y)
              (x_2 :
                (y : α) 
                  (a : r y x) 
                    (fun (x : α) (x_2 : @Acc.{1} α r x) => Bool) y (x_1 y a)) =>
            p)
          a h)
        p :=
  fun (α : Type) (r : α  α  Prop) (a : α) (h : @Acc.{1} α r a) (p : Bool) =>
    @Eq.refl.{1} Bool p

👍 125_quotMkType

Asserting the type of Quot.mk.

Includes: Eq, Eq.refl

quot Quot.{u} : {α : Sort u}  (r : α  α  Prop)  Sort u
quot Quot.mk.{u} : {α : Sort u}  (r : α  α  Prop)  (a : α)  @Quot.{u} α r
quot Quot.lift.{u, v} :
    {α : Sort u} 
      {r : α  α  Prop} 
        {β : Sort v} 
          (f : (a : α)  β) 
            (a :  (a b : α) (a_1 : r a b), @Eq.{v} β (f a) (f b)) 
              (a : @Quot.{u} α r)  β
quot Quot.ind.{u} :
     {α : Sort u} {r : α  α  Prop} {β : (a : @Quot.{u} α r)  Prop}
      (mk :  (a : α), β (@Quot.mk.{u} α r a)) (q : @Quot.{u} α r), β q
def quotMkType.{u} : {α : Sort u}  (r : α  α  Prop)  (a : α)  @Quot.{u} α r :=
  @Quot.mk.{u}

👍 126_quotIndType

Asserting the type of Quot.ind.

Includes: Eq, Eq.refl, Quot, Quot.mk, Quot.lift, Quot.ind

def quotIndType.{u} :
     {α : Sort u} {r : α  α  Prop} {β : (a : @Quot.{u} α r)  Prop}
      (mk :  (a : α), β (@Quot.mk.{u} α r a)) (q : @Quot.{u} α r), β q :=
  @Quot.ind.{u}

👍 127_quotLiftType

Asserting the type of Quot.lift.

Includes: Eq, Eq.refl, Quot, Quot.mk, Quot.lift, Quot.ind

def quotLiftType.{u, v} :
    {α : Sort u} 
      {r : α  α  Prop} 
        {β : Sort v} 
          (f : (a : α)  β) 
            (a :  (a b : α) (a_1 : r a b), @Eq.{v} β (f a) (f b)) 
              (a : @Quot.{u} α r)  β :=
  @Quot.lift.{u, v}

👍 128_quotSoundType

Asserting the type of Quot.sound.

Includes: Eq, Eq.refl, Quot, Quot.mk, Quot.lift, Quot.ind

axiom Quot.sound.{u} :
     {α : Sort u} {r : α  α  Prop} {a b : α},
      r a b  @Eq.{u} (@Quot.{u} α r) (@Quot.mk.{u} α r a) (@Quot.mk.{u} α r b)
def quotSoundType.{u} :
     {α : Sort u} {r : α  α  Prop} {a b : α},
      r a b  @Eq.{u} (@Quot.{u} α r) (@Quot.mk.{u} α r a) (@Quot.mk.{u} α r b) :=
  @Quot.sound.{u}

👍 129_quotLiftReduction

Reduction behavior of Quot.lift on Quot.mk.

Includes: Eq, Eq.refl, Quot, Quot.mk, Quot.lift, Quot.ind

theorem quotLiftReduction.{u, v} :
     {α : Sort u} {r : α  α  Prop} {β : Sort v} (f : (a : α)  β)
      (h :  (a b : α) (a_1 : r a b), @Eq.{v} β (f a) (f b)) (a : α),
      @Eq.{v} β (@Quot.lift.{u, v} α r β f h (@Quot.mk.{u} α r a)) (f a) :=
  fun {α : Sort u} {r : α  α  Prop} {β : Sort v} (f : (a : α)  β)
      (h :  (a b : α) (a_1 : r a b), @Eq.{v} β (f a) (f b)) (a : α) =>
    @Eq.refl.{v} β (@Quot.lift.{u, v} α r β f h (@Quot.mk.{u} α r a))

👍 130_quotIndReduction

Reduction behavior of Quot.ind on Quot.mk.

Includes: Eq, Eq.refl, Quot, Quot.mk, Quot.lift, Quot.ind

theorem quotIndReduction.{u} :
     {α : Sort u} (r : α  α  Prop) {β : (a : @Quot.{u} α r)  Prop}
      (mk :  (a : α), β (@Quot.mk.{u} α r a)) (a : α),
      @Eq.{0} (β (@Quot.mk.{u} α r a))
        (@Quot.ind.{u} α r β mk (@Quot.mk.{u} α r a)) (mk a) :=
  fun {α : Sort u} (r : α  α  Prop) {β : (a : @Quot.{u} α r)  Prop}
      (mk :  (a : α), β (@Quot.mk.{u} α r a)) (a : α) =>
    @Eq.refl.{0} (β (@Quot.mk.{u} α r a))
      (@Quot.ind.{u} α r β mk (@Quot.mk.{u} α r a))

131_dup_defs

Two definitions with the same name

Includes: dup_defs

def dup_defs : Type :=
  Prop

132_dup_ind_def

A definition and a constructor with the same name

Includes: dup_ind_def

inductive dup_ind_def : Type
constructor dup_ind_def.mk : dup_ind_def

133_dup_ctor_def

A definition and a constructor with the same name

Includes: dup_ctor_def.mk

constructor dup_ctor_def.mk : dup_ctor_def
inductive dup_ctor_def : Type

134_dup_rec_def

A definition and a recursor with the same name

inductive dup_rec_def : Type
constructor dup_rec_def.mk : dup_rec_def

135_misnamed_rec_user

The name of the recursor for misnamed_rec must be misnamed_rec.rec: another name (like misnamed_rec.not_rec) should be rejected. dupRecUser is included so that checkers that recreate the recursor (as misnamed_rec.rec) rather than validating it still fail, because misnamed_rec_user references misnamed_rec.not_rec.

inductive misnamed_rec : Type
constructor misnamed_rec.mk : misnamed_rec
def misnamed_rec_user.{u_1} :
    {motive : (t : misnamed_rec)  Sort u_1} 
      (mk : motive misnamed_rec.mk)  (t : misnamed_rec)  motive t :=
  @misnamed_rec.not_rec.{u_1}

136_dup_rec_def2

Even if a kernel doesn't catch a recursor for dup_rec_def2 that is misnamed as dup_rec_def2.not_rec, it should catch some other constant being given the name dup_rec_def2.rec that is reserved for the recursor.

def dup_rec_def2.rec : Type :=
  Prop
inductive dup_rec_def2 : Type
constructor dup_rec_def2.mk : dup_rec_def2

137_dup_ctor_rec

A constructor and a recursor with the same name

inductive dup_ctor_rec : Type

138_DupConCon

An inductive with two constructors with the same name

Includes: dup_ind_con_con.mk

inductive DupConCon : Type
constructor dup_ind_con_con.mk : DupConCon