Theorem: Array.SatisfiesM_anyM
File: .lake/packages/batteries/Batteries/Data/Array/Monadic.lean

tactic: simp only [Array.anyM_eq_anyM_loop]
state_before: m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop : Nat
hstart : start ≤ min stop as.size
tru : Prop
fal : Nat → Prop
h0 : fal start
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
⊢ SatisfiesM (fun res => bif res then tru else fal (min stop as.size)) (anyM p as start stop)
state_after: m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop : Nat
hstart : start ≤ min stop as.size
tru : Prop
fal : Nat → Prop
h0 : fal start
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
⊢ SatisfiesM (fun res => bif res then tru else fal (min stop as.size)) (anyM.loop p as (min stop as.size) ⋯ start)

tactic: exact go hstart _ h0 fun i hi => hp i <| Nat.lt_of_lt_of_le hi <| Nat.min_le_left ..
state_before: m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop : Nat
hstart : start ≤ min stop as.size
tru : Prop
fal : Nat → Prop
h0 : fal start
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
⊢ SatisfiesM (fun res => bif res then tru else fal (min stop as.size)) (anyM.loop p as (min stop as.size) ⋯ start)
state_after: no goals

tactic: unfold anyM.loop
state_before: m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop✝ : Nat
hstart : start ≤ min stop✝ as.size
tru : Prop
fal : Nat → Prop
h0✝ : fal start
hp✝ : ∀ (i : Fin as.size), ↑i < stop✝ → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
stop j : Nat
hj' : j ≤ stop
hstop : stop ≤ as.size
h0 : fal j
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
⊢ SatisfiesM (fun res => bif res then tru else fal stop) (anyM.loop p as stop hstop j)
state_after: m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop✝ : Nat
hstart : start ≤ min stop✝ as.size
tru : Prop
fal : Nat → Prop
h0✝ : fal start
hp✝ : ∀ (i : Fin as.size), ↑i < stop✝ → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
stop j : Nat
hj' : j ≤ stop
hstop : stop ≤ as.size
h0 : fal j
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
⊢ SatisfiesM (fun res => bif res then tru else fal stop)
    (if hlt : j < stop then
      let_fun this := ⋯;
      do
      let __do_lift ← p as[j]
      if __do_lift = true then pure true else anyM.loop p as stop hstop (j + 1)
    else pure false)

tactic: split
state_before: m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop✝ : Nat
hstart : start ≤ min stop✝ as.size
tru : Prop
fal : Nat → Prop
h0✝ : fal start
hp✝ : ∀ (i : Fin as.size), ↑i < stop✝ → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
stop j : Nat
hj' : j ≤ stop
hstop : stop ≤ as.size
h0 : fal j
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
⊢ SatisfiesM (fun res => bif res then tru else fal stop)
    (if hlt : j < stop then
      let_fun this := ⋯;
      do
      let __do_lift ← p as[j]
      if __do_lift = true then pure true else anyM.loop p as stop hstop (j + 1)
    else pure false)
state_after: case isTrue
m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop✝ : Nat
hstart : start ≤ min stop✝ as.size
tru : Prop
fal : Nat → Prop
h0✝ : fal start
hp✝ : ∀ (i : Fin as.size), ↑i < stop✝ → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
stop j : Nat
hj' : j ≤ stop
hstop : stop ≤ as.size
h0 : fal j
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
h✝ : j < stop
⊢ SatisfiesM (fun res => bif res then tru else fal stop)
    (let_fun this := ⋯;
    do
    let __do_lift ← p as[j]
    if __do_lift = true then pure true else anyM.loop p as stop hstop (j + 1))

case isFalse
m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop✝ : Nat
hstart : start ≤ min stop✝ as.size
tru : Prop
fal : Nat → Prop
h0✝ : fal start
hp✝ : ∀ (i : Fin as.size), ↑i < stop✝ → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
stop j : Nat
hj' : j ≤ stop
hstop : stop ≤ as.size
h0 : fal j
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
h✝ : ¬j < stop
⊢ SatisfiesM (fun res => bif res then tru else fal stop) (pure false)

tactic: next hj =>
exact (hp ⟨j, Nat.lt_of_lt_of_le hj hstop⟩ hj h0).bind fun
  | true, h => .pure h
  | false, h => go hj hstop h hp
state_before: case isTrue
m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop✝ : Nat
hstart : start ≤ min stop✝ as.size
tru : Prop
fal : Nat → Prop
h0✝ : fal start
hp✝ : ∀ (i : Fin as.size), ↑i < stop✝ → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
stop j : Nat
hj' : j ≤ stop
hstop : stop ≤ as.size
h0 : fal j
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
h✝ : j < stop
⊢ SatisfiesM (fun res => bif res then tru else fal stop)
    (let_fun this := ⋯;
    do
    let __do_lift ← p as[j]
    if __do_lift = true then pure true else anyM.loop p as stop hstop (j + 1))
state_after: no goals

tactic: exact (hp ⟨j, Nat.lt_of_lt_of_le hj hstop⟩ hj h0).bind fun
  | true, h => .pure h
  | false, h => go hj hstop h hp
state_before: m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop✝ : Nat
hstart : start ≤ min stop✝ as.size
tru : Prop
fal : Nat → Prop
h0✝ : fal start
hp✝ : ∀ (i : Fin as.size), ↑i < stop✝ → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
stop j : Nat
hj' : j ≤ stop
hstop : stop ≤ as.size
h0 : fal j
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
hj : j < stop
⊢ SatisfiesM (fun res => bif res then tru else fal stop)
    (let_fun this := ⋯;
    do
    let __do_lift ← p as[j]
    if __do_lift = true then pure true else anyM.loop p as stop hstop (j + 1))
state_after: no goals

tactic: next hj => exact .pure <| Nat.le_antisymm hj' (Nat.ge_of_not_lt hj) ▸ h0
state_before: case isFalse
m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop✝ : Nat
hstart : start ≤ min stop✝ as.size
tru : Prop
fal : Nat → Prop
h0✝ : fal start
hp✝ : ∀ (i : Fin as.size), ↑i < stop✝ → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
stop j : Nat
hj' : j ≤ stop
hstop : stop ≤ as.size
h0 : fal j
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
h✝ : ¬j < stop
⊢ SatisfiesM (fun res => bif res then tru else fal stop) (pure false)
state_after: no goals

tactic: exact .pure <| Nat.le_antisymm hj' (Nat.ge_of_not_lt hj) ▸ h0
state_before: m : Type → Type u_1
α : Type u_2
inst✝¹ : Monad m
inst✝ : LawfulMonad m
p : α → m Bool
as : Array α
start stop✝ : Nat
hstart : start ≤ min stop✝ as.size
tru : Prop
fal : Nat → Prop
h0✝ : fal start
hp✝ : ∀ (i : Fin as.size), ↑i < stop✝ → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
stop j : Nat
hj' : j ≤ stop
hstop : stop ≤ as.size
h0 : fal j
hp : ∀ (i : Fin as.size), ↑i < stop → fal ↑i → SatisfiesM (fun x => bif x then tru else fal (↑i + 1)) (p as[i])
hj : ¬j < stop
⊢ SatisfiesM (fun res => bif res then tru else fal stop) (pure false)
state_after: no goals