Theorem: Std.Range.forIn_eq_forIn_range'
File: .lake/packages/batteries/Batteries/Data/Range/Lemmas.lean

tactic: refine Eq.trans ?_ <| (forIn'_eq_forIn_range' r init (fun x _ => f x)).trans ?_
state_before: m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
⊢ forIn r init f = forIn (List.range' r.start r.numElems r.step) init f
state_after: case refine_1
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
⊢ forIn r init f = forIn' r init fun x x_1 => f x

case refine_2
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
⊢ (forIn (List.pmap Subtype.mk (List.range' r.start r.numElems r.step) ⋯) init fun x =>
      match (motive := { x // x ∈ r } → β → m (ForInStep β)) x with
      | ⟨a, h⟩ => f a) =
    forIn (List.range' r.start r.numElems r.step) init f

tactic: simp [forIn, forIn', Range.forIn, Range.forIn']
state_before: case refine_1
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
⊢ forIn r init f = forIn' r init fun x x_1 => f x
state_after: case refine_1
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
⊢ forIn.loop f r.stop r.start r.stop r.step init =
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) r.stop r.start ⋯ init

tactic: suffices ∀ fuel i hl b, forIn'.loop r.start r.stop r.step (fun x _ => f x) fuel i hl b =
    forIn.loop f fuel i r.stop r.step b from (this _ ..).symm
state_before: case refine_1
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
⊢ forIn.loop f r.stop r.start r.stop r.step init =
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) r.stop r.start ⋯ init
state_after: case refine_1
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
⊢ ∀ (fuel i : Nat) (hl : r.start ≤ i) (b : β),
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) fuel i hl b = forIn.loop f fuel i r.stop r.step b

tactic: intro fuel
state_before: case refine_1
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
⊢ ∀ (fuel i : Nat) (hl : r.start ≤ i) (b : β),
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) fuel i hl b = forIn.loop f fuel i r.stop r.step b
state_after: case refine_1
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
fuel : Nat
⊢ ∀ (i : Nat) (hl : r.start ≤ i) (b : β),
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) fuel i hl b = forIn.loop f fuel i r.stop r.step b

tactic: induction fuel <;> intro i hl b <;>
unfold forIn.loop forIn'.loop <;> simp [*]
state_before: case refine_1
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
fuel : Nat
⊢ ∀ (i : Nat) (hl : r.start ≤ i) (b : β),
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) fuel i hl b = forIn.loop f fuel i r.stop r.step b
state_after: case refine_1.succ
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
n✝ : Nat
a✝ :
  ∀ (i : Nat) (hl : r.start ≤ i) (b : β),
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) n✝ i hl b = forIn.loop f n✝ i r.stop r.step b
i : Nat
hl : r.start ≤ i
b : β
⊢ (if i < r.stop then do
      let __do_lift ← f i b
      match __do_lift with
        | ForInStep.done b => pure b
        | ForInStep.yield b => forIn.loop f n✝ (i + r.step) r.stop r.step b
    else pure b) =
    if r.stop ≤ i then pure b
    else do
      let __do_lift ← f i b
      match __do_lift with
        | ForInStep.done b => pure b
        | ForInStep.yield b => forIn.loop f n✝ (i + r.step) r.stop r.step b

tactic: split
state_before: case refine_1.succ
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
n✝ : Nat
a✝ :
  ∀ (i : Nat) (hl : r.start ≤ i) (b : β),
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) n✝ i hl b = forIn.loop f n✝ i r.stop r.step b
i : Nat
hl : r.start ≤ i
b : β
⊢ (if i < r.stop then do
      let __do_lift ← f i b
      match __do_lift with
        | ForInStep.done b => pure b
        | ForInStep.yield b => forIn.loop f n✝ (i + r.step) r.stop r.step b
    else pure b) =
    if r.stop ≤ i then pure b
    else do
      let __do_lift ← f i b
      match __do_lift with
        | ForInStep.done b => pure b
        | ForInStep.yield b => forIn.loop f n✝ (i + r.step) r.stop r.step b
