l3lab/ntp-mathlib huggingface dataset:
/--
  If there is a set of states that is closed under `f`, and such that `f` produces that same output
  for all states in this set, then the state is not actually needed.
  Hence, then we can rewrite `mapAccumr₂` into just `map₂`
-/
theorem mapAccumr₂_eq_map₂ {f : α → β → σ → σ × γ} {s₀ : σ} (S : Set σ) (h₀ : s₀ ∈ S)
    (closure : ∀ a b s, s ∈ S → (f a b s).1 ∈ S)
    (out : ∀ a b s s', s ∈ S → s' ∈ S → (f a b s).2 = (f a b s').2) :
    (mapAccumr₂ f xs ys s₀).snd = map₂ (f · · s₀ |>.snd) xs ys := by
  rw[Vector.map₂_eq_mapAccumr₂]
  apply mapAccumr₂_bisim_tail
  use fun s _ => s ∈ S, h₀
  

Proof state:
case right
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
f : α → β → σ → σ × γ
s₀ : σ
S : Set σ
h₀ : s₀ ∈ S
closure : ∀ (a : α) (b : β), ∀ s ∈ S, (f a b s).1 ∈ S
out : ∀ (a : α) (b : β) (s s' : σ), s ∈ S → s' ∈ S → (f a b s).2 = (f a b s').2
⊢ ∀ {s : σ} {q : Unit} (a : α) (b : β), s ∈ S → (f a b s).1 ∈ S ∧ (f a b s).2 = ((), (f a b s₀).2).2

Next tactic:
exact @fun s _q a b h => ⟨closure a b s h, out a b s s₀ h h₀⟩
/--
  If an accumulation function `f`, given an initial state `s`, produces `s` as its output state
  for all possible input bits, then the state is redundant and can be optimized out
-/
@[simp]
theorem mapAccumr_eq_map_of_constant_state (f : α → σ → σ × β) (s : σ) (h : ∀ a, (f a s).fst = s) :
    mapAccumr f xs s = (s, (map (fun x => (f x s).snd) xs)) := by
  

Proof state:
α : Type u_2
n : ℕ
β : Type u_1
xs : Vector α n
ys : Vector β n
σ : Type
f : α → σ → σ × β
s : σ
h : ∀ (a : α), (f a s).1 = s
⊢ mapAccumr f xs s = (s, map (fun x => (f x s).2) xs)

Next tactic:
clear ys
/--
  If an accumulation function `f`, given an initial state `s`, produces `s` as its output state
  for all possible input bits, then the state is redundant and can be optimized out
-/
@[simp]
theorem mapAccumr_eq_map_of_constant_state (f : α → σ → σ × β) (s : σ) (h : ∀ a, (f a s).fst = s) :
    mapAccumr f xs s = (s, (map (fun x => (f x s).snd) xs)) := by
  clear ys
  

Proof state:
α : Type u_2
n : ℕ
β : Type u_1
xs : Vector α n
σ : Type
f : α → σ → σ × β
s : σ
h : ∀ (a : α), (f a s).1 = s
⊢ mapAccumr f xs s = (s, map (fun x => (f x s).2) xs)

Next tactic:
induction xs using revInductionOn
/--
  If an accumulation function `f`, given an initial state `s`, produces `s` as its output state
  for all possible input bits, then the state is redundant and can be optimized out
-/
@[simp]
theorem mapAccumr_eq_map_of_constant_state (f : α → σ → σ × β) (s : σ) (h : ∀ a, (f a s).fst = s) :
    mapAccumr f xs s = (s, (map (fun x => (f x s).snd) xs)) := by
  clear ys
  induction xs using revInductionOn <;> 

Proof state:
case nil
α : Type u_2
n : ℕ
β : Type u_1
xs : Vector α n
σ : Type
f : α → σ → σ × β
s : σ
h : ∀ (a : α), (f a s).1 = s
⊢ mapAccumr f nil s = (s, map (fun x => (f x s).2) nil)

Next tactic:
simp_all
/--
  If an accumulation function `f`, given an initial state `s`, produces `s` as its output state
  for all possible input bits, then the state is redundant and can be optimized out
-/
@[simp]
theorem mapAccumr_eq_map_of_constant_state (f : α → σ → σ × β) (s : σ) (h : ∀ a, (f a s).fst = s) :
    mapAccumr f xs s = (s, (map (fun x => (f x s).snd) xs)) := by
  clear ys
  induction xs using revInductionOn <;> 

Proof state:
case snoc
α : Type u_2
n : ℕ
β : Type u_1
xs : Vector α n
σ : Type
f : α → σ → σ × β
s : σ
h : ∀ (a : α), (f a s).1 = s
n✝ : ℕ
xs✝ : Vector α n✝
x✝ : α
a✝ : mapAccumr f xs✝ s = (s, map (fun x => (f x s).2) xs✝)
⊢ mapAccumr f (snoc xs✝ x✝) s = (s, map (fun x => (f x s).2) (snoc xs✝ x✝))

Next tactic:
simp_all
/--
  If an accumulation function `f`, given an initial state `s`, produces `s` as its output state
  for all possible input bits, then the state is redundant and can be optimized out
-/
@[simp]
theorem mapAccumr₂_eq_map₂_of_constant_state (f : α → β → σ → σ × γ) (s : σ)
    (h : ∀ a b, (f a b s).fst = s) :
    mapAccumr₂ f xs ys s = (s, (map₂ (fun x y => (f x y s).snd) xs ys)) := by
  

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
f : α → β → σ → σ × γ
s : σ
h : ∀ (a : α) (b : β), (f a b s).1 = s
⊢ mapAccumr₂ f xs ys s = (s, map₂ (fun x y => (f x y s).2) xs ys)

Next tactic:
induction xs, ys using revInductionOn₂
/--
  If an accumulation function `f`, given an initial state `s`, produces `s` as its output state
  for all possible input bits, then the state is redundant and can be optimized out
-/
@[simp]
theorem mapAccumr₂_eq_map₂_of_constant_state (f : α → β → σ → σ × γ) (s : σ)
    (h : ∀ a b, (f a b s).fst = s) :
    mapAccumr₂ f xs ys s = (s, (map₂ (fun x y => (f x y s).snd) xs ys)) := by
  induction xs, ys using revInductionOn₂ <;> 

Proof state:
case nil
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
f : α → β → σ → σ × γ
s : σ
h : ∀ (a : α) (b : β), (f a b s).1 = s
⊢ mapAccumr₂ f nil nil s = (s, map₂ (fun x y => (f x y s).2) nil nil)

Next tactic:
simp_all
/--
  If an accumulation function `f`, given an initial state `s`, produces `s` as its output state
  for all possible input bits, then the state is redundant and can be optimized out
-/
@[simp]
theorem mapAccumr₂_eq_map₂_of_constant_state (f : α → β → σ → σ × γ) (s : σ)
    (h : ∀ a b, (f a b s).fst = s) :
    mapAccumr₂ f xs ys s = (s, (map₂ (fun x y => (f x y s).snd) xs ys)) := by
  induction xs, ys using revInductionOn₂ <;> 

Proof state:
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
f : α → β → σ → σ × γ
s : σ
h : ∀ (a : α) (b : β), (f a b s).1 = s
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ : mapAccumr₂ f xs✝ ys✝ s = (s, map₂ (fun x y => (f x y s).2) xs✝ ys✝)
⊢ mapAccumr₂ f (snoc xs✝ x✝) (snoc ys✝ y✝) s = (s, map₂ (fun x y => (f x y s).2) (snoc xs✝ x✝) (snoc ys✝ y✝))

Next tactic:
simp_all
/-- If `f` takes a pair of states, but always returns the same value for both elements of the
    pair, then we can simplify to just a single element of state
  -/
@[simp]
theorem mapAccumr_redundant_pair (f : α → (σ × σ) → (σ × σ) × β)
    (h : ∀ x s, (f x (s, s)).fst.fst = (f x (s, s)).fst.snd) :
    (mapAccumr f xs (s, s)).snd = (mapAccumr (fun x (s : σ) =>
      (f x (s, s) |>.fst.fst, f x (s, s) |>.snd)
    ) xs s).snd :=
  mapAccumr_bisim_tail <| by
    

Proof state:
α : Type u_2
n : ℕ
β : Type u_1
xs : Vector α n
ys : Vector β n
σ : Type
s : σ
f : α → σ × σ → (σ × σ) × β
h : ∀ (x : α) (s : σ), (f x (s, s)).1.1 = (f x (s, s)).1.2
⊢ ∃ R,
    R (s, s) s ∧
      ∀ {s : σ × σ} {q : σ} (a : α),
        R s q → R (f a s).1 ((f a (q, q)).1.1, (f a (q, q)).2).1 ∧ (f a s).2 = ((f a (q, q)).1.1, (f a (q, q)).2).2

Next tactic:
use fun (s₁, s₂) s => s₂ = s ∧ s₁ = s
/-- If `f` takes a pair of states, but always returns the same value for both elements of the
    pair, then we can simplify to just a single element of state
  -/
@[simp]
theorem mapAccumr_redundant_pair (f : α → (σ × σ) → (σ × σ) × β)
    (h : ∀ x s, (f x (s, s)).fst.fst = (f x (s, s)).fst.snd) :
    (mapAccumr f xs (s, s)).snd = (mapAccumr (fun x (s : σ) =>
      (f x (s, s) |>.fst.fst, f x (s, s) |>.snd)
    ) xs s).snd :=
  mapAccumr_bisim_tail <| by
    use fun (s₁, s₂) s => s₂ = s ∧ s₁ = s
    

Proof state:
case h
α : Type u_2
n : ℕ
β : Type u_1
xs : Vector α n
ys : Vector β n
σ : Type
s : σ
f : α → σ × σ → (σ × σ) × β
h : ∀ (x : α) (s : σ), (f x (s, s)).1.1 = (f x (s, s)).1.2
⊢ (match (s, s) with
    | (s₁, s₂) => s₂ = s ∧ s₁ = s) ∧
    ∀ {s : σ × σ} {q : σ} (a : α),
      (match s with
        | (s₁, s₂) => s₂ = q ∧ s₁ = q) →
        (match (f a s).1 with
          | (s₁, s₂) => s₂ = ((f a (q, q)).1.1, (f a (q, q)).2).1 ∧ s₁ = ((f a (q, q)).1.1, (f a (q, q)).2).1) ∧
          (f a s).2 = ((f a (q, q)).1.1, (f a (q, q)).2).2

Next tactic:
simp_all
/-- If `f` takes a pair of states, but always returns the same value for both elements of the
    pair, then we can simplify to just a single element of state
  -/
@[simp]
theorem mapAccumr₂_redundant_pair (f : α → β → (σ × σ) → (σ × σ) × γ)
    (h : ∀ x y s, let s' := (f x y (s, s)).fst; s'.fst = s'.snd) :
    (mapAccumr₂ f xs ys (s, s)).snd = (mapAccumr₂ (fun x y (s : σ) =>
      (f x y (s, s) |>.fst.fst, f x y (s, s) |>.snd)
    ) xs ys s).snd :=
  mapAccumr₂_bisim_tail <| by
    

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
s : σ
f : α → β → σ × σ → (σ × σ) × γ
h :
  ∀ (x : α) (y : β) (s : σ),
    let s' := (f x y (s, s)).1;
    s'.1 = s'.2
⊢ ∃ R,
    R (s, s) s ∧
      ∀ {s : σ × σ} {q : σ} (a : α) (b : β),
        R s q →
          R (f a b s).1 ((f a b (q, q)).1.1, (f a b (q, q)).2).1 ∧
            (f a b s).2 = ((f a b (q, q)).1.1, (f a b (q, q)).2).2

Next tactic:
use fun (s₁, s₂) s => s₂ = s ∧ s₁ = s
/-- If `f` takes a pair of states, but always returns the same value for both elements of the
    pair, then we can simplify to just a single element of state
  -/
@[simp]
theorem mapAccumr₂_redundant_pair (f : α → β → (σ × σ) → (σ × σ) × γ)
    (h : ∀ x y s, let s' := (f x y (s, s)).fst; s'.fst = s'.snd) :
    (mapAccumr₂ f xs ys (s, s)).snd = (mapAccumr₂ (fun x y (s : σ) =>
      (f x y (s, s) |>.fst.fst, f x y (s, s) |>.snd)
    ) xs ys s).snd :=
  mapAccumr₂_bisim_tail <| by
    use fun (s₁, s₂) s => s₂ = s ∧ s₁ = s
    

Proof state:
case h
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
s : σ
f : α → β → σ × σ → (σ × σ) × γ
h :
  ∀ (x : α) (y : β) (s : σ),
    let s' := (f x y (s, s)).1;
    s'.1 = s'.2
⊢ (match (s, s) with
    | (s₁, s₂) => s₂ = s ∧ s₁ = s) ∧
    ∀ {s : σ × σ} {q : σ} (a : α) (b : β),
      (match s with
        | (s₁, s₂) => s₂ = q ∧ s₁ = q) →
        (match (f a b s).1 with
          | (s₁, s₂) => s₂ = ((f a b (q, q)).1.1, (f a b (q, q)).2).1 ∧ s₁ = ((f a b (q, q)).1.1, (f a b (q, q)).2).1) ∧
          (f a b s).2 = ((f a b (q, q)).1.1, (f a b (q, q)).2).2

Next tactic:
simp_all
/--
  If `f` returns the same output and next state for every value of it's first argument, then
  `xs : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_left [Inhabited α] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f default b s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun b s => f default b s) ys s := by
  

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
s : σ
inst✝ : Inhabited α
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f default b s = f a b s
⊢ mapAccumr₂ f xs ys s = mapAccumr (fun b s => f default b s) ys s

Next tactic:
induction xs, ys using Vector.revInductionOn₂ generalizing s
/--
  If `f` returns the same output and next state for every value of it's first argument, then
  `xs : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_left [Inhabited α] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f default b s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun b s => f default b s) ys s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  

Proof state:
case nil
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
inst✝ : Inhabited α
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f default b s = f a b s
s : σ
⊢ mapAccumr₂ f nil nil s = mapAccumr (fun b s => f default b s) nil s
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
inst✝ : Inhabited α
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f default b s = f a b s
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ : ∀ {s : σ}, mapAccumr₂ f xs✝ ys✝ s = mapAccumr (fun b s => f default b s) ys✝ s
s : σ
⊢ mapAccumr₂ f (snoc xs✝ x✝) (snoc ys✝ y✝) s = mapAccumr (fun b s => f default b s) (snoc ys✝ y✝) s

Next tactic:
case nil => rfl
/--
  If `f` returns the same output and next state for every value of it's first argument, then
  `xs : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_left [Inhabited α] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f default b s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun b s => f default b s) ys s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
inst✝ : Inhabited α
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f default b s = f a b s
s : σ
⊢ mapAccumr₂ f nil nil s = mapAccumr (fun b s => f default b s) nil s

Next tactic:
case nil => rfl
/--
  If `f` returns the same output and next state for every value of it's first argument, then
  `xs : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_left [Inhabited α] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f default b s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun b s => f default b s) ys s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  case nil => 

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
inst✝ : Inhabited α
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f default b s = f a b s
s : σ
⊢ mapAccumr₂ f nil nil s = mapAccumr (fun b s => f default b s) nil s

Next tactic:
rfl
/--
  If `f` returns the same output and next state for every value of it's first argument, then
  `xs : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_left [Inhabited α] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f default b s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun b s => f default b s) ys s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  case nil => rfl
  

Proof state:
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
inst✝ : Inhabited α
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f default b s = f a b s
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ : ∀ {s : σ}, mapAccumr₂ f xs✝ ys✝ s = mapAccumr (fun b s => f default b s) ys✝ s
s : σ
⊢ mapAccumr₂ f (snoc xs✝ x✝) (snoc ys✝ y✝) s = mapAccumr (fun b s => f default b s) (snoc ys✝ y✝) s

Next tactic:
case snoc xs ys x y ih =>
    simp[h x y s, ih]
/--
  If `f` returns the same output and next state for every value of it's first argument, then
  `xs : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_left [Inhabited α] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f default b s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun b s => f default b s) ys s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  case nil => rfl
  

Proof state:
α : Type
n : ℕ
β : Type
xs✝ : Vector α n
ys✝ : Vector β n
σ γ : Type
inst✝ : Inhabited α
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f default b s = f a b s
n✝ : ℕ
xs : Vector α n✝
ys : Vector β n✝
x : α
y : β
ih : ∀ {s : σ}, mapAccumr₂ f xs ys s = mapAccumr (fun b s => f default b s) ys s
s : σ
⊢ mapAccumr₂ f (snoc xs x) (snoc ys y) s = mapAccumr (fun b s => f default b s) (snoc ys y) s

Next tactic:
case snoc xs ys x y ih =>
    simp[h x y s, ih]
/--
  If `f` returns the same output and next state for every value of it's first argument, then
  `xs : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_left [Inhabited α] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f default b s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun b s => f default b s) ys s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  case nil => rfl
  case snoc xs ys x y ih =>
    

Proof state:
α : Type
n : ℕ
β : Type
xs✝ : Vector α n
ys✝ : Vector β n
σ γ : Type
inst✝ : Inhabited α
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f default b s = f a b s
n✝ : ℕ
xs : Vector α n✝
ys : Vector β n✝
x : α
y : β
ih : ∀ {s : σ}, mapAccumr₂ f xs ys s = mapAccumr (fun b s => f default b s) ys s
s : σ
⊢ mapAccumr₂ f (snoc xs x) (snoc ys y) s = mapAccumr (fun b s => f default b s) (snoc ys y) s

Next tactic:
simp[h x y s, ih]
/--
  If `f` returns the same output and next state for every value of it's second argument, then
  `ys : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_right [Inhabited β] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f a default s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun a s => f a default s) xs s := by
  

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
s : σ
inst✝ : Inhabited β
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f a default s = f a b s
⊢ mapAccumr₂ f xs ys s = mapAccumr (fun a s => f a default s) xs s

Next tactic:
induction xs, ys using Vector.revInductionOn₂ generalizing s
/--
  If `f` returns the same output and next state for every value of it's second argument, then
  `ys : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_right [Inhabited β] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f a default s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun a s => f a default s) xs s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  

Proof state:
case nil
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
inst✝ : Inhabited β
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f a default s = f a b s
s : σ
⊢ mapAccumr₂ f nil nil s = mapAccumr (fun a s => f a default s) nil s
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
inst✝ : Inhabited β
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f a default s = f a b s
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ : ∀ {s : σ}, mapAccumr₂ f xs✝ ys✝ s = mapAccumr (fun a s => f a default s) xs✝ s
s : σ
⊢ mapAccumr₂ f (snoc xs✝ x✝) (snoc ys✝ y✝) s = mapAccumr (fun a s => f a default s) (snoc xs✝ x✝) s

Next tactic:
case nil => rfl
/--
  If `f` returns the same output and next state for every value of it's second argument, then
  `ys : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_right [Inhabited β] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f a default s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun a s => f a default s) xs s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
inst✝ : Inhabited β
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f a default s = f a b s
s : σ
⊢ mapAccumr₂ f nil nil s = mapAccumr (fun a s => f a default s) nil s

Next tactic:
case nil => rfl
/--
  If `f` returns the same output and next state for every value of it's second argument, then
  `ys : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_right [Inhabited β] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f a default s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun a s => f a default s) xs s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  case nil => 

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
inst✝ : Inhabited β
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f a default s = f a b s
s : σ
⊢ mapAccumr₂ f nil nil s = mapAccumr (fun a s => f a default s) nil s

Next tactic:
rfl
/--
  If `f` returns the same output and next state for every value of it's second argument, then
  `ys : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_right [Inhabited β] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f a default s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun a s => f a default s) xs s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  case nil => rfl
  

