Theorem: List.mapIdxMAux'_eq_mapIdxMGo
File: Mathlib/Data/List/Indexes.lean

tactic: revert arr
state_before: α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
as : List α
arr : Array PUnit.{u + 1}
⊢ mapIdxMAux' f arr.size as = SeqRight.seqRight (mapIdxM.go f as arr) fun x => pure PUnit.unit
state_after: α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
as : List α
⊢ ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size as = SeqRight.seqRight (mapIdxM.go f as arr) fun x => pure PUnit.unit

tactic: induction' as with head tail ih <;> intro arr
state_before: α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
as : List α
⊢ ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size as = SeqRight.seqRight (mapIdxM.go f as arr) fun x => pure PUnit.unit
state_after: case nil
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
arr : Array PUnit.{u + 1}
⊢ mapIdxMAux' f arr.size [] = SeqRight.seqRight (mapIdxM.go f [] arr) fun x => pure PUnit.unit

case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
⊢ mapIdxMAux' f arr.size (head :: tail) = SeqRight.seqRight (mapIdxM.go f (head :: tail) arr) fun x => pure PUnit.unit

tactic: simp only [mapIdxMAux', mapIdxM.go, seqRight_eq, map_pure, seq_pure]
state_before: case nil
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
arr : Array PUnit.{u + 1}
⊢ mapIdxMAux' f arr.size [] = SeqRight.seqRight (mapIdxM.go f [] arr) fun x => pure PUnit.unit
state_after: no goals

tactic: simp only [mapIdxMAux', seqRight_eq, map_eq_pure_bind, seq_eq_bind, bind_pure_unit,
  LawfulMonad.bind_assoc, pure_bind, mapIdxM.go, seq_pure]
state_before: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
⊢ mapIdxMAux' f arr.size (head :: tail) = SeqRight.seqRight (mapIdxM.go f (head :: tail) arr) fun x => pure PUnit.unit
state_after: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
⊢ (do
      f arr.size head
      mapIdxMAux' f (arr.size + 1) tail) =
    do
    let x ← f arr.size head
    let x ← mapIdxM.go f tail (arr.push x)
    pure (const (List PUnit.{u + 1}) id x PUnit.unit)

tactic: generalize (f (Array.size arr) head) = head
state_before: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
⊢ (do
      f arr.size head
      mapIdxMAux' f (arr.size + 1) tail) =
    do
    let x ← f arr.size head
    let x ← mapIdxM.go f tail (arr.push x)
    pure (const (List PUnit.{u + 1}) id x PUnit.unit)
state_after: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head✝ : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
head : m PUnit.{u + 1}
⊢ (do
      head
      mapIdxMAux' f (arr.size + 1) tail) =
    do
    let x ← head
    let x ← mapIdxM.go f tail (arr.push x)
    pure (const (List PUnit.{u + 1}) id x PUnit.unit)

tactic: let arr_1 := arr.push ⟨⟩
state_before: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head✝ : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
head : m PUnit.{u + 1}
⊢ (do
      head
      mapIdxMAux' f (arr.size + 1) tail) =
    do
    let x ← head
    let x ← mapIdxM.go f tail (arr.push x)
    pure (const (List PUnit.{u + 1}) id x PUnit.unit)
state_after: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head✝ : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
head : m PUnit.{u + 1}
arr_1 : Array PUnit.{u + 1} := arr.push PUnit.unit
⊢ (do
      head
      mapIdxMAux' f (arr.size + 1) tail) =
    do
    let x ← head
    let x ← mapIdxM.go f tail (arr.push x)
    pure (const (List PUnit.{u + 1}) id x PUnit.unit)

tactic: have : arr_1.size = arr.size + 1 := Array.size_push arr ⟨⟩
state_before: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head✝ : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
head : m PUnit.{u + 1}
arr_1 : Array PUnit.{u + 1} := arr.push PUnit.unit
⊢ (do
      head
      mapIdxMAux' f (arr.size + 1) tail) =
    do
    let x ← head
    let x ← mapIdxM.go f tail (arr.push x)
    pure (const (List PUnit.{u + 1}) id x PUnit.unit)
state_after: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head✝ : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
head : m PUnit.{u + 1}
arr_1 : Array PUnit.{u + 1} := arr.push PUnit.unit
this : arr_1.size = arr.size + 1
⊢ (do
      head
      mapIdxMAux' f (arr.size + 1) tail) =
    do
    let x ← head
    let x ← mapIdxM.go f tail (arr.push x)
    pure (const (List PUnit.{u + 1}) id x PUnit.unit)

tactic: rw [← this, ih arr_1]
state_before: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head✝ : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
head : m PUnit.{u + 1}
arr_1 : Array PUnit.{u + 1} := arr.push PUnit.unit
this : arr_1.size = arr.size + 1
⊢ (do
      head
      mapIdxMAux' f (arr.size + 1) tail) =
    do
    let x ← head
    let x ← mapIdxM.go f tail (arr.push x)
    pure (const (List PUnit.{u + 1}) id x PUnit.unit)
state_after: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head✝ : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
head : m PUnit.{u + 1}
arr_1 : Array PUnit.{u + 1} := arr.push PUnit.unit
this : arr_1.size = arr.size + 1
⊢ (do
      head
      SeqRight.seqRight (mapIdxM.go f tail arr_1) fun x => pure PUnit.unit) =
    do
    let x ← head
    let x ← mapIdxM.go f tail (arr.push x)
    pure (const (List PUnit.{u + 1}) id x PUnit.unit)

tactic: simp only [seqRight_eq, map_eq_pure_bind, seq_pure, LawfulMonad.bind_assoc, pure_bind]
state_before: case cons
α✝ : Type u
β : Type v
m : Type u → Type v
inst✝¹ : Monad m
inst✝ : LawfulMonad m
α : Type u_1
f : ℕ → α → m PUnit.{u + 1}
head✝ : α
tail : List α
ih :
  ∀ (arr : Array PUnit.{u + 1}),
    mapIdxMAux' f arr.size tail = SeqRight.seqRight (mapIdxM.go f tail arr) fun x => pure PUnit.unit
arr : Array PUnit.{u + 1}
head : m PUnit.{u + 1}
arr_1 : Array PUnit.{u + 1} := arr.push PUnit.unit
this : arr_1.size = arr.size + 1
⊢ (do
      head
      SeqRight.seqRight (mapIdxM.go f tail arr_1) fun x => pure PUnit.unit) =
    do
    let x ← head
    let x ← mapIdxM.go f tail (arr.push x)
    pure (const (List PUnit.{u + 1}) id x PUnit.unit)
state_after: no goals