state_after: case refine_1.succ.isTrue
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
n✝ : Nat
a✝ :
  ∀ (i : Nat) (hl : r.start ≤ i) (b : β),
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) n✝ i hl b = forIn.loop f n✝ i r.stop r.step b
i : Nat
hl : r.start ≤ i
b : β
h✝ : i < r.stop
⊢ (do
      let __do_lift ← f i b
      match __do_lift with
        | ForInStep.done b => pure b
        | ForInStep.yield b => forIn.loop f n✝ (i + r.step) r.stop r.step b) =
    if r.stop ≤ i then pure b
    else do
      let __do_lift ← f i b
      match __do_lift with
        | ForInStep.done b => pure b
        | ForInStep.yield b => forIn.loop f n✝ (i + r.step) r.stop r.step b

case refine_1.succ.isFalse
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
n✝ : Nat
a✝ :
  ∀ (i : Nat) (hl : r.start ≤ i) (b : β),
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) n✝ i hl b = forIn.loop f n✝ i r.stop r.step b
i : Nat
hl : r.start ≤ i
b : β
h✝ : ¬i < r.stop
⊢ pure b =
    if r.stop ≤ i then pure b
    else do
      let __do_lift ← f i b
      match __do_lift with
        | ForInStep.done b => pure b
        | ForInStep.yield b => forIn.loop f n✝ (i + r.step) r.stop r.step b

tactic: simp [if_neg (Nat.not_le.2 ‹_›)]
state_before: case refine_1.succ.isTrue
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
n✝ : Nat
a✝ :
  ∀ (i : Nat) (hl : r.start ≤ i) (b : β),
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) n✝ i hl b = forIn.loop f n✝ i r.stop r.step b
i : Nat
hl : r.start ≤ i
b : β
h✝ : i < r.stop
⊢ (do
      let __do_lift ← f i b
      match __do_lift with
        | ForInStep.done b => pure b
        | ForInStep.yield b => forIn.loop f n✝ (i + r.step) r.stop r.step b) =
    if r.stop ≤ i then pure b
    else do
      let __do_lift ← f i b
      match __do_lift with
        | ForInStep.done b => pure b
        | ForInStep.yield b => forIn.loop f n✝ (i + r.step) r.stop r.step b
state_after: no goals

tactic: simp [if_pos (Nat.not_lt.1 ‹_›)]
state_before: case refine_1.succ.isFalse
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
n✝ : Nat
a✝ :
  ∀ (i : Nat) (hl : r.start ≤ i) (b : β),
    forIn'.loop r.start r.stop r.step (fun x x_1 => f x) n✝ i hl b = forIn.loop f n✝ i r.stop r.step b
i : Nat
hl : r.start ≤ i
b : β
h✝ : ¬i < r.stop
⊢ pure b =
    if r.stop ≤ i then pure b
    else do
      let __do_lift ← f i b
      match __do_lift with
        | ForInStep.done b => pure b
        | ForInStep.yield b => forIn.loop f n✝ (i + r.step) r.stop r.step b
state_after: no goals

tactic: intro L
state_before: case refine_2
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
⊢ ∀ (L : List Nat) (H : ∀ (a : Nat), a ∈ L → a ∈ r),
    (forIn (List.pmap Subtype.mk L H) init fun x => f x.val) = forIn L init f
state_after: case refine_2
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
L : List Nat
⊢ ∀ (H : ∀ (a : Nat), a ∈ L → a ∈ r), (forIn (List.pmap Subtype.mk L H) init fun x => f x.val) = forIn L init f

tactic: induction L generalizing init <;> intro H <;> simp [*]
state_before: case refine_2
m : Type u_1 → Type u_2
β : Type u_1
inst✝ : Monad m
r : Range
init : β
f : Nat → β → m (ForInStep β)
L : List Nat
⊢ ∀ (H : ∀ (a : Nat), a ∈ L → a ∈ r), (forIn (List.pmap Subtype.mk L H) init fun x => f x.val) = forIn L init f
state_after: no goals