l3lab/ntp-mathlib huggingface dataset:
/-- The clifford algebra over a 1-dimensional vector space with 0 quadratic form is isomorphic to
the dual numbers. -/
protected def equiv : CliffordAlgebra (0 : QuadraticForm R R) ≃ₐ[R] R[ε] :=
  AlgEquiv.ofAlgHom
    (CliffordAlgebra.lift (0 : QuadraticForm R R) ⟨inrHom R _, fun m => inr_mul_inr _ m m⟩)
    (DualNumber.lift ⟨
      (Algebra.ofId _ _, ι (R := R) _ 1),
      ι_mul_ι (1 : R) 1,
      fun _ => (Algebra.commutes _ _).symm⟩)
    (by
      ext : 1
      -- This used to be a single `simp` before leanprover/lean4#2644
      simp; erw [lift_ι_apply]; simp)
    -- This used to be a single `simp` before leanprover/lean4#2644
    (by 

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
⊢ AlgHom.comp
      (DualNumber.lift
        { val := (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1),
          property :=
            (_ :
              (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2 * (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2 = 0 ∧
                ∀ (a : R),
                  Commute (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2
                    ((Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).1 a)) })
      ((CliffordAlgebra.lift 0) { val := inrHom R R, property := (_ : ∀ (m : R), inr m * inr m = 0) }) =
    AlgHom.id R (CliffordAlgebra 0)

Next tactic:
ext : 2
/-- The clifford algebra over a 1-dimensional vector space with 0 quadratic form is isomorphic to
the dual numbers. -/
protected def equiv : CliffordAlgebra (0 : QuadraticForm R R) ≃ₐ[R] R[ε] :=
  AlgEquiv.ofAlgHom
    (CliffordAlgebra.lift (0 : QuadraticForm R R) ⟨inrHom R _, fun m => inr_mul_inr _ m m⟩)
    (DualNumber.lift ⟨
      (Algebra.ofId _ _, ι (R := R) _ 1),
      ι_mul_ι (1 : R) 1,
      fun _ => (Algebra.commutes _ _).symm⟩)
    (by
      ext : 1
      -- This used to be a single `simp` before leanprover/lean4#2644
      simp; erw [lift_ι_apply]; simp)
    -- This used to be a single `simp` before leanprover/lean4#2644
    (by ext : 2; 

Proof state:
case a.h
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
⊢ (AlgHom.toLinearMap
          (AlgHom.comp
            (DualNumber.lift
              { val := (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1),
                property :=
                  (_ :
                    (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2 * (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2 =
                        0 ∧
                      ∀ (a : R),
                        Commute (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2
                          ((Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).1 a)) })
            ((CliffordAlgebra.lift 0) { val := inrHom R R, property := (_ : ∀ (m : R), inr m * inr m = 0) })) ∘ₗ
        ι 0)
      1 =
    (AlgHom.toLinearMap (AlgHom.id R (CliffordAlgebra 0)) ∘ₗ ι 0) 1

Next tactic:
simp
/-- The clifford algebra over a 1-dimensional vector space with 0 quadratic form is isomorphic to
the dual numbers. -/
protected def equiv : CliffordAlgebra (0 : QuadraticForm R R) ≃ₐ[R] R[ε] :=
  AlgEquiv.ofAlgHom
    (CliffordAlgebra.lift (0 : QuadraticForm R R) ⟨inrHom R _, fun m => inr_mul_inr _ m m⟩)
    (DualNumber.lift ⟨
      (Algebra.ofId _ _, ι (R := R) _ 1),
      ι_mul_ι (1 : R) 1,
      fun _ => (Algebra.commutes _ _).symm⟩)
    (by
      ext : 1
      -- This used to be a single `simp` before leanprover/lean4#2644
      simp; erw [lift_ι_apply]; simp)
    -- This used to be a single `simp` before leanprover/lean4#2644
    (by ext : 2; simp; 

Proof state:
case a.h
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
⊢ (DualNumber.lift
        { val := (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1),
          property :=
            (_ :
              (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2 * (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2 = 0 ∧
                ∀ (a : R),
                  Commute (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2
                    ((Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).1 a)) })
      (((CliffordAlgebra.lift 0) { val := inrHom R R, property := (_ : ∀ (m : R), inr m * inr m = 0) }) ((ι 0) 1)) =
    (ι 0) 1

Next tactic:
erw [lift_ι_apply]
/-- The clifford algebra over a 1-dimensional vector space with 0 quadratic form is isomorphic to
the dual numbers. -/
protected def equiv : CliffordAlgebra (0 : QuadraticForm R R) ≃ₐ[R] R[ε] :=
  AlgEquiv.ofAlgHom
    (CliffordAlgebra.lift (0 : QuadraticForm R R) ⟨inrHom R _, fun m => inr_mul_inr _ m m⟩)
    (DualNumber.lift ⟨
      (Algebra.ofId _ _, ι (R := R) _ 1),
      ι_mul_ι (1 : R) 1,
      fun _ => (Algebra.commutes _ _).symm⟩)
    (by
      ext : 1
      -- This used to be a single `simp` before leanprover/lean4#2644
      simp; erw [lift_ι_apply]; simp)
    -- This used to be a single `simp` before leanprover/lean4#2644
    (by ext : 2; simp; erw [lift_ι_apply]; 

Proof state:
case a.h
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
⊢ (DualNumber.lift
        { val := (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1),
          property :=
            (_ :
              (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2 * (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2 = 0 ∧
                ∀ (a : R),
                  Commute (Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).2
                    ((Algebra.ofId R (CliffordAlgebra 0), (ι 0) 1).1 a)) })
      ((inrHom R R) 1) =
    (ι 0) 1

Next tactic:
simp
instance (priority := 100) sq_hasLift_of_hasLiftingProperty {f : A ⟶ X} {g : B ⟶ Y}
    (sq : CommSq f i p g) [hip : HasLiftingProperty i p] : sq.HasLift := by 

Proof state:
C : Type u_1
inst✝ : Category.{?u.598, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
f : A ⟶ X
g : B ⟶ Y
sq : CommSq f i p g
hip : HasLiftingProperty i p
⊢ CommSq.HasLift sq

Next tactic:
apply hip.sq_hasLift
theorem op (h : HasLiftingProperty i p) : HasLiftingProperty p.op i.op :=
  ⟨fun {f} {g} sq => by
    

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
h : HasLiftingProperty i p
f : Opposite.op Y ⟶ Opposite.op B
g : Opposite.op X ⟶ Opposite.op A
sq : CommSq f p.op i.op g
⊢ CommSq.HasLift sq

Next tactic:
simp only [CommSq.HasLift.iff_unop, Quiver.Hom.unop_op]
theorem op (h : HasLiftingProperty i p) : HasLiftingProperty p.op i.op :=
  ⟨fun {f} {g} sq => by
    simp only [CommSq.HasLift.iff_unop, Quiver.Hom.unop_op]
    

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
h : HasLiftingProperty i p
f : Opposite.op Y ⟶ Opposite.op B
g : Opposite.op X ⟶ Opposite.op A
sq : CommSq f p.op i.op g
⊢ CommSq.HasLift (_ : CommSq g.unop i p f.unop)

Next tactic:
infer_instance
theorem unop {A B X Y : Cᵒᵖ} {i : A ⟶ B} {p : X ⟶ Y} (h : HasLiftingProperty i p) :
    HasLiftingProperty p.unop i.unop :=
  ⟨fun {f} {g} sq => by
    

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B' X✝ Y✝ Y' : C
i✝ : A✝ ⟶ B✝
i' : B✝ ⟶ B'
p✝ : X✝ ⟶ Y✝
p' : Y✝ ⟶ Y'
A B X Y : Cᵒᵖ
i : A ⟶ B
p : X ⟶ Y
h : HasLiftingProperty i p
f : Y.unop ⟶ B.unop
g : X.unop ⟶ A.unop
sq : CommSq f p.unop i.unop g
⊢ CommSq.HasLift sq

Next tactic:
rw [CommSq.HasLift.iff_op]
theorem unop {A B X Y : Cᵒᵖ} {i : A ⟶ B} {p : X ⟶ Y} (h : HasLiftingProperty i p) :
    HasLiftingProperty p.unop i.unop :=
  ⟨fun {f} {g} sq => by
    rw [CommSq.HasLift.iff_op]
    

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B' X✝ Y✝ Y' : C
i✝ : A✝ ⟶ B✝
i' : B✝ ⟶ B'
p✝ : X✝ ⟶ Y✝
p' : Y✝ ⟶ Y'
A B X Y : Cᵒᵖ
i : A ⟶ B
p : X ⟶ Y
h : HasLiftingProperty i p
f : Y.unop ⟶ B.unop
g : X.unop ⟶ A.unop
sq : CommSq f p.unop i.unop g
⊢ CommSq.HasLift (_ : CommSq g.op i.unop.op p.unop.op f.op)

Next tactic:
simp only [Quiver.Hom.op_unop]
theorem unop {A B X Y : Cᵒᵖ} {i : A ⟶ B} {p : X ⟶ Y} (h : HasLiftingProperty i p) :
    HasLiftingProperty p.unop i.unop :=
  ⟨fun {f} {g} sq => by
    rw [CommSq.HasLift.iff_op]
    simp only [Quiver.Hom.op_unop]
    

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B' X✝ Y✝ Y' : C
i✝ : A✝ ⟶ B✝
i' : B✝ ⟶ B'
p✝ : X✝ ⟶ Y✝
p' : Y✝ ⟶ Y'
A B X Y : Cᵒᵖ
i : A ⟶ B
p : X ⟶ Y
h : HasLiftingProperty i p
f : Y.unop ⟶ B.unop
g : X.unop ⟶ A.unop
sq : CommSq f p.unop i.unop g
⊢ CommSq.HasLift (_ : CommSq g.op i p f.op)

Next tactic:
infer_instance
instance (priority := 100) of_left_iso [IsIso i] : HasLiftingProperty i p :=
  ⟨fun {f} {g} sq =>
    CommSq.HasLift.mk'
      { l := inv i ≫ f
        fac_left := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.3720, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝ : IsIso i
f : A ⟶ X
g : B ⟶ Y
sq : CommSq f i p g
⊢ i ≫ inv i ≫ f = f

Next tactic:
simp only [IsIso.hom_inv_id_assoc]
instance (priority := 100) of_left_iso [IsIso i] : HasLiftingProperty i p :=
  ⟨fun {f} {g} sq =>
    CommSq.HasLift.mk'
      { l := inv i ≫ f
        fac_left := by simp only [IsIso.hom_inv_id_assoc]
        fac_right := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.3720, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝ : IsIso i
f : A ⟶ X
g : B ⟶ Y
sq : CommSq f i p g
⊢ (inv i ≫ f) ≫ p = g

Next tactic:
simp only [sq.w, assoc, IsIso.inv_hom_id_assoc]
instance (priority := 100) of_right_iso [IsIso p] : HasLiftingProperty i p :=
  ⟨fun {f} {g} sq =>
    CommSq.HasLift.mk'
      { l := g ≫ inv p
        fac_left := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.4577, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝ : IsIso p
f : A ⟶ X
g : B ⟶ Y
sq : CommSq f i p g
⊢ i ≫ g ≫ inv p = f

Next tactic:
simp only [← sq.w_assoc, IsIso.hom_inv_id, comp_id]
instance (priority := 100) of_right_iso [IsIso p] : HasLiftingProperty i p :=
  ⟨fun {f} {g} sq =>
    CommSq.HasLift.mk'
      { l := g ≫ inv p
        fac_left := by simp only [← sq.w_assoc, IsIso.hom_inv_id, comp_id]
        fac_right := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.4577, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝ : IsIso p
f : A ⟶ X
g : B ⟶ Y
sq : CommSq f i p g
⊢ (g ≫ inv p) ≫ p = g

Next tactic:
simp only [assoc, IsIso.inv_hom_id, comp_id]
instance of_comp_left [HasLiftingProperty i p] [HasLiftingProperty i' p] :
    HasLiftingProperty (i ≫ i') p :=
  ⟨fun {f} {g} sq => by
    

Proof state:
C : Type u_1
inst✝² : Category.{?u.5611, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i' p
f : A ⟶ X
g : B' ⟶ Y
sq : CommSq f (i ≫ i') p g
⊢ CommSq.HasLift sq

Next tactic:
have fac := sq.w
instance of_comp_left [HasLiftingProperty i p] [HasLiftingProperty i' p] :
    HasLiftingProperty (i ≫ i') p :=
  ⟨fun {f} {g} sq => by
    have fac := sq.w
    

Proof state:
C : Type u_1
inst✝² : Category.{?u.5611, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i' p
f : A ⟶ X
g : B' ⟶ Y
sq : CommSq f (i ≫ i') p g
fac : f ≫ p = (i ≫ i') ≫ g
⊢ CommSq.HasLift sq

Next tactic:
rw [assoc] at fac
instance of_comp_left [HasLiftingProperty i p] [HasLiftingProperty i' p] :
    HasLiftingProperty (i ≫ i') p :=
  ⟨fun {f} {g} sq => by
    have fac := sq.w
    rw [assoc] at fac
    

Proof state:
C : Type u_1
inst✝² : Category.{?u.5611, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i' p
f : A ⟶ X
g : B' ⟶ Y
sq : CommSq f (i ≫ i') p g
fac : f ≫ p = i ≫ i' ≫ g
⊢ CommSq.HasLift sq

Next tactic:
exact
      CommSq.HasLift.mk'
        { l := (CommSq.mk (CommSq.mk fac).fac_right).lift
          fac_left := by simp only [assoc, CommSq.fac_left]
          fac_right := by simp only [CommSq.fac_right] }
instance of_comp_left [HasLiftingProperty i p] [HasLiftingProperty i' p] :
    HasLiftingProperty (i ≫ i') p :=
  ⟨fun {f} {g} sq => by
    have fac := sq.w
    rw [assoc] at fac
    exact
      CommSq.HasLift.mk'
        { l := (CommSq.mk (CommSq.mk fac).fac_right).lift
          fac_left := by 

Proof state:
C : Type u_1
inst✝² : Category.{?u.5611, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i' p
f : A ⟶ X
g : B' ⟶ Y
sq : CommSq f (i ≫ i') p g
fac : f ≫ p = i ≫ i' ≫ g
⊢ (i ≫ i') ≫ CommSq.lift (_ : CommSq (CommSq.lift (_ : CommSq f i p (i' ≫ g))) i' p g) = f

Next tactic:
simp only [assoc, CommSq.fac_left]
instance of_comp_left [HasLiftingProperty i p] [HasLiftingProperty i' p] :
    HasLiftingProperty (i ≫ i') p :=
  ⟨fun {f} {g} sq => by
    have fac := sq.w
    rw [assoc] at fac
    exact
      CommSq.HasLift.mk'
        { l := (CommSq.mk (CommSq.mk fac).fac_right).lift
          fac_left := by simp only [assoc, CommSq.fac_left]
          fac_right := by 

Proof state:
C : Type u_1
inst✝² : Category.{?u.5611, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i' p
f : A ⟶ X
g : B' ⟶ Y
sq : CommSq f (i ≫ i') p g
fac : f ≫ p = i ≫ i' ≫ g
⊢ CommSq.lift (_ : CommSq (CommSq.lift (_ : CommSq f i p (i' ≫ g))) i' p g) ≫ p = g

Next tactic:
simp only [CommSq.fac_right]
instance of_comp_right [HasLiftingProperty i p] [HasLiftingProperty i p'] :
    HasLiftingProperty i (p ≫ p') :=
  ⟨fun {f} {g} sq => by
    

Proof state:
C : Type u_1
inst✝² : Category.{?u.7184, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i p'
f : A ⟶ X
g : B ⟶ Y'
sq : CommSq f i (p ≫ p') g
⊢ CommSq.HasLift sq

Next tactic:
have fac := sq.w
instance of_comp_right [HasLiftingProperty i p] [HasLiftingProperty i p'] :
    HasLiftingProperty i (p ≫ p') :=
  ⟨fun {f} {g} sq => by
    have fac := sq.w
    

Proof state:
C : Type u_1
inst✝² : Category.{?u.7184, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i p'
f : A ⟶ X
g : B ⟶ Y'
sq : CommSq f i (p ≫ p') g
fac : f ≫ p ≫ p' = i ≫ g
⊢ CommSq.HasLift sq

Next tactic:
rw [← assoc] at fac
instance of_comp_right [HasLiftingProperty i p] [HasLiftingProperty i p'] :
    HasLiftingProperty i (p ≫ p') :=
  ⟨fun {f} {g} sq => by
    have fac := sq.w
    rw [← assoc] at fac
    

Proof state:
C : Type u_1
inst✝² : Category.{?u.7184, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i p'
f : A ⟶ X
g : B ⟶ Y'
sq : CommSq f i (p ≫ p') g
fac : (f ≫ p) ≫ p' = i ≫ g
⊢ CommSq.HasLift sq

Next tactic:
let _ := (CommSq.mk (CommSq.mk fac).fac_left.symm).lift
instance of_comp_right [HasLiftingProperty i p] [HasLiftingProperty i p'] :
    HasLiftingProperty i (p ≫ p') :=
  ⟨fun {f} {g} sq => by
    have fac := sq.w
    rw [← assoc] at fac
    let _ := (CommSq.mk (CommSq.mk fac).fac_left.symm).lift
    

Proof state:
C : Type u_1
inst✝² : Category.{?u.7184, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i p'
f : A ⟶ X
g : B ⟶ Y'
sq : CommSq f i (p ≫ p') g
fac : (f ≫ p) ≫ p' = i ≫ g
x✝ : B ⟶ X := CommSq.lift (_ : CommSq f i p (CommSq.lift (_ : CommSq (f ≫ p) i p' g)))
⊢ CommSq.HasLift sq

Next tactic:
exact
      CommSq.HasLift.mk'
        { l := (CommSq.mk (CommSq.mk fac).fac_left.symm).lift
          fac_left := by simp only [CommSq.fac_left]
          fac_right := by simp only [CommSq.fac_right_assoc, CommSq.fac_right] }
instance of_comp_right [HasLiftingProperty i p] [HasLiftingProperty i p'] :
    HasLiftingProperty i (p ≫ p') :=
  ⟨fun {f} {g} sq => by
    have fac := sq.w
    rw [← assoc] at fac
    let _ := (CommSq.mk (CommSq.mk fac).fac_left.symm).lift
    exact
      CommSq.HasLift.mk'
        { l := (CommSq.mk (CommSq.mk fac).fac_left.symm).lift
          fac_left := by 

Proof state:
C : Type u_1
inst✝² : Category.{?u.7184, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i p'
f : A ⟶ X
g : B ⟶ Y'
sq : CommSq f i (p ≫ p') g
fac : (f ≫ p) ≫ p' = i ≫ g
x✝ : B ⟶ X := CommSq.lift (_ : CommSq f i p (CommSq.lift (_ : CommSq (f ≫ p) i p' g)))
⊢ i ≫ CommSq.lift (_ : CommSq f i p (CommSq.lift (_ : CommSq (f ≫ p) i p' g))) = f

Next tactic:
simp only [CommSq.fac_left]
instance of_comp_right [HasLiftingProperty i p] [HasLiftingProperty i p'] :
    HasLiftingProperty i (p ≫ p') :=
  ⟨fun {f} {g} sq => by
    have fac := sq.w
    rw [← assoc] at fac
    let _ := (CommSq.mk (CommSq.mk fac).fac_left.symm).lift
    exact
      CommSq.HasLift.mk'
        { l := (CommSq.mk (CommSq.mk fac).fac_left.symm).lift
          fac_left := by simp only [CommSq.fac_left]
          fac_right := by 

Proof state:
C : Type u_1
inst✝² : Category.{?u.7184, u_1} C
A B B' X Y Y' : C
i : A ⟶ B
i' : B ⟶ B'
p : X ⟶ Y
p' : Y ⟶ Y'
inst✝¹ : HasLiftingProperty i p
inst✝ : HasLiftingProperty i p'
f : A ⟶ X
g : B ⟶ Y'
sq : CommSq f i (p ≫ p') g
fac : (f ≫ p) ≫ p' = i ≫ g
x✝ : B ⟶ X := CommSq.lift (_ : CommSq f i p (CommSq.lift (_ : CommSq (f ≫ p) i p' g)))
⊢ CommSq.lift (_ : CommSq f i p (CommSq.lift (_ : CommSq (f ≫ p) i p' g))) ≫ p ≫ p' = g

Next tactic:
simp only [CommSq.fac_right_assoc, CommSq.fac_right]
theorem of_arrow_iso_left {A B A' B' X Y : C} {i : A ⟶ B} {i' : A' ⟶ B'}
    (e : Arrow.mk i ≅ Arrow.mk i') (p : X ⟶ Y) [hip : HasLiftingProperty i p] :
    HasLiftingProperty i' p := by
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B'✝ X✝ Y✝ Y' : C
i✝ : A✝ ⟶ B✝
i'✝ : B✝ ⟶ B'✝
p✝ : X✝ ⟶ Y✝
p' : Y✝ ⟶ Y'
A B A' B' X Y : C
i : A ⟶ B
i' : A' ⟶ B'
e : Arrow.mk i ≅ Arrow.mk i'
p : X ⟶ Y
hip : HasLiftingProperty i p
⊢ HasLiftingProperty i' p

Next tactic:
rw [Arrow.iso_w' e]
theorem of_arrow_iso_left {A B A' B' X Y : C} {i : A ⟶ B} {i' : A' ⟶ B'}
    (e : Arrow.mk i ≅ Arrow.mk i') (p : X ⟶ Y) [hip : HasLiftingProperty i p] :
    HasLiftingProperty i' p := by
  rw [Arrow.iso_w' e]
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B'✝ X✝ Y✝ Y' : C
i✝ : A✝ ⟶ B✝
i'✝ : B✝ ⟶ B'✝
p✝ : X✝ ⟶ Y✝
p' : Y✝ ⟶ Y'
A B A' B' X Y : C
i : A ⟶ B
i' : A' ⟶ B'
e : Arrow.mk i ≅ Arrow.mk i'
p : X ⟶ Y
hip : HasLiftingProperty i p
⊢ HasLiftingProperty (e.inv.left ≫ i ≫ e.hom.right) p

Next tactic:
infer_instance
theorem of_arrow_iso_right {A B X Y X' Y' : C} (i : A ⟶ B) {p : X ⟶ Y} {p' : X' ⟶ Y'}
    (e : Arrow.mk p ≅ Arrow.mk p') [hip : HasLiftingProperty i p] : HasLiftingProperty i p' := by
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B' X✝ Y✝ Y'✝ : C
i✝ : A✝ ⟶ B✝
i' : B✝ ⟶ B'
p✝ : X✝ ⟶ Y✝
p'✝ : Y✝ ⟶ Y'✝
A B X Y X' Y' : C
i : A ⟶ B
p : X ⟶ Y
p' : X' ⟶ Y'
e : Arrow.mk p ≅ Arrow.mk p'
hip : HasLiftingProperty i p
⊢ HasLiftingProperty i p'

Next tactic:
rw [Arrow.iso_w' e]
theorem of_arrow_iso_right {A B X Y X' Y' : C} (i : A ⟶ B) {p : X ⟶ Y} {p' : X' ⟶ Y'}
    (e : Arrow.mk p ≅ Arrow.mk p') [hip : HasLiftingProperty i p] : HasLiftingProperty i p' := by
  rw [Arrow.iso_w' e]
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B' X✝ Y✝ Y'✝ : C
i✝ : A✝ ⟶ B✝
i' : B✝ ⟶ B'
p✝ : X✝ ⟶ Y✝
p'✝ : Y✝ ⟶ Y'✝
A B X Y X' Y' : C
i : A ⟶ B
p : X ⟶ Y
p' : X' ⟶ Y'
e : Arrow.mk p ≅ Arrow.mk p'
hip : HasLiftingProperty i p
⊢ HasLiftingProperty i (e.inv.left ≫ p ≫ e.hom.right)

Next tactic:
infer_instance
theorem iff_of_arrow_iso_left {A B A' B' X Y : C} {i : A ⟶ B} {i' : A' ⟶ B'}
    (e : Arrow.mk i ≅ Arrow.mk i') (p : X ⟶ Y) :
    HasLiftingProperty i p ↔ HasLiftingProperty i' p := by
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B'✝ X✝ Y✝ Y' : C
i✝ : A✝ ⟶ B✝
i'✝ : B✝ ⟶ B'✝
p✝ : X✝ ⟶ Y✝
p' : Y✝ ⟶ Y'
A B A' B' X Y : C
i : A ⟶ B
i' : A' ⟶ B'
e : Arrow.mk i ≅ Arrow.mk i'
p : X ⟶ Y
⊢ HasLiftingProperty i p ↔ HasLiftingProperty i' p

Next tactic:
constructor
theorem iff_of_arrow_iso_left {A B A' B' X Y : C} {i : A ⟶ B} {i' : A' ⟶ B'}
    (e : Arrow.mk i ≅ Arrow.mk i') (p : X ⟶ Y) :
    HasLiftingProperty i p ↔ HasLiftingProperty i' p := by
  constructor <;> 

Proof state:
case mp
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B'✝ X✝ Y✝ Y' : C
i✝ : A✝ ⟶ B✝
i'✝ : B✝ ⟶ B'✝
p✝ : X✝ ⟶ Y✝
p' : Y✝ ⟶ Y'
A B A' B' X Y : C
i : A ⟶ B
i' : A' ⟶ B'
e : Arrow.mk i ≅ Arrow.mk i'
p : X ⟶ Y
⊢ HasLiftingProperty i p → HasLiftingProperty i' p

Next tactic:
intro
theorem iff_of_arrow_iso_left {A B A' B' X Y : C} {i : A ⟶ B} {i' : A' ⟶ B'}
    (e : Arrow.mk i ≅ Arrow.mk i') (p : X ⟶ Y) :
    HasLiftingProperty i p ↔ HasLiftingProperty i' p := by
  constructor <;> 

Proof state:
case mpr
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B'✝ X✝ Y✝ Y' : C
i✝ : A✝ ⟶ B✝
i'✝ : B✝ ⟶ B'✝
p✝ : X✝ ⟶ Y✝
p' : Y✝ ⟶ Y'
A B A' B' X Y : C
i : A ⟶ B
i' : A' ⟶ B'
e : Arrow.mk i ≅ Arrow.mk i'
p : X ⟶ Y
⊢ HasLiftingProperty i' p → HasLiftingProperty i p

Next tactic:
intro
theorem iff_of_arrow_iso_left {A B A' B' X Y : C} {i : A ⟶ B} {i' : A' ⟶ B'}
    (e : Arrow.mk i ≅ Arrow.mk i') (p : X ⟶ Y) :
    HasLiftingProperty i p ↔ HasLiftingProperty i' p := by
  constructor <;> intro
  

Proof state:
case mp
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B'✝ X✝ Y✝ Y' : C
i✝ : A✝ ⟶ B✝
i'✝ : B✝ ⟶ B'✝
p✝ : X✝ ⟶ Y✝
p' : Y✝ ⟶ Y'
A B A' B' X Y : C
i : A ⟶ B
i' : A' ⟶ B'
e : Arrow.mk i ≅ Arrow.mk i'
p : X ⟶ Y
a✝ : HasLiftingProperty i p
⊢ HasLiftingProperty i' p
case mpr
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B'✝ X✝ Y✝ Y' : C
i✝ : A✝ ⟶ B✝
i'✝ : B✝ ⟶ B'✝
p✝ : X✝ ⟶ Y✝
p' : Y✝ ⟶ Y'
A B A' B' X Y : C
i : A ⟶ B
i' : A' ⟶ B'
e : Arrow.mk i ≅ Arrow.mk i'
p : X ⟶ Y
a✝ : HasLiftingProperty i' p
⊢ HasLiftingProperty i p

Next tactic:
exacts [of_arrow_iso_left e p, of_arrow_iso_left e.symm p]
theorem iff_of_arrow_iso_right {A B X Y X' Y' : C} (i : A ⟶ B) {p : X ⟶ Y} {p' : X' ⟶ Y'}
    (e : Arrow.mk p ≅ Arrow.mk p') : HasLiftingProperty i p ↔ HasLiftingProperty i p' := by
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B' X✝ Y✝ Y'✝ : C
i✝ : A✝ ⟶ B✝
i' : B✝ ⟶ B'
p✝ : X✝ ⟶ Y✝
p'✝ : Y✝ ⟶ Y'✝
A B X Y X' Y' : C
i : A ⟶ B
p : X ⟶ Y
p' : X' ⟶ Y'
e : Arrow.mk p ≅ Arrow.mk p'
⊢ HasLiftingProperty i p ↔ HasLiftingProperty i p'

Next tactic:
constructor
theorem iff_of_arrow_iso_right {A B X Y X' Y' : C} (i : A ⟶ B) {p : X ⟶ Y} {p' : X' ⟶ Y'}
    (e : Arrow.mk p ≅ Arrow.mk p') : HasLiftingProperty i p ↔ HasLiftingProperty i p' := by
  constructor <;> 

Proof state:
case mp
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B' X✝ Y✝ Y'✝ : C
i✝ : A✝ ⟶ B✝
i' : B✝ ⟶ B'
p✝ : X✝ ⟶ Y✝
p'✝ : Y✝ ⟶ Y'✝
A B X Y X' Y' : C
i : A ⟶ B
p : X ⟶ Y
p' : X' ⟶ Y'
e : Arrow.mk p ≅ Arrow.mk p'
⊢ HasLiftingProperty i p → HasLiftingProperty i p'

Next tactic:
intro
theorem iff_of_arrow_iso_right {A B X Y X' Y' : C} (i : A ⟶ B) {p : X ⟶ Y} {p' : X' ⟶ Y'}
    (e : Arrow.mk p ≅ Arrow.mk p') : HasLiftingProperty i p ↔ HasLiftingProperty i p' := by
  constructor <;> 

Proof state:
case mpr
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B' X✝ Y✝ Y'✝ : C
i✝ : A✝ ⟶ B✝
i' : B✝ ⟶ B'
p✝ : X✝ ⟶ Y✝
p'✝ : Y✝ ⟶ Y'✝
A B X Y X' Y' : C
i : A ⟶ B
p : X ⟶ Y
p' : X' ⟶ Y'
e : Arrow.mk p ≅ Arrow.mk p'
⊢ HasLiftingProperty i p' → HasLiftingProperty i p

Next tactic:
intro
theorem iff_of_arrow_iso_right {A B X Y X' Y' : C} (i : A ⟶ B) {p : X ⟶ Y} {p' : X' ⟶ Y'}
    (e : Arrow.mk p ≅ Arrow.mk p') : HasLiftingProperty i p ↔ HasLiftingProperty i p' := by
  constructor <;> intro
  

Proof state:
case mp
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B' X✝ Y✝ Y'✝ : C
i✝ : A✝ ⟶ B✝
i' : B✝ ⟶ B'
p✝ : X✝ ⟶ Y✝
p'✝ : Y✝ ⟶ Y'✝
A B X Y X' Y' : C
i : A ⟶ B
p : X ⟶ Y
p' : X' ⟶ Y'
e : Arrow.mk p ≅ Arrow.mk p'
a✝ : HasLiftingProperty i p
⊢ HasLiftingProperty i p'
case mpr
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A✝ B✝ B' X✝ Y✝ Y'✝ : C
i✝ : A✝ ⟶ B✝
i' : B✝ ⟶ B'
p✝ : X✝ ⟶ Y✝
p'✝ : Y✝ ⟶ Y'✝
A B X Y X' Y' : C
i : A ⟶ B
p : X ⟶ Y
p' : X' ⟶ Y'
e : Arrow.mk p ≅ Arrow.mk p'
a✝ : HasLiftingProperty i p'
⊢ HasLiftingProperty i p

Next tactic:
exacts [of_arrow_iso_right i e, of_arrow_iso_right i e.symm]
@[simp, norm_cast]
theorem coe_sub (h : q ≤ p) : ((p - q : ℚ≥0) : ℚ) = p - q :=
  max_eq_left <| le_sub_comm.2 <| by 

Proof state:
α : Type u_1
p q : ℚ≥0
h : q ≤ p
⊢ ↑q ≤ ↑p - 0

Next tactic:
rwa [sub_zero]
@[simp]
theorem coe_eq_zero : (q : ℚ) = 0 ↔ q = 0 := by 

Proof state:
α : Type u_1
p q : ℚ≥0
⊢ ↑q = 0 ↔ q = 0

Next tactic:
norm_cast