[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
x✝ : ℕ
n : ℕ := x✝
h : ¬n < E.order
k : Fin E.order
⊢ n - E.order + ↑k < n
[PROOFSTEP]
rw [add_comm, ← add_tsub_assoc_of_le (not_lt.mp h), tsub_lt_iff_left]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
x✝ : ℕ
n : ℕ := x✝
h : ¬n < E.order
k : Fin E.order
⊢ ↑k + n < E.order + n
[PROOFSTEP]
exact add_lt_add_right k.is_lt n
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
x✝ : ℕ
n : ℕ := x✝
h : ¬n < E.order
k : Fin E.order
⊢ E.order ≤ ↑k + n
[PROOFSTEP]
convert add_le_add (zero_le (k : ℕ)) (not_lt.mp h)
[GOAL]
case h.e'_3
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
x✝ : ℕ
n : ℕ := x✝
h : ¬n < E.order
k : Fin E.order
⊢ E.order = 0 + E.order
[PROOFSTEP]
simp only [zero_add]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
⊢ IsSolution E (mkSol E init)
[PROOFSTEP]
intro n
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
n : ℕ
⊢ mkSol E init (n + E.order) = ∑ i : Fin E.order, coeffs E i * mkSol E init (n + ↑i)
[PROOFSTEP]
rw [mkSol]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
n : ℕ
⊢ (if h : n + E.order < E.order then init { val := n + E.order, isLt := h }
    else
      ∑ k : Fin E.order,
        let_fun x := (_ : n + E.order - E.order + ↑k < n + E.order);
        coeffs E k * mkSol E init (n + E.order - E.order + ↑k)) =
    ∑ i : Fin E.order, coeffs E i * mkSol E init (n + ↑i)
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
⊢ ∀ (n : Fin E.order), mkSol E init ↑n = init n
[PROOFSTEP]
intro n
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
n : Fin E.order
⊢ mkSol E init ↑n = init n
[PROOFSTEP]
rw [mkSol]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
n : Fin E.order
⊢ (if h : ↑n < E.order then init { val := ↑n, isLt := h }
    else
      ∑ k : Fin E.order,
        let_fun x := (_ : ↑n - E.order + ↑k < ↑n);
        coeffs E k * mkSol E init (↑n - E.order + ↑k)) =
    init n
[PROOFSTEP]
simp only [n.is_lt, dif_pos, Fin.mk_val, Fin.eta]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
⊢ ∀ (n : ℕ), u n = mkSol E init n
[PROOFSTEP]
intro n
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
⊢ u n = mkSol E init n
[PROOFSTEP]
rw [mkSol]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
⊢ u n =
    if h : n < E.order then init { val := n, isLt := h }
    else
      ∑ k : Fin E.order,
        let_fun x := (_ : n - E.order + ↑k < n);
        coeffs E k * mkSol E init (n - E.order + ↑k)
[PROOFSTEP]
split_ifs with h'
[GOAL]
case pos
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : n < E.order
⊢ u n = init { val := n, isLt := h' }
[PROOFSTEP]
exact_mod_cast heq ⟨n, h'⟩
[GOAL]
case neg
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
⊢ u n =
    ∑ k : Fin E.order,
      let_fun x := (_ : n - E.order + ↑k < n);
      coeffs E k * mkSol E init (n - E.order + ↑k)
[PROOFSTEP]
simp only
[GOAL]
case neg
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
⊢ u n = ∑ x : Fin E.order, coeffs E x * mkSol E init (n - E.order + ↑x)
[PROOFSTEP]
rw [← tsub_add_cancel_of_le (le_of_not_lt h'), h (n - E.order)]
[GOAL]
case neg
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
⊢ ∑ i : Fin E.order, coeffs E i * u (n - E.order + ↑i) =
    ∑ x : Fin E.order, coeffs E x * mkSol E init (n - E.order + E.order - E.order + ↑x)
[PROOFSTEP]
congr with k
[GOAL]
case neg.e_f.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
⊢ coeffs E k * u (n - E.order + ↑k) = coeffs E k * mkSol E init (n - E.order + E.order - E.order + ↑k)
[PROOFSTEP]
have : n - E.order + k < n :=
  by
  rw [add_comm, ← add_tsub_assoc_of_le (not_lt.mp h'), tsub_lt_iff_left]
  · exact add_lt_add_right k.is_lt n
  · convert add_le_add (zero_le (k : ℕ)) (not_lt.mp h')
    simp only [zero_add]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
⊢ n - E.order + ↑k < n
[PROOFSTEP]
rw [add_comm, ← add_tsub_assoc_of_le (not_lt.mp h'), tsub_lt_iff_left]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
⊢ ↑k + n < E.order + n
[PROOFSTEP]
exact add_lt_add_right k.is_lt n
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
⊢ E.order ≤ ↑k + n
[PROOFSTEP]
convert add_le_add (zero_le (k : ℕ)) (not_lt.mp h')
[GOAL]
case h.e'_3
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
⊢ E.order = 0 + E.order
[PROOFSTEP]
simp only [zero_add]
[GOAL]
case neg.e_f.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
this : n - E.order + ↑k < n
⊢ coeffs E k * u (n - E.order + ↑k) = coeffs E k * mkSol E init (n - E.order + E.order - E.order + ↑k)
[PROOFSTEP]
rw [eq_mk_of_is_sol_of_eq_init h heq (n - E.order + k)]
[GOAL]
case neg.e_f.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
this : n - E.order + ↑k < n
⊢ coeffs E k * mkSol E (fun n => init n) (n - E.order + ↑k) =
    coeffs E k * mkSol E init (n - E.order + E.order - E.order + ↑k)
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : u ∈ {u | IsSolution E u}
hv : v ∈ {u | IsSolution E u}
n : ℕ
⊢ (u + v) (n + E.order) = ∑ i : Fin E.order, coeffs E i * (u + v) (n + ↑i)
[PROOFSTEP]
simp [mul_add, sum_add_distrib, hu n, hv n]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
n : ℕ
⊢ OfNat.ofNat 0 (n + E.order) = ∑ i : Fin E.order, coeffs E i * OfNat.ofNat 0 (n + ↑i)
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : ℕ → α
hu :
  u ∈
    {
          toAddSubsemigroup :=
            { carrier := {u | IsSolution E u},
              add_mem' :=
                (_ :
                  ∀ {u v : ℕ → α},
                    u ∈ {u | IsSolution E u} →
                      v ∈ {u | IsSolution E u} →
                        ∀ (n : ℕ),
                          u (n + E.order) + v (n + E.order) = ∑ i : Fin E.order, coeffs E i * (u + v) (n + ↑i)) },
          zero_mem' :=
            (_ : ∀ (n : ℕ), 0 = ∑ i : Fin E.order, coeffs E i * OfNat.ofNat 0 (n + ↑i)) }.toAddSubsemigroup.carrier
n : ℕ
⊢ (a • u) (n + E.order) = ∑ i : Fin E.order, coeffs E i * (a • u) (n + ↑i)
[PROOFSTEP]
simp [hu n, mul_sum]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : ℕ → α
hu :
  u ∈
    {
          toAddSubsemigroup :=
            { carrier := {u | IsSolution E u},
              add_mem' :=
                (_ :
                  ∀ {u v : ℕ → α},
                    u ∈ {u | IsSolution E u} →
                      v ∈ {u | IsSolution E u} →
                        ∀ (n : ℕ),
                          u (n + E.order) + v (n + E.order) = ∑ i : Fin E.order, coeffs E i * (u + v) (n + ↑i)) },
          zero_mem' :=
            (_ : ∀ (n : ℕ), 0 = ∑ i : Fin E.order, coeffs E i * OfNat.ofNat 0 (n + ↑i)) }.toAddSubsemigroup.carrier
n : ℕ
⊢ ∑ x : Fin E.order, a * (coeffs E x * u (n + ↑x)) = ∑ x : Fin E.order, coeffs E x * (a * u (n + ↑x))
[PROOFSTEP]
congr
[GOAL]
case e_f
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : ℕ → α
hu :
  u ∈
    {
          toAddSubsemigroup :=
            { carrier := {u | IsSolution E u},
              add_mem' :=
                (_ :
                  ∀ {u v : ℕ → α},
                    u ∈ {u | IsSolution E u} →
                      v ∈ {u | IsSolution E u} →
                        ∀ (n : ℕ),
                          u (n + E.order) + v (n + E.order) = ∑ i : Fin E.order, coeffs E i * (u + v) (n + ↑i)) },
          zero_mem' :=
            (_ : ∀ (n : ℕ), 0 = ∑ i : Fin E.order, coeffs E i * OfNat.ofNat 0 (n + ↑i)) }.toAddSubsemigroup.carrier
n : ℕ
⊢ (fun x => a * (coeffs E x * u (n + ↑x))) = fun x => coeffs E x * (a * u (n + ↑x))
[PROOFSTEP]
ext
[GOAL]
case e_f.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : ℕ → α
hu :
  u ∈
    {
          toAddSubsemigroup :=
            { carrier := {u | IsSolution E u},
              add_mem' :=
                (_ :
                  ∀ {u v : ℕ → α},
                    u ∈ {u | IsSolution E u} →
                      v ∈ {u | IsSolution E u} →
                        ∀ (n : ℕ),
                          u (n + E.order) + v (n + E.order) = ∑ i : Fin E.order, coeffs E i * (u + v) (n + ↑i)) },
          zero_mem' :=
            (_ : ∀ (n : ℕ), 0 = ∑ i : Fin E.order, coeffs E i * OfNat.ofNat 0 (n + ↑i)) }.toAddSubsemigroup.carrier
n : ℕ
x✝ : Fin E.order
⊢ a * (coeffs E x✝ * u (n + ↑x✝)) = coeffs E x✝ * (a * u (n + ↑x✝))
[PROOFSTEP]
ac_rfl
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : { x // x ∈ solSpace E }
⊢ (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v
[PROOFSTEP]
ext
[GOAL]
case h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : { x // x ∈ solSpace E }
x✝ : Fin E.order
⊢ (fun u x => ↑u ↑x) (u + v) x✝ = ((fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) x✝
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : { x // x ∈ solSpace E }
⊢ AddHom.toFun
      { toFun := fun u x => ↑u ↑x,
        map_add' :=
          (_ :
            ∀ (u v : { x // x ∈ solSpace E }),
              (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
      (a • u) =
    ↑(RingHom.id α) a •
      AddHom.toFun
        { toFun := fun u x => ↑u ↑x,
          map_add' :=
            (_ :
              ∀ (u v : { x // x ∈ solSpace E }),
                (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
        u
[PROOFSTEP]
ext
[GOAL]
case h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : { x // x ∈ solSpace E }
x✝ : Fin E.order
⊢ AddHom.toFun
      { toFun := fun u x => ↑u ↑x,
        map_add' :=
          (_ :
            ∀ (u v : { x // x ∈ solSpace E }),
              (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
      (a • u) x✝ =
    (↑(RingHom.id α) a •
        AddHom.toFun
          { toFun := fun u x => ↑u ↑x,
            map_add' :=
              (_ :
                ∀ (u v : { x // x ∈ solSpace E }),
                  (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
          u)
      x✝
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : { x // x ∈ solSpace E }
⊢ (fun u => { val := mkSol E u, property := (_ : IsSolution E (mkSol E u)) })
      (AddHom.toFun
        {
            toAddHom :=
              { toFun := fun u x => ↑u ↑x,
                map_add' :=
                  (_ :
                    ∀ (u v : { x // x ∈ solSpace E }),
                      (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) },
            map_smul' :=
              (_ :
                ∀ (a : α) (u : { x // x ∈ solSpace E }),
                  AddHom.toFun
                      { toFun := fun u x => ↑u ↑x,
                        map_add' :=
                          (_ :
                            ∀ (u v : { x // x ∈ solSpace E }),
                              (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                      (a • u) =
                    ↑(RingHom.id α) a •
                      AddHom.toFun
                        { toFun := fun u x => ↑u ↑x,
                          map_add' :=
                            (_ :
                              ∀ (u v : { x // x ∈ solSpace E }),
                                (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                        u) }.toAddHom
        u) =
    u
[PROOFSTEP]
ext n
[GOAL]
case a.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : { x // x ∈ solSpace E }
n : ℕ
⊢ ↑((fun u => { val := mkSol E u, property := (_ : IsSolution E (mkSol E u)) })
          (AddHom.toFun
            {
                toAddHom :=
                  { toFun := fun u x => ↑u ↑x,
                    map_add' :=
                      (_ :
                        ∀ (u v : { x // x ∈ solSpace E }),
                          (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) },
                map_smul' :=
                  (_ :
                    ∀ (a : α) (u : { x // x ∈ solSpace E }),
                      AddHom.toFun
                          { toFun := fun u x => ↑u ↑x,
                            map_add' :=
                              (_ :
                                ∀ (u v : { x // x ∈ solSpace E }),
                                  (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                          (a • u) =
                        ↑(RingHom.id α) a •
                          AddHom.toFun
                            { toFun := fun u x => ↑u ↑x,
                              map_add' :=
                                (_ :
                                  ∀ (u v : { x // x ∈ solSpace E }),
                                    (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                            u) }.toAddHom
            u))
      n =
    ↑u n
[PROOFSTEP]
symm
[GOAL]
case a.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : { x // x ∈ solSpace E }
n : ℕ
⊢ ↑u n =
    ↑((fun u => { val := mkSol E u, property := (_ : IsSolution E (mkSol E u)) })
          (AddHom.toFun
            {
                toAddHom :=
                  { toFun := fun u x => ↑u ↑x,
                    map_add' :=
                      (_ :
                        ∀ (u v : { x // x ∈ solSpace E }),
                          (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) },
                map_smul' :=
                  (_ :
                    ∀ (a : α) (u : { x // x ∈ solSpace E }),
                      AddHom.toFun
                          { toFun := fun u x => ↑u ↑x,
                            map_add' :=
                              (_ :
                                ∀ (u v : { x // x ∈ solSpace E }),
                                  (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                          (a • u) =
                        ↑(RingHom.id α) a •
                          AddHom.toFun
                            { toFun := fun u x => ↑u ↑x,
                              map_add' :=
                                (_ :
                                  ∀ (u v : { x // x ∈ solSpace E }),
                                    (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                            u) }.toAddHom
            u))
      n
[PROOFSTEP]
apply E.eq_mk_of_is_sol_of_eq_init u.2
[GOAL]
case a.h.heq
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : { x // x ∈ solSpace E }
n : ℕ
⊢ ∀ (n : Fin E.order),
    ↑u ↑n =
      AddHom.toFun
        {
            toAddHom :=
              { toFun := fun u x => ↑u ↑x,
                map_add' :=
                  (_ :
                    ∀ (u v : { x // x ∈ solSpace E }),
                      (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) },
            map_smul' :=
              (_ :
                ∀ (a : α) (u : { x // x ∈ solSpace E }),
                  AddHom.toFun
                      { toFun := fun u x => ↑u ↑x,
                        map_add' :=
                          (_ :
                            ∀ (u v : { x // x ∈ solSpace E }),
                              (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                      (a • u) =
                    ↑(RingHom.id α) a •
                      AddHom.toFun
                        { toFun := fun u x => ↑u ↑x,
                          map_add' :=
                            (_ :
                              ∀ (u v : { x // x ∈ solSpace E }),
                                (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                        u) }.toAddHom
        u n
[PROOFSTEP]
intro k
[GOAL]
case a.h.heq
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : { x // x ∈ solSpace E }
n : ℕ
k : Fin E.order
⊢ ↑u ↑k =
    AddHom.toFun
      {
          toAddHom :=
            { toFun := fun u x => ↑u ↑x,
              map_add' :=
                (_ :
                  ∀ (u v : { x // x ∈ solSpace E }),
                    (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) },
          map_smul' :=
            (_ :
              ∀ (a : α) (u : { x // x ∈ solSpace E }),
                AddHom.toFun
                    { toFun := fun u x => ↑u ↑x,
                      map_add' :=
                        (_ :
                          ∀ (u v : { x // x ∈ solSpace E }),
                            (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                    (a • u) =
                  ↑(RingHom.id α) a •
                    AddHom.toFun
                      { toFun := fun u x => ↑u ↑x,
                        map_add' :=
                          (_ :
                            ∀ (u v : { x // x ∈ solSpace E }),
                              (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                      u) }.toAddHom
      u k
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
⊢ u = v ↔ Set.EqOn u v ↑(range E.order)
[PROOFSTEP]
refine' Iff.intro (fun h x _ ↦ h ▸ rfl) _
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
⊢ Set.EqOn u v ↑(range E.order) → u = v
[PROOFSTEP]
intro h
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
h : Set.EqOn u v ↑(range E.order)
⊢ u = v
[PROOFSTEP]
set u' : ↥E.solSpace := ⟨u, hu⟩
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
h : Set.EqOn u v ↑(range E.order)
u' : { x // x ∈ solSpace E } := { val := u, property := hu }
⊢ u = v
[PROOFSTEP]
set v' : ↥E.solSpace := ⟨v, hv⟩
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
h : Set.EqOn u v ↑(range E.order)
u' : { x // x ∈ solSpace E } := { val := u, property := hu }
v' : { x // x ∈ solSpace E } := { val := v, property := hv }
⊢ u = v
[PROOFSTEP]
change u'.val = v'.val
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
h : Set.EqOn u v ↑(range E.order)
u' : { x // x ∈ solSpace E } := { val := u, property := hu }
v' : { x // x ∈ solSpace E } := { val := v, property := hv }
⊢ ↑u' = ↑v'
[PROOFSTEP]
suffices h' : u' = v'
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
h : Set.EqOn u v ↑(range E.order)
u' : { x // x ∈ solSpace E } := { val := u, property := hu }
v' : { x // x ∈ solSpace E } := { val := v, property := hv }
h' : u' = v'
⊢ ↑u' = ↑v'
case h'
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
h : Set.EqOn u v ↑(range E.order)
u' : { x // x ∈ solSpace E } := { val := u, property := hu }
v' : { x // x ∈ solSpace E } := { val := v, property := hv }
⊢ u' = v'
[PROOFSTEP]
exact h' ▸ rfl
[GOAL]
case h'
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
h : Set.EqOn u v ↑(range E.order)
u' : { x // x ∈ solSpace E } := { val := u, property := hu }
v' : { x // x ∈ solSpace E } := { val := v, property := hv }
⊢ u' = v'
[PROOFSTEP]
rw [← E.toInit.toEquiv.apply_eq_iff_eq, LinearEquiv.coe_toEquiv]
[GOAL]
case h'
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
h : Set.EqOn u v ↑(range E.order)
u' : { x // x ∈ solSpace E } := { val := u, property := hu }
v' : { x // x ∈ solSpace E } := { val := v, property := hv }
⊢ ↑(toInit E) u' = ↑(toInit E) v'
[PROOFSTEP]
ext x
[GOAL]
case h'.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : IsSolution E u
hv : IsSolution E v
h : Set.EqOn u v ↑(range E.order)
u' : { x // x ∈ solSpace E } := { val := u, property := hu }
v' : { x // x ∈ solSpace E } := { val := v, property := hv }
x : Fin E.order
⊢ ↑(toInit E) u' x = ↑(toInit E) v' x
[PROOFSTEP]
exact_mod_cast h (mem_range.mpr x.2)
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x y : Fin E.order → α
⊢ (fun X i => if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * X i)
      (x + y) =
    (fun X i => if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * X i)
        x +
      (fun X i => if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * X i)
        y
[PROOFSTEP]
ext i
[GOAL]
case h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x y : Fin E.order → α
i : Fin E.order
⊢ (fun X i => if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * X i)
      (x + y) i =
    ((fun X i => if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * X i)
          x +
        (fun X i =>
            if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * X i)
          y)
      i
[PROOFSTEP]
simp only
[GOAL]
case h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x y : Fin E.order → α
i : Fin E.order
⊢ (if h : ↑i + 1 < E.order then (x + y) { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * (x + y) i) =
    ((fun i => if h : ↑i + 1 < E.order then x { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * x i) +
        fun i => if h : ↑i + 1 < E.order then y { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * y i)
      i
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x y : Fin E.order → α
i : Fin E.order
h : ↑i + 1 < E.order
⊢ (x + y) { val := ↑i + 1, isLt := h } =
    ((fun i => if h : ↑i + 1 < E.order then x { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * x i) +
        fun i => if h : ↑i + 1 < E.order then y { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * y i)
      i
[PROOFSTEP]
simp [h, mul_add, sum_add_distrib]
[GOAL]
case neg
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x y : Fin E.order → α
i : Fin E.order
h : ¬↑i + 1 < E.order
⊢ ∑ i : Fin E.order, coeffs E i * (x + y) i =
    ((fun i => if h : ↑i + 1 < E.order then x { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * x i) +
        fun i => if h : ↑i + 1 < E.order then y { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * y i)
      i
[PROOFSTEP]
simp [h, mul_add, sum_add_distrib]
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x : α
y : Fin E.order → α
⊢ AddHom.toFun
      {
        toFun := fun X i =>
          if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * X i,
        map_add' :=
          (_ :
            ∀ (x y : Fin E.order → α),
              (fun X i =>
                    if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                    else ∑ i : Fin E.order, coeffs E i * X i)
                  (x + y) =
                (fun X i =>
                      if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                      else ∑ i : Fin E.order, coeffs E i * X i)
                    x +
                  (fun X i =>
                      if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                      else ∑ i : Fin E.order, coeffs E i * X i)
                    y) }
      (x • y) =
    ↑(RingHom.id α) x •
      AddHom.toFun
        {
          toFun := fun X i =>
            if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * X i,
          map_add' :=
            (_ :
              ∀ (x y : Fin E.order → α),
                (fun X i =>
                      if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                      else ∑ i : Fin E.order, coeffs E i * X i)
                    (x + y) =
                  (fun X i =>
                        if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                        else ∑ i : Fin E.order, coeffs E i * X i)
                      x +
                    (fun X i =>
                        if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                        else ∑ i : Fin E.order, coeffs E i * X i)
                      y) }
        y
[PROOFSTEP]
ext i
[GOAL]
case h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x : α
y : Fin E.order → α
i : Fin E.order
⊢ AddHom.toFun
      {
        toFun := fun X i =>
          if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * X i,
        map_add' :=
          (_ :
            ∀ (x y : Fin E.order → α),
              (fun X i =>
                    if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                    else ∑ i : Fin E.order, coeffs E i * X i)
                  (x + y) =
                (fun X i =>
                      if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                      else ∑ i : Fin E.order, coeffs E i * X i)
                    x +
                  (fun X i =>
                      if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                      else ∑ i : Fin E.order, coeffs E i * X i)
                    y) }
      (x • y) i =
    (↑(RingHom.id α) x •
        AddHom.toFun
          {
            toFun := fun X i =>
              if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * X i,
            map_add' :=
              (_ :
                ∀ (x y : Fin E.order → α),
                  (fun X i =>
                        if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                        else ∑ i : Fin E.order, coeffs E i * X i)
                      (x + y) =
                    (fun X i =>
                          if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                          else ∑ i : Fin E.order, coeffs E i * X i)
                        x +
                      (fun X i =>
                          if h : ↑i + 1 < E.order then X { val := ↑i + 1, isLt := h }
                          else ∑ i : Fin E.order, coeffs E i * X i)
                        y) }
          y)
      i
[PROOFSTEP]
simp only
[GOAL]
case h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x : α
y : Fin E.order → α
i : Fin E.order
⊢ (if h : ↑i + 1 < E.order then (x • y) { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * (x • y) i) =
    (↑(RingHom.id α) x • fun i =>
        if h : ↑i + 1 < E.order then y { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * y i)
      i
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x : α
y : Fin E.order → α
i : Fin E.order
h : ↑i + 1 < E.order
⊢ (x • y) { val := ↑i + 1, isLt := h } =
    (↑(RingHom.id α) x • fun i =>
        if h : ↑i + 1 < E.order then y { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * y i)
      i
[PROOFSTEP]
simp [h, mul_sum]
[GOAL]
case neg
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x : α
y : Fin E.order → α
i : Fin E.order
h : ¬↑i + 1 < E.order
⊢ ∑ i : Fin E.order, coeffs E i * (x • y) i =
    (↑(RingHom.id α) x • fun i =>
        if h : ↑i + 1 < E.order then y { val := ↑i + 1, isLt := h } else ∑ i : Fin E.order, coeffs E i * y i)
      i
[PROOFSTEP]
simp [h, mul_sum]
[GOAL]
case neg
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x : α
y : Fin E.order → α
i : Fin E.order
h : ¬↑i + 1 < E.order
⊢ ∑ x_1 : Fin E.order, coeffs E x_1 * (x * y x_1) = ∑ x_1 : Fin E.order, x * (coeffs E x_1 * y x_1)
[PROOFSTEP]
exact sum_congr rfl fun x _ ↦ by ac_rfl
[GOAL]
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
x✝¹ : α
y : Fin E.order → α
i : Fin E.order
h : ¬↑i + 1 < E.order
x : Fin E.order
x✝ : x ∈ univ
⊢ coeffs E x * (x✝¹ * y x) = x✝¹ * (coeffs E x * y x)
[PROOFSTEP]
ac_rfl
[GOAL]
α : Type u_1
inst✝ : CommRing α
E : LinearRecurrence α
q : α
⊢ (IsSolution E fun n => q ^ n) ↔ IsRoot (charPoly E) q
[PROOFSTEP]
rw [charPoly, Polynomial.IsRoot.def, Polynomial.eval]
[GOAL]
α : Type u_1
inst✝ : CommRing α
E : LinearRecurrence α
q : α
⊢ (IsSolution E fun n => q ^ n) ↔
    eval₂ (RingHom.id α) q (↑(monomial E.order) 1 - ∑ i : Fin E.order, ↑(monomial ↑i) (coeffs E i)) = 0
[PROOFSTEP]
simp only [Polynomial.eval₂_finset_sum, one_mul, RingHom.id_apply, Polynomial.eval₂_monomial, Polynomial.eval₂_sub]
[GOAL]
α : Type u_1
inst✝ : CommRing α
E : LinearRecurrence α
q : α
⊢ (IsSolution E fun n => q ^ n) ↔ q ^ E.order - ∑ x : Fin E.order, coeffs E x * q ^ ↑x = 0
[PROOFSTEP]
constructor
[GOAL]
case mp
α : Type u_1
inst✝ : CommRing α
E : LinearRecurrence α
q : α
⊢ (IsSolution E fun n => q ^ n) → q ^ E.order - ∑ x : Fin E.order, coeffs E x * q ^ ↑x = 0
[PROOFSTEP]
intro h
[GOAL]
case mp
α : Type u_1
inst✝ : CommRing α
E : LinearRecurrence α
q : α
h : IsSolution E fun n => q ^ n
⊢ q ^ E.order - ∑ x : Fin E.order, coeffs E x * q ^ ↑x = 0
[PROOFSTEP]
simpa [sub_eq_zero] using h 0
[GOAL]
case mpr
α : Type u_1
inst✝ : CommRing α
E : LinearRecurrence α
q : α
⊢ q ^ E.order - ∑ x : Fin E.order, coeffs E x * q ^ ↑x = 0 → IsSolution E fun n => q ^ n
[PROOFSTEP]
intro h n
[GOAL]
case mpr
α : Type u_1
inst✝ : CommRing α
E : LinearRecurrence α
q : α
h : q ^ E.order - ∑ x : Fin E.order, coeffs E x * q ^ ↑x = 0
n : ℕ
⊢ (fun n => q ^ n) (n + E.order) = ∑ i : Fin E.order, coeffs E i * (fun n => q ^ n) (n + ↑i)
[PROOFSTEP]
simp only [pow_add, sub_eq_zero.mp h, mul_sum]
[GOAL]
case mpr
α : Type u_1
inst✝ : CommRing α
E : LinearRecurrence α
q : α
h : q ^ E.order - ∑ x : Fin E.order, coeffs E x * q ^ ↑x = 0
n : ℕ
⊢ ∑ x : Fin E.order, q ^ n * (coeffs E x * q ^ ↑x) = ∑ x : Fin E.order, coeffs E x * (q ^ n * q ^ ↑x)
[PROOFSTEP]
exact sum_congr rfl fun _ _ ↦ by ring
[GOAL]
α : Type u_1
inst✝ : CommRing α
E : LinearRecurrence α
q : α
h : q ^ E.order - ∑ x : Fin E.order, coeffs E x * q ^ ↑x = 0
n : ℕ
x✝¹ : Fin E.order
x✝ : x✝¹ ∈ univ
⊢ q ^ n * (coeffs E x✝¹ * q ^ ↑x✝¹) = coeffs E x✝¹ * (q ^ n * q ^ ↑x✝¹)
[PROOFSTEP]
ring


[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
x y : TruncatedWittVector p n R
h : x = y
i : Fin n
⊢ coeff i x = coeff i y
[PROOFSTEP]
rw [h]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
x : TruncatedWittVector p n R
⊢ (mk p fun i => coeff i x) = x
[PROOFSTEP]
ext i
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
x : TruncatedWittVector p n R
i : Fin n
⊢ coeff i (mk p fun i => coeff i x) = coeff i x
[PROOFSTEP]
rw [coeff_mk]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : TruncatedWittVector p n R
i : Fin n
⊢ WittVector.coeff (out x) ↑i = coeff i x
[PROOFSTEP]
rw [out]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : TruncatedWittVector p n R
i : Fin n
⊢ WittVector.coeff { coeff := fun i => if h : i < n then coeff { val := i, isLt := h } x else 0 } ↑i = coeff i x
[PROOFSTEP]
dsimp only
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : TruncatedWittVector p n R
i : Fin n
⊢ (if h : ↑i < n then coeff { val := ↑i, isLt := h } x else 0) = coeff i x
[PROOFSTEP]
rw [dif_pos i.is_lt, Fin.eta]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
⊢ Injective out
[PROOFSTEP]
intro x y h
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x y : TruncatedWittVector p n R
h : out x = out y
⊢ x = y
[PROOFSTEP]
ext i
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x y : TruncatedWittVector p n R
h : out x = out y
i : Fin n
⊢ coeff i x = coeff i y
[PROOFSTEP]
rw [WittVector.ext_iff] at h
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x y : TruncatedWittVector p n R
h : ∀ (n_1 : ℕ), WittVector.coeff (out x) n_1 = WittVector.coeff (out y) n_1
i : Fin n
⊢ coeff i x = coeff i y
[PROOFSTEP]
simpa only [coeff_out] using h ↑i
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
x : 𝕎 R
i : Fin n
⊢ TruncatedWittVector.coeff i (truncateFun n x) = coeff x ↑i
[PROOFSTEP]
rw [truncateFun, TruncatedWittVector.coeff_mk]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
⊢ TruncatedWittVector.out (truncateFun n x) = init n x
[PROOFSTEP]
ext i
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
i : ℕ
⊢ coeff (TruncatedWittVector.out (truncateFun n x)) i = coeff (init n x) i
[PROOFSTEP]
dsimp [TruncatedWittVector.out, init, select, coeff_mk]
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
i : ℕ
⊢ (if h : i < n then TruncatedWittVector.coeff { val := i, isLt := h } (truncateFun n x) else 0) =
    if i < n then coeff x i else 0
[PROOFSTEP]
split_ifs with hi
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
i : ℕ
hi : i < n
⊢ TruncatedWittVector.coeff { val := i, isLt := hi } (truncateFun n x) = coeff x i
case neg p : ℕ hp : Fact (Nat.Prime p) n : ℕ R : Type u_1 inst✝ : CommRing R x : 𝕎 R i : ℕ hi : ¬i < n ⊢ 0 = 0
[PROOFSTEP]
swap
[GOAL]
case neg
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
i : ℕ
hi : ¬i < n
⊢ 0 = 0
[PROOFSTEP]
rfl
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
i : ℕ
hi : i < n
⊢ TruncatedWittVector.coeff { val := i, isLt := hi } (truncateFun n x) = coeff x i
[PROOFSTEP]
rw [coeff_truncateFun, Fin.val_mk]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : TruncatedWittVector p n R
⊢ WittVector.truncateFun n (out x) = x
[PROOFSTEP]
simp only [WittVector.truncateFun, coeff_out, mk_coeff]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
i : Fin n
⊢ coeff i 0 = 0
[PROOFSTEP]
show coeff i (truncateFun _ 0 : TruncatedWittVector p n R) = 0
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
i : Fin n
⊢ coeff i (truncateFun n 0) = 0
[PROOFSTEP]
rw [coeff_truncateFun, WittVector.zero_coeff]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x y : 𝕎 R
⊢ truncateFun n (x + y) = truncateFun n x + truncateFun n y
[PROOFSTEP]
witt_truncateFun_tac
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x y : 𝕎 R
⊢ truncateFun n (x * y) = truncateFun n x * truncateFun n y
[PROOFSTEP]
witt_truncateFun_tac
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
⊢ truncateFun n (-x) = -truncateFun n x
[PROOFSTEP]
witt_truncateFun_tac
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x y : 𝕎 R
⊢ truncateFun n (x - y) = truncateFun n x - truncateFun n y
[PROOFSTEP]
witt_truncateFun_tac
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
m : ℕ
⊢ truncateFun n (m • x) = m • truncateFun n x
[PROOFSTEP]
witt_truncateFun_tac
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
m : ℤ
⊢ truncateFun n (m • x) = m • truncateFun n x
[PROOFSTEP]
witt_truncateFun_tac
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
m : ℕ
⊢ truncateFun n (x ^ m) = truncateFun n x ^ m
[PROOFSTEP]
witt_truncateFun_tac
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
⊢ x ∈ RingHom.ker (truncate n) ↔ ∀ (i : ℕ), i < n → coeff x i = 0
[PROOFSTEP]
simp only [RingHom.mem_ker, truncate, truncateFun, RingHom.coe_mk, TruncatedWittVector.ext_iff,
  TruncatedWittVector.coeff_mk, coeff_zero]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
⊢ (∀ (i : Fin n),
      TruncatedWittVector.coeff i
          (↑{ toOneHom := { toFun := truncateFun n, map_one' := (_ : truncateFun n 1 = 1) },
                map_mul' := (_ : ∀ (x y : 𝕎 R), truncateFun n (x * y) = truncateFun n x * truncateFun n y) }
            x) =
        0) ↔
    ∀ (i : ℕ), i < n → coeff x i = 0
[PROOFSTEP]
exact Fin.forall_iff
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
f : ℕ → R
⊢ ↑(truncate n) { coeff := f } = TruncatedWittVector.mk p fun k => f ↑k
[PROOFSTEP]
ext i
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
f : ℕ → R
i : Fin n
⊢ TruncatedWittVector.coeff i (↑(truncate n) { coeff := f }) =
    TruncatedWittVector.coeff i (TruncatedWittVector.mk p fun k => f ↑k)
[PROOFSTEP]
simp only [coeff_truncate, TruncatedWittVector.coeff_mk]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
hm : n ≤ m
⊢ RingHom.ker (WittVector.truncate m) ≤ RingHom.ker (WittVector.truncate n)
[PROOFSTEP]
intro x
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
hm : n ≤ m
x : 𝕎 R
⊢ x ∈ RingHom.ker (WittVector.truncate m) → x ∈ RingHom.ker (WittVector.truncate n)
[PROOFSTEP]
simp only [WittVector.mem_ker_truncate]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
hm : n ≤ m
x : 𝕎 R
⊢ (∀ (i : ℕ), i < m → WittVector.coeff x i = 0) → ∀ (i : ℕ), i < n → WittVector.coeff x i = 0
[PROOFSTEP]
intro h i hi
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
hm : n ≤ m
x : 𝕎 R
h : ∀ (i : ℕ), i < m → WittVector.coeff x i = 0
i : ℕ
hi : i < n
⊢ WittVector.coeff x i = 0
[PROOFSTEP]
exact h i (lt_of_lt_of_le hi hm)
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
n₁ n₂ n₃ : ℕ
h1 : n₁ ≤ n₂
h2 : n₂ ≤ n₃
x : TruncatedWittVector p n₃ R
⊢ ↑(truncate h1) (↑(truncate h2) x) = ↑(truncate (_ : n₁ ≤ n₃)) x
[PROOFSTEP]
obtain ⟨x, rfl⟩ := @WittVector.truncate_surjective p _ n₃ R _ x
[GOAL]
case intro
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
n₁ n₂ n₃ : ℕ
h1 : n₁ ≤ n₂
h2 : n₂ ≤ n₃
x : 𝕎 R
⊢ ↑(truncate h1) (↑(truncate h2) (↑(WittVector.truncate n₃) x)) =
    ↑(truncate (_ : n₁ ≤ n₃)) (↑(WittVector.truncate n₃) x)
[PROOFSTEP]
simp only [truncate_wittVector_truncate]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
n₁ n₂ n₃ : ℕ
h1 : n₁ ≤ n₂
h2 : n₂ ≤ n₃
⊢ RingHom.comp (truncate h1) (truncate h2) = truncate (_ : n₁ ≤ n₃)
[PROOFSTEP]
ext1 x
[GOAL]
case a
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
n₁ n₂ n₃ : ℕ
h1 : n₁ ≤ n₂
h2 : n₂ ≤ n₃
x : TruncatedWittVector p n₃ R
⊢ ↑(RingHom.comp (truncate h1) (truncate h2)) x = ↑(truncate (_ : n₁ ≤ n₃)) x
[PROOFSTEP]
simp only [truncate_truncate, Function.comp_apply, RingHom.coe_comp]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
hm : n ≤ m
⊢ Surjective ↑(truncate hm)
[PROOFSTEP]
intro x
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
hm : n ≤ m
x : TruncatedWittVector p n R
⊢ ∃ a, ↑(truncate hm) a = x
[PROOFSTEP]
obtain ⟨x, rfl⟩ := @WittVector.truncate_surjective p _ _ R _ x
[GOAL]
case intro
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
hm : n ≤ m
x : 𝕎 R
⊢ ∃ a, ↑(truncate hm) a = ↑(WittVector.truncate n) x
[PROOFSTEP]
exact ⟨WittVector.truncate _ x, truncate_wittVector_truncate _ _⟩
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
hm : n ≤ m
i : Fin n
x : TruncatedWittVector p m R
⊢ coeff i (↑(truncate hm) x) = coeff (Fin.castLE hm i) x
[PROOFSTEP]
obtain ⟨y, rfl⟩ := @WittVector.truncate_surjective p _ _ _ _ x
[GOAL]
case intro
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
hm : n ≤ m
i : Fin n
y : 𝕎 R
⊢ coeff i (↑(truncate hm) (↑(WittVector.truncate m) y)) = coeff (Fin.castLE hm i) (↑(WittVector.truncate m) y)
[PROOFSTEP]
simp only [truncate_wittVector_truncate, WittVector.coeff_truncate, Fin.coe_castLE]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R✝ : Type u_1
inst✝¹ : CommRing R✝
R : Type u_2
inst✝ : Fintype R
⊢ Fintype.card (TruncatedWittVector p n R) = Fintype.card R ^ n
[PROOFSTEP]
simp only [TruncatedWittVector, Fintype.card_fin, Fintype.card_fun]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
⊢ ⨅ (i : ℕ), RingHom.ker (WittVector.truncate i) = ⊥
[PROOFSTEP]
rw [Submodule.eq_bot_iff]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
⊢ ∀ (x : 𝕎 R), x ∈ ⨅ (i : ℕ), RingHom.ker (WittVector.truncate i) → x = 0
[PROOFSTEP]
intro x hx
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
hx : x ∈ ⨅ (i : ℕ), RingHom.ker (WittVector.truncate i)
⊢ x = 0
[PROOFSTEP]
ext
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
hx : x ∈ ⨅ (i : ℕ), RingHom.ker (WittVector.truncate i)
n✝ : ℕ
⊢ WittVector.coeff x n✝ = WittVector.coeff 0 n✝
[PROOFSTEP]
simp only [WittVector.mem_ker_truncate, Ideal.mem_iInf, WittVector.zero_coeff] at hx ⊢
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
n✝ : ℕ
hx : ∀ (i i_1 : ℕ), i_1 < i → WittVector.coeff x i_1 = 0
⊢ WittVector.coeff x n✝ = 0
[PROOFSTEP]
exact hx _ _ (Nat.lt_succ_self _)
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
s : S
⊢ ↑(truncate n) (liftFun f s) = ↑(f n) s
[PROOFSTEP]
ext i
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
s : S
i : Fin n
⊢ TruncatedWittVector.coeff i (↑(truncate n) (liftFun f s)) = TruncatedWittVector.coeff i (↑(f n) s)
[PROOFSTEP]
simp only [liftFun, TruncatedWittVector.coeff_mk, WittVector.truncate_mk']
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
s : S
i : Fin n
⊢ TruncatedWittVector.coeff (Fin.last ↑i) (↑(f (↑i + 1)) s) = TruncatedWittVector.coeff i (↑(f n) s)
[PROOFSTEP]
rw [← f_compat (i + 1) n i.is_lt, RingHom.comp_apply, TruncatedWittVector.coeff_truncate]
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
s : S
i : Fin n
⊢ TruncatedWittVector.coeff (Fin.castLE (_ : ↑i < n) (Fin.last ↑i)) (↑(f n) s) = TruncatedWittVector.coeff i (↑(f n) s)
[PROOFSTEP]
congr 1 with _
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ S →+* 𝕎 R
[PROOFSTEP]
refine'
  { toFun := liftFun f
    map_zero' := _
    map_one' := _
    map_add' := _
    map_mul' := _ }
[GOAL]
case refine'_1
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ liftFun f 1 = 1
[PROOFSTEP]
intros
[GOAL]
case refine'_1
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ liftFun f 1 = 1
[PROOFSTEP]
dsimp only
[GOAL]
case refine'_1
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ liftFun f 1 = 1
[PROOFSTEP]
rw [← sub_eq_zero, ← Ideal.mem_bot, ← iInf_ker_truncate, Ideal.mem_iInf]
[GOAL]
case refine'_1
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ ∀ (i : ℕ), liftFun f 1 - 1 ∈ RingHom.ker (truncate i)
[PROOFSTEP]
simp [RingHom.mem_ker, f_compat]
[GOAL]
case refine'_2
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ ∀ (x y : S),
    OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } (x * y) =
      OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } x *
        OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } y
[PROOFSTEP]
intros
[GOAL]
case refine'_2
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
x✝ y✝ : S
⊢ OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } (x✝ * y✝) =
    OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } x✝ *
      OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } y✝
[PROOFSTEP]
dsimp only
[GOAL]
case refine'_2
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
x✝ y✝ : S
⊢ liftFun f (x✝ * y✝) = liftFun f x✝ * liftFun f y✝
[PROOFSTEP]
rw [← sub_eq_zero, ← Ideal.mem_bot, ← iInf_ker_truncate, Ideal.mem_iInf]
[GOAL]
case refine'_2
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
x✝ y✝ : S
⊢ ∀ (i : ℕ), liftFun f (x✝ * y✝) - liftFun f x✝ * liftFun f y✝ ∈ RingHom.ker (truncate i)
[PROOFSTEP]
simp [RingHom.mem_ker, f_compat]
[GOAL]
case refine'_3
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ OneHom.toFun
      (↑{ toOneHom := { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) },
          map_mul' :=
            (_ :
              ∀ (x y : S),
                OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } (x * y) =
                  OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } x *
                    OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } y) })
      0 =
    0
[PROOFSTEP]
intros
[GOAL]
case refine'_3
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ OneHom.toFun
      (↑{ toOneHom := { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) },
          map_mul' :=
            (_ :
              ∀ (x y : S),
                OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } (x * y) =
                  OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } x *
                    OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } y) })
      0 =
    0
[PROOFSTEP]
dsimp only
[GOAL]
case refine'_3
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ liftFun f 0 = 0
[PROOFSTEP]
rw [← sub_eq_zero, ← Ideal.mem_bot, ← iInf_ker_truncate, Ideal.mem_iInf]
[GOAL]
case refine'_3
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ ∀ (i : ℕ), liftFun f 0 - 0 ∈ RingHom.ker (truncate i)
[PROOFSTEP]
simp [RingHom.mem_ker, f_compat]
[GOAL]
case refine'_4
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ ∀ (x y : S),
    OneHom.toFun
        (↑{ toOneHom := { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) },
            map_mul' :=
              (_ :
                ∀ (x y : S),
                  OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } (x * y) =
                    OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } x *
                      OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } y) })
        (x + y) =
      OneHom.toFun
          (↑{ toOneHom := { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) },
              map_mul' :=
                (_ :
                  ∀ (x y : S),
                    OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } (x * y) =
                      OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } x *
                        OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } y) })
          x +
        OneHom.toFun
          (↑{ toOneHom := { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) },
              map_mul' :=
                (_ :
                  ∀ (x y : S),
                    OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } (x * y) =
                      OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } x *
                        OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } y) })
          y
[PROOFSTEP]
intros
[GOAL]
case refine'_4
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
x✝ y✝ : S
⊢ OneHom.toFun
      (↑{ toOneHom := { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) },
          map_mul' :=
            (_ :
              ∀ (x y : S),
                OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } (x * y) =
                  OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } x *
                    OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } y) })
      (x✝ + y✝) =
    OneHom.toFun
        (↑{ toOneHom := { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) },
            map_mul' :=
              (_ :
                ∀ (x y : S),
                  OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } (x * y) =
                    OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } x *
                      OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } y) })
        x✝ +
      OneHom.toFun
        (↑{ toOneHom := { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) },
            map_mul' :=
              (_ :
                ∀ (x y : S),
                  OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } (x * y) =
                    OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } x *
                      OneHom.toFun { toFun := liftFun f, map_one' := (_ : liftFun f 1 = 1) } y) })
        y✝
[PROOFSTEP]
dsimp only
[GOAL]
case refine'_4
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
x✝ y✝ : S
⊢ liftFun f (x✝ + y✝) = liftFun f x✝ + liftFun f y✝
[PROOFSTEP]
rw [← sub_eq_zero, ← Ideal.mem_bot, ← iInf_ker_truncate, Ideal.mem_iInf]
[GOAL]
case refine'_4
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
x✝ y✝ : S
⊢ ∀ (i : ℕ), liftFun f (x✝ + y✝) - (liftFun f x✝ + liftFun f y✝) ∈ RingHom.ker (truncate i)
[PROOFSTEP]
simp [RingHom.mem_ker, f_compat]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ RingHom.comp (truncate n) (lift (fun k₂ => f k₂) f_compat) = f n
[PROOFSTEP]
ext1
[GOAL]
case a
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
x✝ : S
⊢ ↑(RingHom.comp (truncate n) (lift (fun k₂ => f k₂) f_compat)) x✝ = ↑(f n) x✝
[PROOFSTEP]
rw [RingHom.comp_apply, truncate_lift]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
g : S →+* 𝕎 R
g_compat : ∀ (k : ℕ), RingHom.comp (truncate k) g = f k
⊢ lift (fun k₂ => f k₂) f_compat = g
[PROOFSTEP]
ext1 x
[GOAL]
case a
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
g : S →+* 𝕎 R
g_compat : ∀ (k : ℕ), RingHom.comp (truncate k) g = f k
x : S
⊢ ↑(lift (fun k₂ => f k₂) f_compat) x = ↑g x
[PROOFSTEP]
rw [← sub_eq_zero, ← Ideal.mem_bot, ← iInf_ker_truncate, Ideal.mem_iInf]
[GOAL]
case a
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
g : S →+* 𝕎 R
g_compat : ∀ (k : ℕ), RingHom.comp (truncate k) g = f k
x : S
⊢ ∀ (i : ℕ), ↑(lift (fun k₂ => f k₂) f_compat) x - ↑g x ∈ RingHom.ker (truncate i)
[PROOFSTEP]
intro i
[GOAL]
case a
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
g : S →+* 𝕎 R
g_compat : ∀ (k : ℕ), RingHom.comp (truncate k) g = f k
x : S
i : ℕ
⊢ ↑(lift (fun k₂ => f k₂) f_compat) x - ↑g x ∈ RingHom.ker (truncate i)
[PROOFSTEP]
simp only [RingHom.mem_ker, g_compat, ← RingHom.comp_apply, truncate_comp_lift, RingHom.map_sub, sub_self]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
g : S →+* 𝕎 R
⊢ ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂),
    RingHom.comp (TruncatedWittVector.truncate hk) ((fun k => RingHom.comp (truncate k) g) k₂) =
      (fun k => RingHom.comp (truncate k) g) k₁
[PROOFSTEP]
intro _ _ h
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
g : S →+* 𝕎 R
k₁✝ k₂✝ : ℕ
h : k₁✝ ≤ k₂✝
⊢ RingHom.comp (TruncatedWittVector.truncate h) ((fun k => RingHom.comp (truncate k) g) k₂✝) =
    (fun k => RingHom.comp (truncate k) g) k₁✝
[PROOFSTEP]
simp only [← RingHom.comp_assoc, truncate_comp_wittVector_truncate]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ Function.LeftInverse
    (fun g =>
      { val := fun k => RingHom.comp (truncate k) g,
        property :=
          (_ :
            ∀ (k₁ k₂ : ℕ) (h : k₁ ≤ k₂),
              RingHom.comp (RingHom.comp (TruncatedWittVector.truncate h) (truncate k₂)) g =
                RingHom.comp (truncate k₁) g) })
    fun f => lift ↑f (_ : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (↑f k₂) = ↑f k₁)
[PROOFSTEP]
rintro ⟨f, hf⟩
[GOAL]
case mk
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : Semiring S
f✝ : (k : ℕ) → S →+* TruncatedWittVector p k R
f_compat : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f✝ k₂) = f✝ k₁
f : (k : ℕ) → S →+* TruncatedWittVector p k R
hf : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (f k₂) = f k₁
⊢ (fun g =>
        { val := fun k => RingHom.comp (truncate k) g,
          property :=
            (_ :
              ∀ (k₁ k₂ : ℕ) (h : k₁ ≤ k₂),
                RingHom.comp (RingHom.comp (TruncatedWittVector.truncate h) (truncate k₂)) g =
                  RingHom.comp (truncate k₁) g) })
      ((fun f =>
          lift ↑f (_ : ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), RingHom.comp (TruncatedWittVector.truncate hk) (↑f k₂) = ↑f k₁))
        { val := f, property := hf }) =
    { val := f, property := hf }
[PROOFSTEP]
simp only [truncate_comp_lift]


[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝ : HasEqualizer f g
⊢ (equalizerSubobjectIso f g).hom ≫ equalizer.ι f g = arrow (equalizerSubobject f g)
[PROOFSTEP]
simp [equalizerSubobjectIso]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝ : HasEqualizer f g
⊢ (equalizerSubobjectIso f g).inv ≫ arrow (equalizerSubobject f g) = equalizer.ι f g
[PROOFSTEP]
simp [equalizerSubobjectIso]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝ : HasEqualizer f g
⊢ arrow (equalizerSubobject f g) ≫ f = arrow (equalizerSubobject f g) ≫ g
[PROOFSTEP]
rw [← equalizerSubobject_arrow, Category.assoc, Category.assoc, equalizer.condition]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝ : HasEqualizer f g
W : C
h : W ⟶ X
w : h ≫ f = h ≫ g
⊢ equalizer.lift h w ≫ MonoOver.arrow (MonoOver.mk' (equalizer.ι f g)) = h
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝ : HasEqualizer f g
W : C
h : W ⟶ X
w : Factors (equalizerSubobject f g) h
⊢ h ≫ f = h ≫ g
[PROOFSTEP]
rw [← Subobject.factorThru_arrow _ _ w, Category.assoc, equalizerSubobject_arrow_comp, Category.assoc]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
⊢ (kernelSubobjectIso f).hom ≫ kernel.ι f = arrow (kernelSubobject f)
[PROOFSTEP]
simp [kernelSubobjectIso]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
⊢ (kernelSubobjectIso f).inv ≫ arrow (kernelSubobject f) = kernel.ι f
[PROOFSTEP]
simp [kernelSubobjectIso]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
⊢ arrow (kernelSubobject f) ≫ f = 0
[PROOFSTEP]
rw [← kernelSubobject_arrow]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
⊢ ((kernelSubobjectIso f).hom ≫ kernel.ι f) ≫ f = 0
[PROOFSTEP]
simp only [Category.assoc, kernel.condition, comp_zero]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
W : C
h : W ⟶ X
w : h ≫ f = 0
⊢ kernel.lift f h w ≫ MonoOver.arrow (MonoOver.mk' (kernel.ι f)) = h
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
W : C
h : W ⟶ X
w : Factors (kernelSubobject f) h
⊢ h ≫ f = 0
[PROOFSTEP]
rw [← Subobject.factorThru_arrow _ _ w, Category.assoc, kernelSubobject_arrow_comp, comp_zero]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
W : C
h : W ⟶ X
w : h ≫ f = 0
⊢ factorThruKernelSubobject f h w ≫ arrow (kernelSubobject f) = h
[PROOFSTEP]
dsimp [factorThruKernelSubobject]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
W : C
h : W ⟶ X
w : h ≫ f = 0
⊢ factorThru (kernelSubobject f) h (_ : Factors (kernelSubobject f) h) ≫ arrow (kernelSubobject f) = h
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
W : C
h : W ⟶ X
w : h ≫ f = 0
⊢ (factorThruKernelSubobject f h w ≫ (kernelSubobjectIso f).hom) ≫ kernel.ι f = kernel.lift f h w ≫ kernel.ι f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
inst✝² : HasZeroMorphisms C
f : X ⟶ Y
inst✝¹ : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝ : HasKernel f'
sq : Arrow.mk f ⟶ Arrow.mk f'
⊢ (arrow (kernelSubobject f) ≫ sq.left) ≫ f' = 0
[PROOFSTEP]
simp [sq.w]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
inst✝² : HasZeroMorphisms C
f : X ⟶ Y
inst✝¹ : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝ : HasKernel f'
sq : Arrow.mk f ⟶ Arrow.mk f'
⊢ kernelSubobjectMap sq ≫ arrow (kernelSubobject f') = arrow (kernelSubobject f) ≫ sq.left
[PROOFSTEP]
simp [kernelSubobjectMap]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
inst✝² : HasZeroMorphisms C
f : X ⟶ Y
inst✝¹ : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝ : HasKernel f'
⊢ kernelSubobjectMap (𝟙 (Arrow.mk f)) = 𝟙 (underlying.obj (kernelSubobject f))
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
inst✝³ : HasZeroMorphisms C
f : X ⟶ Y
inst✝² : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝¹ : HasKernel f'
X'' Y'' : C
f'' : X'' ⟶ Y''
inst✝ : HasKernel f''
sq : Arrow.mk f ⟶ Arrow.mk f'
sq' : Arrow.mk f' ⟶ Arrow.mk f''
⊢ kernelSubobjectMap (sq ≫ sq') = kernelSubobjectMap sq ≫ kernelSubobjectMap sq'
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
inst✝² : HasZeroMorphisms C
f : X ⟶ Y
inst✝¹ : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝ : HasKernel f'
sq : Arrow.mk f ⟶ Arrow.mk f'
⊢ kernel.map f f' sq.left sq.right (_ : (Arrow.mk f).hom ≫ (𝟭 C).map sq.right = (𝟭 C).map sq.left ≫ (Arrow.mk f').hom) ≫
      (kernelSubobjectIso f').inv =
    (kernelSubobjectIso f).inv ≫ kernelSubobjectMap sq
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
inst✝² : HasZeroMorphisms C
f : X ⟶ Y
inst✝¹ : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝ : HasKernel f'
sq : Arrow.mk f ⟶ Arrow.mk f'
⊢ (kernelSubobjectIso f).hom ≫
      kernel.map f f' sq.left sq.right
        (_ : (Arrow.mk f).hom ≫ (𝟭 C).map sq.right = (𝟭 C).map sq.left ≫ (Arrow.mk f').hom) =
    kernelSubobjectMap sq ≫ (kernelSubobjectIso f').hom
[PROOFSTEP]
simp [← Iso.comp_inv_eq, kernel_map_comp_kernelSubobjectIso_inv]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
A B : C
⊢ IsIso (kernel.ι 0)
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
A : Subobject X
h : arrow A ≫ f = 0
⊢ kernel.lift f (arrow A) h ≫ kernel.ι f = arrow A
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
X' : C
f : X' ⟶ X
inst✝¹ : IsIso f
g : X ⟶ Y
inst✝ : HasKernel g
⊢ (kernelSubobjectIsoComp f g).hom ≫ arrow (kernelSubobject g) = arrow (kernelSubobject (f ≫ g)) ≫ f
[PROOFSTEP]
simp [kernelSubobjectIsoComp]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
X' : C
f : X' ⟶ X
inst✝¹ : IsIso f
g : X ⟶ Y
inst✝ : HasKernel g
⊢ (kernelSubobjectIsoComp f g).inv ≫ arrow (kernelSubobject (f ≫ g)) = arrow (kernelSubobject g) ≫ inv f
[PROOFSTEP]
simp [kernelSubobjectIsoComp]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z✝ : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
f : X ⟶ Y
inst✝¹ : HasKernel f
Z : C
h : Y ⟶ Z
inst✝ : HasKernel (f ≫ h)
⊢ arrow (kernelSubobject f) ≫ f ≫ h = 0
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z✝ : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
f : X ⟶ Y
inst✝¹ : HasKernel f
Z : C
h : Y ⟶ Z
inst✝ : Mono h
⊢ (arrow (kernelSubobject (f ≫ h)) ≫ f) ≫ h = 0 ≫ h
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z✝ : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
f : X ⟶ Y
inst✝¹ : HasKernel f
Z : C
h : Y ⟶ Z
inst✝ : Mono h
⊢ IsIso (ofLE (kernelSubobject f) (kernelSubobject (f ≫ h)) (_ : kernelSubobject f ≤ kernelSubobject (f ≫ h)))
[PROOFSTEP]
rw [ofLE_mk_le_mk_of_comm (kernelCompMono f h).inv]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z✝ : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
f : X ⟶ Y
inst✝¹ : HasKernel f
Z : C
h : Y ⟶ Z
inst✝ : Mono h
⊢ IsIso ((underlyingIso (kernel.ι f)).hom ≫ (kernelCompMono f h).inv ≫ (underlyingIso (kernel.ι (f ≫ h))).inv)
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z✝ : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
f : X ⟶ Y
inst✝¹ : HasKernel f
Z : C
h : Y ⟶ Z
inst✝ : Mono h
⊢ (kernelCompMono f h).inv ≫ kernel.ι (f ≫ h) = kernel.ι f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasCokernels C
X : C
⊢ ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [inst : Mono f] [inst_1 : Mono g] (i : A ≅ B),
    i.hom ≫ g = f →
      (fun A f x => Subobject.mk (cokernel.π f).op) A f inst = (fun A f x => Subobject.mk (cokernel.π f).op) B g inst_1
[PROOFSTEP]
rintro A B f g hf hg i rfl
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasCokernels C
X A B : C
g : B ⟶ X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ (fun A f x => Subobject.mk (cokernel.π f).op) A (i.hom ≫ g) hf = (fun A f x => Subobject.mk (cokernel.π f).op) B g hg
[PROOFSTEP]
refine' Subobject.mk_eq_mk_of_comm _ _ (Iso.op _) (Quiver.Hom.unop_inj _)
[GOAL]
case refine'_1
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasCokernels C
X A B : C
g : B ⟶ X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ cokernel g ≅ cokernel (i.hom ≫ g)
[PROOFSTEP]
exact
  (IsColimit.coconePointUniqueUpToIso (colimit.isColimit _) (isCokernelEpiComp (colimit.isColimit _) i.hom rfl)).symm
[GOAL]
case refine'_2
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasCokernels C
X A B : C
g : B ⟶ X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ ((Iso.op
            (IsColimit.coconePointUniqueUpToIso (colimit.isColimit (parallelPair (i.hom ≫ g) 0))
                (isCokernelEpiComp (colimit.isColimit (parallelPair g 0)) i.hom
                  (_ : i.hom ≫ g = i.hom ≫ g))).symm).hom ≫
        (cokernel.π g).op).unop =
    (cokernel.π (i.hom ≫ g)).op.unop
[PROOFSTEP]
simp only [Iso.comp_inv_eq, Iso.op_hom, Iso.symm_hom, unop_comp, Quiver.Hom.unop_op,
  colimit.comp_coconePointUniqueUpToIso_hom, Cofork.ofπ_ι_app, coequalizer.cofork_π]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasCokernels C
X : C
⊢ ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [inst : Mono f] [inst_1 : Mono g],
    Subobject.mk f ≤ Subobject.mk g →
      Subobject.lift (fun A f x => Subobject.mk (cokernel.π f).op)
          (_ :
            ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
              i.hom ≫ g = f →
                (fun A f x => Subobject.mk (cokernel.π f).op) A f hf =
                  (fun A f x => Subobject.mk (cokernel.π f).op) B g hg)
          (Subobject.mk f) ≤
        Subobject.lift (fun A f x => Subobject.mk (cokernel.π f).op)
          (_ :
            ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
              i.hom ≫ g = f →
                (fun A f x => Subobject.mk (cokernel.π f).op) A f hf =
                  (fun A f x => Subobject.mk (cokernel.π f).op) B g hg)
          (Subobject.mk g)
[PROOFSTEP]
intro A B f g hf hg h
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasCokernels C
X A B : C
f : A ⟶ X
g : B ⟶ X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ Subobject.lift (fun A f x => Subobject.mk (cokernel.π f).op)
      (_ :
        ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
          i.hom ≫ g = f →
            (fun A f x => Subobject.mk (cokernel.π f).op) A f hf = (fun A f x => Subobject.mk (cokernel.π f).op) B g hg)
      (Subobject.mk f) ≤
    Subobject.lift (fun A f x => Subobject.mk (cokernel.π f).op)
      (_ :
        ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
          i.hom ≫ g = f →
            (fun A f x => Subobject.mk (cokernel.π f).op) A f hf = (fun A f x => Subobject.mk (cokernel.π f).op) B g hg)
      (Subobject.mk g)
[PROOFSTEP]
dsimp only [Subobject.lift_mk]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasCokernels C
X A B : C
f : A ⟶ X
g : B ⟶ X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ Subobject.mk (cokernel.π f).op ≤ Subobject.mk (cokernel.π g).op
[PROOFSTEP]
refine' Subobject.mk_le_mk_of_comm (cokernel.desc f (cokernel.π g) _).op _
[GOAL]
case refine'_1
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasCokernels C
X A B : C
f : A ⟶ X
g : B ⟶ X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ f ≫ cokernel.π g = 0
[PROOFSTEP]
rw [← Subobject.ofMkLEMk_comp h, Category.assoc, cokernel.condition, comp_zero]
[GOAL]
case refine'_2
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasCokernels C
X A B : C
f : A ⟶ X
g : B ⟶ X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ (cokernel.desc f (cokernel.π g) (_ : f ≫ cokernel.π g = 0)).op ≫ (cokernel.π f).op = (cokernel.π g).op
[PROOFSTEP]
exact Quiver.Hom.unop_inj (cokernel.π_desc _ _ _)
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
⊢ ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [inst : Mono f] [inst_1 : Mono g] (i : A ≅ B),
    i.hom ≫ g = f →
      (fun A f x => Subobject.mk (kernel.ι f.unop)) A f inst = (fun A f x => Subobject.mk (kernel.ι f.unop)) B g inst_1
[PROOFSTEP]
rintro A B f g hf hg i rfl
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
g : B ⟶ op X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ (fun A f x => Subobject.mk (kernel.ι f.unop)) A (i.hom ≫ g) hf = (fun A f x => Subobject.mk (kernel.ι f.unop)) B g hg
[PROOFSTEP]
refine' Subobject.mk_eq_mk_of_comm _ _ _ _
[GOAL]
case refine'_1
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
g : B ⟶ op X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ kernel (i.hom ≫ g).unop ≅ kernel g.unop
[PROOFSTEP]
exact
  IsLimit.conePointUniqueUpToIso (limit.isLimit _)
    (isKernelCompMono (limit.isLimit (parallelPair g.unop 0)) i.unop.hom rfl)
[GOAL]
case refine'_2
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
g : B ⟶ op X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ (IsLimit.conePointUniqueUpToIso (limit.isLimit (parallelPair (g.unop ≫ (Iso.unop i).hom) 0))
          (isKernelCompMono (limit.isLimit (parallelPair g.unop 0)) (Iso.unop i).hom
            (_ : g.unop ≫ (Iso.unop i).hom = g.unop ≫ (Iso.unop i).hom))).hom ≫
      kernel.ι g.unop =
    kernel.ι (i.hom ≫ g).unop
[PROOFSTEP]
dsimp
[GOAL]
case refine'_2
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
g : B ⟶ op X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ (IsLimit.conePointUniqueUpToIso (limit.isLimit (parallelPair (g.unop ≫ i.hom.unop) 0))
          (isKernelCompMono (limit.isLimit (parallelPair g.unop 0)) i.hom.unop
            (_ : g.unop ≫ i.hom.unop = g.unop ≫ i.hom.unop))).hom ≫
      kernel.ι g.unop =
    kernel.ι (g.unop ≫ i.hom.unop)
[PROOFSTEP]
simp only [← Iso.eq_inv_comp, limit.conePointUniqueUpToIso_inv_comp, Fork.ofι_π_app]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
⊢ ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [inst : Mono f] [inst_1 : Mono g],
    Subobject.mk f ≤ Subobject.mk g →
      Subobject.lift (fun A f x => Subobject.mk (kernel.ι f.unop))
          (_ :
            ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
              i.hom ≫ g = f →
                (fun A f x => Subobject.mk (kernel.ι f.unop)) A f hf =
                  (fun A f x => Subobject.mk (kernel.ι f.unop)) B g hg)
          (Subobject.mk f) ≤
        Subobject.lift (fun A f x => Subobject.mk (kernel.ι f.unop))
          (_ :
            ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
              i.hom ≫ g = f →
                (fun A f x => Subobject.mk (kernel.ι f.unop)) A f hf =
                  (fun A f x => Subobject.mk (kernel.ι f.unop)) B g hg)
          (Subobject.mk g)
[PROOFSTEP]
intro A B f g hf hg h
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ Subobject.lift (fun A f x => Subobject.mk (kernel.ι f.unop))
      (_ :
        ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
          i.hom ≫ g = f →
            (fun A f x => Subobject.mk (kernel.ι f.unop)) A f hf = (fun A f x => Subobject.mk (kernel.ι f.unop)) B g hg)
      (Subobject.mk f) ≤
    Subobject.lift (fun A f x => Subobject.mk (kernel.ι f.unop))
      (_ :
        ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
          i.hom ≫ g = f →
            (fun A f x => Subobject.mk (kernel.ι f.unop)) A f hf = (fun A f x => Subobject.mk (kernel.ι f.unop)) B g hg)
      (Subobject.mk g)
[PROOFSTEP]
dsimp only [Subobject.lift_mk]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ Subobject.mk (kernel.ι f.unop) ≤ Subobject.mk (kernel.ι g.unop)
[PROOFSTEP]
refine' Subobject.mk_le_mk_of_comm (kernel.lift g.unop (kernel.ι f.unop) _) _
[GOAL]
case refine'_1
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ kernel.ι f.unop ≫ g.unop = 0
[PROOFSTEP]
rw [← Subobject.ofMkLEMk_comp h, unop_comp, kernel.condition_assoc, zero_comp]
[GOAL]
case refine'_2
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ kernel.lift g.unop (kernel.ι f.unop) (_ : kernel.ι f.unop ≫ g.unop = 0) ≫ kernel.ι g.unop = kernel.ι f.unop
[PROOFSTEP]
exact Quiver.Hom.op_inj (by simp)
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ (kernel.lift g.unop (kernel.ι f.unop) (_ : kernel.ι f.unop ≫ g.unop = 0) ≫ kernel.ι g.unop).op = (kernel.ι f.unop).op
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
⊢ (imageSubobjectIso f).hom ≫ image.ι f = arrow (imageSubobject f)
[PROOFSTEP]
simp [imageSubobjectIso]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
⊢ (imageSubobjectIso f).inv ≫ arrow (imageSubobject f) = image.ι f
[PROOFSTEP]
simp [imageSubobjectIso]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasEqualizers C
⊢ Epi (factorThruImageSubobject f)
[PROOFSTEP]
dsimp [factorThruImageSubobject]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasEqualizers C
⊢ Epi (factorThruImage f ≫ (imageSubobjectIso f).inv)
[PROOFSTEP]
apply epi_comp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
⊢ factorThruImageSubobject f ≫ arrow (imageSubobject f) = f
[PROOFSTEP]
simp [factorThruImageSubobject, imageSubobject_arrow]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
inst✝² : HasZeroMorphisms C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
inst✝¹ : HasImage f
inst✝ : Epi (factorThruImageSubobject f)
h : f ≫ g = 0
⊢ factorThruImageSubobject f ≫ arrow (imageSubobject f) ≫ g = 0
[PROOFSTEP]
simp [h]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W : C
k : W ⟶ X
⊢ (k ≫ factorThruImage f) ≫ MonoOver.arrow (MonoOver.mk' (image.ι f)) = k ≫ f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W : C
k : W ⟶ X
h : Factors (imageSubobject f) (k ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ f) h = k ≫ factorThruImageSubobject f
[PROOFSTEP]
ext
[GOAL]
case h
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W : C
k : W ⟶ X
h : Factors (imageSubobject f) (k ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ f) h ≫ arrow (imageSubobject f) =
    (k ≫ factorThruImageSubobject f) ≫ arrow (imageSubobject f)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W W' : C
k : W ⟶ W'
k' : W' ⟶ X
h : Factors (imageSubobject f) (k ≫ k' ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ k' ≫ f) h = k ≫ k' ≫ factorThruImageSubobject f
[PROOFSTEP]
ext
[GOAL]
case h
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W W' : C
k : W ⟶ W'
k' : W' ⟶ X
h : Factors (imageSubobject f) (k ≫ k' ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ k' ≫ f) h ≫ arrow (imageSubobject f) =
    (k ≫ k' ≫ factorThruImageSubobject f) ≫ arrow (imageSubobject f)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝² : HasImage f✝
X' : C
h : X' ⟶ X
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ image.preComp h f ≫ image.ι f = image.ι (h ≫ f)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝² : HasImage f
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
⊢ arrow (imageSubobject 0) = 0
[PROOFSTEP]
rw [← imageSubobject_arrow]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝² : HasImage f
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
⊢ (imageSubobjectIso 0).hom ≫ image.ι 0 = 0
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝² : HasImage f
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
A B : C
⊢ (imageSubobjectIso 0 ≪≫ imageZero ≪≫ botCoeIsoZero.symm).hom ≫ arrow ⊥ = arrow (imageSubobject 0)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁵ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝⁴ : HasImage f✝
inst✝³ : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝² : Epi h
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ Epi (ofLE (imageSubobject (h ≫ f)) (imageSubobject f) (_ : imageSubobject (h ≫ f) ≤ imageSubobject f))
[PROOFSTEP]
rw [ofLE_mk_le_mk_of_comm (image.preComp h f)]
[GOAL]
C : Type u
inst✝⁵ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝⁴ : HasImage f✝
inst✝³ : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝² : Epi h
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ Epi ((underlyingIso (image.ι (h ≫ f))).hom ≫ image.preComp h f ≫ (underlyingIso (image.ι f)).inv)
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u
inst✝⁵ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝⁴ : HasImage f✝
inst✝³ : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝² : Epi h
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ image.preComp h f ≫ image.ι f = image.ι (h ≫ f)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝³ : HasImage f✝
inst✝² : HasEqualizers C
f : X ⟶ Y
inst✝¹ : HasImage f
Y' : C
h : Y ⟶ Y'
inst✝ : IsIso h
⊢ (imageSubobjectCompIso f h).hom ≫ arrow (imageSubobject f) = arrow (imageSubobject (f ≫ h)) ≫ inv h
[PROOFSTEP]
simp [imageSubobjectCompIso]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝³ : HasImage f✝
inst✝² : HasEqualizers C
f : X ⟶ Y
inst✝¹ : HasImage f
Y' : C
h : Y ⟶ Y'
inst✝ : IsIso h
⊢ (imageSubobjectCompIso f h).inv ≫ arrow (imageSubobject (f ≫ h)) = arrow (imageSubobject f) ≫ h
[PROOFSTEP]
simp [imageSubobjectCompIso]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝¹ : HasImage f✝
f : X ⟶ Y
inst✝ : Mono f
⊢ (imageSubobjectIso f ≪≫ imageMonoIsoSource f ≪≫ (underlyingIso f).symm).hom ≫ arrow (Subobject.mk f) =
    arrow (imageSubobject f)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝³ : HasImage f✝
inst✝² : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝¹ : IsIso h
f : X ⟶ Y
inst✝ : HasImage f
⊢ inv (image.preComp h f) ≫ image.ι (h ≫ f) = image.ι f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X✝ Y Z : C
f✝ : X✝ ⟶ Y
inst✝¹ : HasImage f✝
A B : C
X : Subobject B
f : A ⟶ B
inst✝ : HasImage f
h : A ⟶ underlying.obj X
w : h ≫ arrow X = f
⊢ ((imageSubobjectIso f).hom ≫ image.lift (MonoFactorisation.mk (underlying.obj X) (arrow X) h)) ≫ arrow X =
    arrow (imageSubobject f)
[PROOFSTEP]
rw [assoc, image.lift_fac, imageSubobject_arrow]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
f✝ : X✝ ⟶ Y
inst✝² : HasImage f✝
A B X : C
g : X ⟶ B
inst✝¹ : Mono g
f : A ⟶ B
inst✝ : HasImage f
h : A ⟶ X
w : h ≫ g = f
⊢ (h ≫ (underlyingIso g).inv) ≫ arrow (Subobject.mk g) = f
[PROOFSTEP]
simp [w]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ imageSubobjectMap sq ≫ arrow (imageSubobject g) = arrow (imageSubobject f) ≫ sq.right
[PROOFSTEP]
simp only [imageSubobjectMap, Category.assoc, imageSubobject_arrow']
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ (imageSubobjectIso f).hom ≫ image.map sq ≫ image.ι g = arrow (imageSubobject f) ≫ sq.right
[PROOFSTEP]
erw [image.map_ι, ← Category.assoc, imageSubobject_arrow]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ image.map sq ≫ (imageSubobjectIso (Arrow.mk g).hom).inv = (imageSubobjectIso f).inv ≫ imageSubobjectMap sq
[PROOFSTEP]
ext
[GOAL]
case h
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ (image.map sq ≫ (imageSubobjectIso (Arrow.mk g).hom).inv) ≫ arrow (imageSubobject (Arrow.mk g).hom) =
    ((imageSubobjectIso f).inv ≫ imageSubobjectMap sq) ≫ arrow (imageSubobject (Arrow.mk g).hom)
[PROOFSTEP]
simpa using image.map_ι sq
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ (imageSubobjectIso (Arrow.mk f).hom).hom ≫ image.map sq = imageSubobjectMap sq ≫ (imageSubobjectIso g).hom
[PROOFSTEP]
erw [← Iso.comp_inv_eq, Category.assoc, ← (imageSubobjectIso f).eq_inv_comp, image_map_comp_imageSubobjectIso_inv sq]


[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
hx : x ≤ a
⊢ projIcc a b h x = { val := a, property := (_ : a ∈ Icc a b) }
[PROOFSTEP]
simp [projIcc, hx, hx.trans h]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
hx : b ≤ x
⊢ projIcc a b h x = { val := b, property := (_ : b ∈ Icc a b) }
[PROOFSTEP]
simp [projIcc, hx, h]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
⊢ projIci a x = { val := a, property := (_ : a ≤ a) } ↔ x ≤ a
[PROOFSTEP]
simp [projIci, Subtype.ext_iff]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
⊢ projIic b x = { val := b, property := (_ : b ≤ b) } ↔ b ≤ x
[PROOFSTEP]
simp [projIic, Subtype.ext_iff]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h✝ : a ≤ b
x : α
h : a < b
⊢ projIcc a b (_ : a ≤ b) x = { val := a, property := (_ : a ∈ Icc a b) } ↔ x ≤ a
[PROOFSTEP]
simp [projIcc, Subtype.ext_iff, h.not_le]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h✝ : a ≤ b
x : α
h : a < b
⊢ projIcc a b (_ : a ≤ b) x = { val := b, property := (_ : b ∈ Icc a b) } ↔ b ≤ x
[PROOFSTEP]
simp [projIcc, Subtype.ext_iff, max_min_distrib_left, h.le, h.not_le]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
hx : x ∈ Ici a
⊢ projIci a x = { val := x, property := hx }
[PROOFSTEP]
simpa [projIci]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
hx : x ∈ Iic b
⊢ projIic b x = { val := x, property := hx }
[PROOFSTEP]
simpa [projIic]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
hx : x ∈ Icc a b
⊢ projIcc a b h x = { val := x, property := hx }
[PROOFSTEP]
simp [projIcc, hx.1, hx.2]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ : α
x : ↑(Ici a)
⊢ projIci a ↑x = x
[PROOFSTEP]
cases x
[GOAL]
case mk
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x val✝ : α
property✝ : val✝ ∈ Ici a
⊢ projIci a ↑{ val := val✝, property := property✝ } = { val := val✝, property := property✝ }
[PROOFSTEP]
apply projIci_of_mem
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ : α
x : ↑(Iic b)
⊢ projIic b ↑x = x
[PROOFSTEP]
cases x
[GOAL]
case mk
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x val✝ : α
property✝ : val✝ ∈ Iic b
⊢ projIic b ↑{ val := val✝, property := property✝ } = { val := val✝, property := property✝ }
[PROOFSTEP]
apply projIic_of_mem
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ : α
x : ↑(Icc a b)
⊢ projIcc a b h ↑x = x
[PROOFSTEP]
cases x
[GOAL]
case mk
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x val✝ : α
property✝ : val✝ ∈ Icc a b
⊢ projIcc a b h ↑{ val := val✝, property := property✝ } = { val := val✝, property := property✝ }
[PROOFSTEP]
apply projIcc_of_mem
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ x : α
hx : x ∈ Ici a
y : α
hy : y ∈ Ici a
hxy : x < y
⊢ projIci a x < projIci a y
[PROOFSTEP]
simpa only [projIci_of_mem, hx, hy]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ x : α
hx : x ∈ Iic b
y : α
hy : y ∈ Iic b
hxy : x < y
⊢ projIic b x < projIic b y
[PROOFSTEP]
simpa only [projIic_of_mem, hx, hy]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ x : α
hx : x ∈ Icc a b
y : α
hy : y ∈ Icc a b
hxy : x < y
⊢ projIcc a b h x < projIcc a b h y
[PROOFSTEP]
simpa only [projIcc_of_mem, hx, hy]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
f : ↑(Ici a) → β
⊢ range (IciExtend f) = range f
[PROOFSTEP]
simp only [IciExtend, range_comp f, range_projIci, range_id', image_univ]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
f : ↑(Iic b) → β
⊢ range (IicExtend f) = range f
[PROOFSTEP]
simp only [IicExtend, range_comp f, range_projIic, range_id', image_univ]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
f : ↑(Icc a b) → β
⊢ range (IccExtend h f) = range f
[PROOFSTEP]
simp only [IccExtend, range_comp f, range_projIcc, image_univ]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x : α
f : α → β
ha : ∀ (x : α), x < a → f x = f a
hb : ∀ (x : α), b < x → f x = f b
⊢ IccExtend h (f ∘ Subtype.val) = f
[PROOFSTEP]
ext x
[GOAL]
case h
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ : α
f : α → β
ha : ∀ (x : α), x < a → f x = f a
hb : ∀ (x : α), b < x → f x = f b
x : α
⊢ IccExtend h (f ∘ Subtype.val) x = f x
[PROOFSTEP]
cases' lt_or_le x a with hxa hax
[GOAL]
case h.inl
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ : α
f : α → β
ha : ∀ (x : α), x < a → f x = f a
hb : ∀ (x : α), b < x → f x = f b
x : α
hxa : x < a
⊢ IccExtend h (f ∘ Subtype.val) x = f x
[PROOFSTEP]
simp [IccExtend_of_le_left _ _ hxa.le, ha x hxa]
[GOAL]
case h.inr
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ : α
f : α → β
ha : ∀ (x : α), x < a → f x = f a
hb : ∀ (x : α), b < x → f x = f b
x : α
hax : a ≤ x
⊢ IccExtend h (f ∘ Subtype.val) x = f x
[PROOFSTEP]
cases' le_or_lt x b with hxb hbx
[GOAL]
case h.inr.inl
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ : α
f : α → β
ha : ∀ (x : α), x < a → f x = f a
hb : ∀ (x : α), b < x → f x = f b
x : α
hax : a ≤ x
hxb : x ≤ b
⊢ IccExtend h (f ∘ Subtype.val) x = f x
[PROOFSTEP]
lift x to Icc a b using ⟨hax, hxb⟩
[GOAL]
case h.inr.inl.intro
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ : α
f : α → β
ha : ∀ (x : α), x < a → f x = f a
hb : ∀ (x : α), b < x → f x = f b
x : { x // x ∈ Icc a b }
hax : a ≤ ↑x
hxb : ↑x ≤ b
⊢ IccExtend h (f ∘ Subtype.val) ↑x = f ↑x
[PROOFSTEP]
rw [IccExtend_val, comp_apply]
[GOAL]
case h.inr.inr
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b : α
h : a ≤ b
x✝ : α
f : α → β
ha : ∀ (x : α), x < a → f x = f a
hb : ∀ (x : α), b < x → f x = f b
x : α
hax : a ≤ x
hbx : b < x
⊢ IccExtend h (f ∘ Subtype.val) x = f x
[PROOFSTEP]
simp [IccExtend_of_right_le _ _ hbx.le, hb x hbx]