Proof state:
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
σ γ : Type
inst✝ : Inhabited β
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f a default s = f a b s
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ : ∀ {s : σ}, mapAccumr₂ f xs✝ ys✝ s = mapAccumr (fun a s => f a default s) xs✝ s
s : σ
⊢ mapAccumr₂ f (snoc xs✝ x✝) (snoc ys✝ y✝) s = mapAccumr (fun a s => f a default s) (snoc xs✝ x✝) s

Next tactic:
case snoc xs ys x y ih =>
    simp[h x y s, ih]
/--
  If `f` returns the same output and next state for every value of it's second argument, then
  `ys : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_right [Inhabited β] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f a default s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun a s => f a default s) xs s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  case nil => rfl
  

Proof state:
α : Type
n : ℕ
β : Type
xs✝ : Vector α n
ys✝ : Vector β n
σ γ : Type
inst✝ : Inhabited β
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f a default s = f a b s
n✝ : ℕ
xs : Vector α n✝
ys : Vector β n✝
x : α
y : β
ih : ∀ {s : σ}, mapAccumr₂ f xs ys s = mapAccumr (fun a s => f a default s) xs s
s : σ
⊢ mapAccumr₂ f (snoc xs x) (snoc ys y) s = mapAccumr (fun a s => f a default s) (snoc xs x) s

Next tactic:
case snoc xs ys x y ih =>
    simp[h x y s, ih]
/--
  If `f` returns the same output and next state for every value of it's second argument, then
  `ys : Vector` is ignored, and we can rewrite `mapAccumr₂` into `map`
-/
@[simp]
theorem mapAccumr₂_unused_input_right [Inhabited β] (f : α → β → σ → σ × γ)
    (h : ∀ a b s, f a default s = f a b s) :
    mapAccumr₂ f xs ys s = mapAccumr (fun a s => f a default s) xs s := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s
  case nil => rfl
  case snoc xs ys x y ih =>
    

Proof state:
α : Type
n : ℕ
β : Type
xs✝ : Vector α n
ys✝ : Vector β n
σ γ : Type
inst✝ : Inhabited β
f : α → β → σ → σ × γ
h : ∀ (a : α) (b : β) (s : σ), f a default s = f a b s
n✝ : ℕ
xs : Vector α n✝
ys : Vector β n✝
x : α
y : β
ih : ∀ {s : σ}, mapAccumr₂ f xs ys s = mapAccumr (fun a s => f a default s) xs s
s : σ
⊢ mapAccumr₂ f (snoc xs x) (snoc ys y) s = mapAccumr (fun a s => f a default s) (snoc xs x) s

Next tactic:
simp[h x y s, ih]
theorem map₂_comm (f : α → α → β) (comm : ∀ a₁ a₂, f a₁ a₂ = f a₂ a₁) :
    map₂ f xs ys = map₂ f ys xs := by
  

Proof state:
α : Type u_2
n : ℕ
xs ys : Vector α n
β : Type u_1
f : α → α → β
comm : ∀ (a₁ a₂ : α), f a₁ a₂ = f a₂ a₁
⊢ map₂ f xs ys = map₂ f ys xs

Next tactic:
induction xs, ys using Vector.inductionOn₂
theorem map₂_comm (f : α → α → β) (comm : ∀ a₁ a₂, f a₁ a₂ = f a₂ a₁) :
    map₂ f xs ys = map₂ f ys xs := by
  induction xs, ys using Vector.inductionOn₂ <;> 

Proof state:
case nil
α : Type u_2
n : ℕ
xs ys : Vector α n
β : Type u_1
f : α → α → β
comm : ∀ (a₁ a₂ : α), f a₁ a₂ = f a₂ a₁
⊢ map₂ f nil nil = map₂ f nil nil

Next tactic:
simp_all
theorem map₂_comm (f : α → α → β) (comm : ∀ a₁ a₂, f a₁ a₂ = f a₂ a₁) :
    map₂ f xs ys = map₂ f ys xs := by
  induction xs, ys using Vector.inductionOn₂ <;> 

Proof state:
case cons
α : Type u_2
n : ℕ
xs ys : Vector α n
β : Type u_1
f : α → α → β
comm : ∀ (a₁ a₂ : α), f a₁ a₂ = f a₂ a₁
n✝ : ℕ
a✝¹ b✝ : α
x✝ y✝ : Vector α n✝
a✝ : map₂ f x✝ y✝ = map₂ f y✝ x✝
⊢ map₂ f (a✝¹ ::ᵥ x✝) (b✝ ::ᵥ y✝) = map₂ f (b✝ ::ᵥ y✝) (a✝¹ ::ᵥ x✝)

Next tactic:
simp_all
theorem mapAccumr₂_comm (f : α → α → σ → σ × γ) (comm : ∀ a₁ a₂ s, f a₁ a₂ s = f a₂ a₁ s) :
    mapAccumr₂ f xs ys s = mapAccumr₂ f ys xs s := by
  

Proof state:
α : Type
n : ℕ
xs ys : Vector α n
σ γ : Type
s : σ
f : α → α → σ → σ × γ
comm : ∀ (a₁ a₂ : α) (s : σ), f a₁ a₂ s = f a₂ a₁ s
⊢ mapAccumr₂ f xs ys s = mapAccumr₂ f ys xs s

Next tactic:
induction xs, ys using Vector.inductionOn₂ generalizing s
theorem mapAccumr₂_comm (f : α → α → σ → σ × γ) (comm : ∀ a₁ a₂ s, f a₁ a₂ s = f a₂ a₁ s) :
    mapAccumr₂ f xs ys s = mapAccumr₂ f ys xs s := by
  induction xs, ys using Vector.inductionOn₂ generalizing s <;> 

Proof state:
case nil
α : Type
n : ℕ
xs ys : Vector α n
σ γ : Type
f : α → α → σ → σ × γ
comm : ∀ (a₁ a₂ : α) (s : σ), f a₁ a₂ s = f a₂ a₁ s
s : σ
⊢ mapAccumr₂ f nil nil s = mapAccumr₂ f nil nil s

Next tactic:
simp_all