l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem mapAccumr₂_mapAccumr_right (f₁ : α → γ → σ₁ → σ₁ × ζ) (f₂ : β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ xs (mapAccumr f₂ ys s₂).snd s₁)
    = let m := (mapAccumr₂ (fun x y s =>
          let r₂ := f₂ y s.snd
          let r₁ := f₁ x r₂.snd s.fst
          ((r₁.fst, r₂.fst), r₁.snd)
        ) xs ys (s₁, s₂))
      (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ ζ σ₂ : Type
f₁ : α → γ → σ₁ → σ₁ × ζ
f₂ : β → σ₂ → σ₂ × γ
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ :
  ∀ {s₂ : σ₂} {s₁ : σ₁},
    mapAccumr₂ f₁ xs✝ (mapAccumr f₂ ys✝ s₂).2 s₁ =
      let m :=
        mapAccumr₂
          (fun x y s =>
            let r₂ := f₂ y s.2;
            let r₁ := f₁ x r₂.2 s.1;
            ((r₁.1, r₂.1), r₁.2))
          xs✝ ys✝ (s₁, s₂);
      (m.1.1, m.2)
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr₂ f₁ (snoc xs✝ x✝) (mapAccumr f₂ (snoc ys✝ y✝) s₂).2 s₁ =
    let m :=
      mapAccumr₂
        (fun x y s =>
          let r₂ := f₂ y s.2;
          let r₁ := f₁ x r₂.2 s.1;
          ((r₁.1, r₂.1), r₁.2))
        (snoc xs✝ x✝) (snoc ys✝ y✝) (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
@[simp]
theorem map₂_map_right (f₁ : α → γ → ζ) (f₂ : β → γ) :
    map₂ f₁ xs (map f₂ ys) = map₂ (fun x y => f₁ x (f₂ y)) xs ys := by
  

Proof state:
α : Type u_3
n : ℕ
β : Type u_4
xs : Vector α n
ys : Vector β n
γ : Type u_1
ζ : Type u_2
f₁ : α → γ → ζ
f₂ : β → γ
⊢ map₂ f₁ xs (map f₂ ys) = map₂ (fun x y => f₁ x (f₂ y)) xs ys

Next tactic:
induction xs, ys using Vector.revInductionOn₂
@[simp]
theorem map₂_map_right (f₁ : α → γ → ζ) (f₂ : β → γ) :
    map₂ f₁ xs (map f₂ ys) = map₂ (fun x y => f₁ x (f₂ y)) xs ys := by
  induction xs, ys using Vector.revInductionOn₂ <;> 

Proof state:
case nil
α : Type u_3
n : ℕ
β : Type u_4
xs : Vector α n
ys : Vector β n
γ : Type u_1
ζ : Type u_2
f₁ : α → γ → ζ
f₂ : β → γ
⊢ map₂ f₁ nil (map f₂ nil) = map₂ (fun x y => f₁ x (f₂ y)) nil nil

Next tactic:
simp_all
@[simp]
theorem map₂_map_right (f₁ : α → γ → ζ) (f₂ : β → γ) :
    map₂ f₁ xs (map f₂ ys) = map₂ (fun x y => f₁ x (f₂ y)) xs ys := by
  induction xs, ys using Vector.revInductionOn₂ <;> 

Proof state:
case snoc
α : Type u_3
n : ℕ
β : Type u_4
xs : Vector α n
ys : Vector β n
γ : Type u_1
ζ : Type u_2
f₁ : α → γ → ζ
f₂ : β → γ
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ : map₂ f₁ xs✝ (map f₂ ys✝) = map₂ (fun x y => f₁ x (f₂ y)) xs✝ ys✝
⊢ map₂ f₁ (snoc xs✝ x✝) (map f₂ (snoc ys✝ y✝)) = map₂ (fun x y => f₁ x (f₂ y)) (snoc xs✝ x✝) (snoc ys✝ y✝)

Next tactic:
simp_all
@[simp]
theorem mapAccumr_mapAccumr₂ (f₁ : γ → σ₁ → σ₁ × ζ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr f₁ (mapAccumr₂ f₂ xs ys s₂).snd s₁)
    = let m := mapAccumr₂ (fun x y s =>
          let r₂ := f₂ x y s.snd
          let r₁ := f₁ r₂.snd s.fst
          ((r₁.fst, r₂.fst), r₁.snd)
        ) xs ys (s₁, s₂)
      (m.fst.fst, m.snd) := by
  

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ ζ σ₂ : Type
s₂ : σ₂
s₁ : σ₁
f₁ : γ → σ₁ → σ₁ × ζ
f₂ : α → β → σ₂ → σ₂ × γ
⊢ mapAccumr f₁ (mapAccumr₂ f₂ xs ys s₂).2 s₁ =
    let m :=
      mapAccumr₂
        (fun x y s =>
          let r₂ := f₂ x y s.2;
          let r₁ := f₁ r₂.2 s.1;
          ((r₁.1, r₂.1), r₁.2))
        xs ys (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂
@[simp]
theorem mapAccumr_mapAccumr₂ (f₁ : γ → σ₁ → σ₁ × ζ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr f₁ (mapAccumr₂ f₂ xs ys s₂).snd s₁)
    = let m := mapAccumr₂ (fun x y s =>
          let r₂ := f₂ x y s.snd
          let r₁ := f₁ r₂.snd s.fst
          ((r₁.fst, r₂.fst), r₁.snd)
        ) xs ys (s₁, s₂)
      (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case nil
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ ζ σ₂ : Type
f₁ : γ → σ₁ → σ₁ × ζ
f₂ : α → β → σ₂ → σ₂ × γ
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr f₁ (mapAccumr₂ f₂ nil nil s₂).2 s₁ =
    let m :=
      mapAccumr₂
        (fun x y s =>
          let r₂ := f₂ x y s.2;
          let r₁ := f₁ r₂.2 s.1;
          ((r₁.1, r₂.1), r₁.2))
        nil nil (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
@[simp]
theorem mapAccumr_mapAccumr₂ (f₁ : γ → σ₁ → σ₁ × ζ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr f₁ (mapAccumr₂ f₂ xs ys s₂).snd s₁)
    = let m := mapAccumr₂ (fun x y s =>
          let r₂ := f₂ x y s.snd
          let r₁ := f₁ r₂.snd s.fst
          ((r₁.fst, r₂.fst), r₁.snd)
        ) xs ys (s₁, s₂)
      (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ ζ σ₂ : Type
f₁ : γ → σ₁ → σ₁ × ζ
f₂ : α → β → σ₂ → σ₂ × γ
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ :
  ∀ {s₂ : σ₂} {s₁ : σ₁},
    mapAccumr f₁ (mapAccumr₂ f₂ xs✝ ys✝ s₂).2 s₁ =
      let m :=
        mapAccumr₂
          (fun x y s =>
            let r₂ := f₂ x y s.2;
            let r₁ := f₁ r₂.2 s.1;
            ((r₁.1, r₂.1), r₁.2))
          xs✝ ys✝ (s₁, s₂);
      (m.1.1, m.2)
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr f₁ (mapAccumr₂ f₂ (snoc xs✝ x✝) (snoc ys✝ y✝) s₂).2 s₁ =
    let m :=
      mapAccumr₂
        (fun x y s =>
          let r₂ := f₂ x y s.2;
          let r₁ := f₁ r₂.2 s.1;
          ((r₁.1, r₂.1), r₁.2))
        (snoc xs✝ x✝) (snoc ys✝ y✝) (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
@[simp]
theorem map_map₂ (f₁ : γ → ζ) (f₂ : α → β → γ) :
    map f₁ (map₂ f₂ xs ys) = map₂ (fun x y => f₁ <| f₂ x y) xs ys := by
  

Proof state:
α : Type u_3
n : ℕ
β : Type u_4
xs : Vector α n
ys : Vector β n
γ : Type u_1
ζ : Type u_2
f₁ : γ → ζ
f₂ : α → β → γ
⊢ map f₁ (map₂ f₂ xs ys) = map₂ (fun x y => f₁ (f₂ x y)) xs ys

Next tactic:
induction xs, ys using Vector.revInductionOn₂
@[simp]
theorem map_map₂ (f₁ : γ → ζ) (f₂ : α → β → γ) :
    map f₁ (map₂ f₂ xs ys) = map₂ (fun x y => f₁ <| f₂ x y) xs ys := by
  induction xs, ys using Vector.revInductionOn₂ <;> 

Proof state:
case nil
α : Type u_3
n : ℕ
β : Type u_4
xs : Vector α n
ys : Vector β n
γ : Type u_1
ζ : Type u_2
f₁ : γ → ζ
f₂ : α → β → γ
⊢ map f₁ (map₂ f₂ nil nil) = map₂ (fun x y => f₁ (f₂ x y)) nil nil

Next tactic:
simp_all
@[simp]
theorem map_map₂ (f₁ : γ → ζ) (f₂ : α → β → γ) :
    map f₁ (map₂ f₂ xs ys) = map₂ (fun x y => f₁ <| f₂ x y) xs ys := by
  induction xs, ys using Vector.revInductionOn₂ <;> 

Proof state:
case snoc
α : Type u_3
n : ℕ
β : Type u_4
xs : Vector α n
ys : Vector β n
γ : Type u_1
ζ : Type u_2
f₁ : γ → ζ
f₂ : α → β → γ
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ : map f₁ (map₂ f₂ xs✝ ys✝) = map₂ (fun x y => f₁ (f₂ x y)) xs✝ ys✝
⊢ map f₁ (map₂ f₂ (snoc xs✝ x✝) (snoc ys✝ y✝)) = map₂ (fun x y => f₁ (f₂ x y)) (snoc xs✝ x✝) (snoc ys✝ y✝)

Next tactic:
simp_all
@[simp]
theorem mapAccumr₂_mapAccumr₂_left_left (f₁ : γ → α → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ (mapAccumr₂ f₂ xs ys s₂).snd xs s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ r₂.snd x s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
s₂ : σ₂
s₁ : σ₁
f₁ : γ → α → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
⊢ mapAccumr₂ f₁ (mapAccumr₂ f₂ xs ys s₂).2 xs s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ r₂.2 x s₁;
            ((r₁.1, r₂.1), r₁.2))
        xs ys (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂
@[simp]
theorem mapAccumr₂_mapAccumr₂_left_left (f₁ : γ → α → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ (mapAccumr₂ f₂ xs ys s₂).snd xs s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ r₂.snd x s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case nil
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
f₁ : γ → α → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr₂ f₁ (mapAccumr₂ f₂ nil nil s₂).2 nil s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ r₂.2 x s₁;
            ((r₁.1, r₂.1), r₁.2))
        nil nil (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
@[simp]
theorem mapAccumr₂_mapAccumr₂_left_left (f₁ : γ → α → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ (mapAccumr₂ f₂ xs ys s₂).snd xs s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ r₂.snd x s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
f₁ : γ → α → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ :
  ∀ {s₂ : σ₂} {s₁ : σ₁},
    mapAccumr₂ f₁ (mapAccumr₂ f₂ xs✝ ys✝ s₂).2 xs✝ s₁ =
      let m :=
        mapAccumr₂
          (fun x y x_1 =>
            match x_1 with
            | (s₁, s₂) =>
              let r₂ := f₂ x y s₂;
              let r₁ := f₁ r₂.2 x s₁;
              ((r₁.1, r₂.1), r₁.2))
          xs✝ ys✝ (s₁, s₂);
      (m.1.1, m.2)
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr₂ f₁ (mapAccumr₂ f₂ (snoc xs✝ x✝) (snoc ys✝ y✝) s₂).2 (snoc xs✝ x✝) s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ r₂.2 x s₁;
            ((r₁.1, r₂.1), r₁.2))
        (snoc xs✝ x✝) (snoc ys✝ y✝) (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
@[simp]
theorem mapAccumr₂_mapAccumr₂_left_right
    (f₁ : γ → β → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ (mapAccumr₂ f₂ xs ys s₂).snd ys s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ r₂.snd y s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
s₂ : σ₂
s₁ : σ₁
f₁ : γ → β → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
⊢ mapAccumr₂ f₁ (mapAccumr₂ f₂ xs ys s₂).2 ys s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ r₂.2 y s₁;
            ((r₁.1, r₂.1), r₁.2))
        xs ys (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂
@[simp]
theorem mapAccumr₂_mapAccumr₂_left_right
    (f₁ : γ → β → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ (mapAccumr₂ f₂ xs ys s₂).snd ys s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ r₂.snd y s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case nil
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
f₁ : γ → β → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr₂ f₁ (mapAccumr₂ f₂ nil nil s₂).2 nil s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ r₂.2 y s₁;
            ((r₁.1, r₂.1), r₁.2))
        nil nil (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
@[simp]
theorem mapAccumr₂_mapAccumr₂_left_right
    (f₁ : γ → β → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ (mapAccumr₂ f₂ xs ys s₂).snd ys s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ r₂.snd y s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
f₁ : γ → β → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ :
  ∀ {s₂ : σ₂} {s₁ : σ₁},
    mapAccumr₂ f₁ (mapAccumr₂ f₂ xs✝ ys✝ s₂).2 ys✝ s₁ =
      let m :=
        mapAccumr₂
          (fun x y x_1 =>
            match x_1 with
            | (s₁, s₂) =>
              let r₂ := f₂ x y s₂;
              let r₁ := f₁ r₂.2 y s₁;
              ((r₁.1, r₂.1), r₁.2))
          xs✝ ys✝ (s₁, s₂);
      (m.1.1, m.2)
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr₂ f₁ (mapAccumr₂ f₂ (snoc xs✝ x✝) (snoc ys✝ y✝) s₂).2 (snoc ys✝ y✝) s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ r₂.2 y s₁;
            ((r₁.1, r₂.1), r₁.2))
        (snoc xs✝ x✝) (snoc ys✝ y✝) (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
@[simp]
theorem mapAccumr₂_mapAccumr₂_right_left (f₁ : α → γ → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ xs (mapAccumr₂ f₂ xs ys s₂).snd s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ x r₂.snd s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
s₂ : σ₂
s₁ : σ₁
f₁ : α → γ → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
⊢ mapAccumr₂ f₁ xs (mapAccumr₂ f₂ xs ys s₂).2 s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ x r₂.2 s₁;
            ((r₁.1, r₂.1), r₁.2))
        xs ys (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂
@[simp]
theorem mapAccumr₂_mapAccumr₂_right_left (f₁ : α → γ → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ xs (mapAccumr₂ f₂ xs ys s₂).snd s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ x r₂.snd s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case nil
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
f₁ : α → γ → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr₂ f₁ nil (mapAccumr₂ f₂ nil nil s₂).2 s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ x r₂.2 s₁;
            ((r₁.1, r₂.1), r₁.2))
        nil nil (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
@[simp]
theorem mapAccumr₂_mapAccumr₂_right_left (f₁ : α → γ → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ xs (mapAccumr₂ f₂ xs ys s₂).snd s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ x r₂.snd s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
f₁ : α → γ → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ :
  ∀ {s₂ : σ₂} {s₁ : σ₁},
    mapAccumr₂ f₁ xs✝ (mapAccumr₂ f₂ xs✝ ys✝ s₂).2 s₁ =
      let m :=
        mapAccumr₂
          (fun x y x_1 =>
            match x_1 with
            | (s₁, s₂) =>
              let r₂ := f₂ x y s₂;
              let r₁ := f₁ x r₂.2 s₁;
              ((r₁.1, r₂.1), r₁.2))
          xs✝ ys✝ (s₁, s₂);
      (m.1.1, m.2)
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr₂ f₁ (snoc xs✝ x✝) (mapAccumr₂ f₂ (snoc xs✝ x✝) (snoc ys✝ y✝) s₂).2 s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ x r₂.2 s₁;
            ((r₁.1, r₂.1), r₁.2))
        (snoc xs✝ x✝) (snoc ys✝ y✝) (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
@[simp]
theorem mapAccumr₂_mapAccumr₂_right_right (f₁ : β → γ → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ ys (mapAccumr₂ f₂ xs ys s₂).snd s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ y r₂.snd s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  

Proof state:
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
s₂ : σ₂
s₁ : σ₁
f₁ : β → γ → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
⊢ mapAccumr₂ f₁ ys (mapAccumr₂ f₂ xs ys s₂).2 s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ y r₂.2 s₁;
            ((r₁.1, r₂.1), r₁.2))
        xs ys (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂
@[simp]
theorem mapAccumr₂_mapAccumr₂_right_right (f₁ : β → γ → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ ys (mapAccumr₂ f₂ xs ys s₂).snd s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ y r₂.snd s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case nil
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
f₁ : β → γ → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr₂ f₁ nil (mapAccumr₂ f₂ nil nil s₂).2 s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ y r₂.2 s₁;
            ((r₁.1, r₂.1), r₁.2))
        nil nil (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
@[simp]
theorem mapAccumr₂_mapAccumr₂_right_right (f₁ : β → γ → σ₁ → σ₁ × φ) (f₂ : α → β → σ₂ → σ₂ × γ) :
    (mapAccumr₂ f₁ ys (mapAccumr₂ f₂ xs ys s₂).snd s₁)
    = let m := mapAccumr₂ (fun x y (s₁, s₂) =>
                let r₂ := f₂ x y s₂
                let r₁ := f₁ y r₂.snd s₁
                ((r₁.fst, r₂.fst), r₁.snd)
              )
            xs ys (s₁, s₂)
    (m.fst.fst, m.snd) := by
  induction xs, ys using Vector.revInductionOn₂ generalizing s₁ s₂ <;> 

Proof state:
case snoc
α : Type
n : ℕ
β : Type
xs : Vector α n
ys : Vector β n
γ σ₁ φ σ₂ : Type
f₁ : β → γ → σ₁ → σ₁ × φ
f₂ : α → β → σ₂ → σ₂ × γ
n✝ : ℕ
xs✝ : Vector α n✝
ys✝ : Vector β n✝
x✝ : α
y✝ : β
a✝ :
  ∀ {s₂ : σ₂} {s₁ : σ₁},
    mapAccumr₂ f₁ ys✝ (mapAccumr₂ f₂ xs✝ ys✝ s₂).2 s₁ =
      let m :=
        mapAccumr₂
          (fun x y x_1 =>
            match x_1 with
            | (s₁, s₂) =>
              let r₂ := f₂ x y s₂;
              let r₁ := f₁ y r₂.2 s₁;
              ((r₁.1, r₂.1), r₁.2))
          xs✝ ys✝ (s₁, s₂);
      (m.1.1, m.2)
s₂ : σ₂
s₁ : σ₁
⊢ mapAccumr₂ f₁ (snoc ys✝ y✝) (mapAccumr₂ f₂ (snoc xs✝ x✝) (snoc ys✝ y✝) s₂).2 s₁ =
    let m :=
      mapAccumr₂
        (fun x y x_1 =>
          match x_1 with
          | (s₁, s₂) =>
            let r₂ := f₂ x y s₂;
            let r₁ := f₁ y r₂.2 s₁;
            ((r₁.1, r₂.1), r₁.2))
        (snoc xs✝ x✝) (snoc ys✝ y✝) (s₁, s₂);
    (m.1.1, m.2)

Next tactic:
simp_all
theorem mapAccumr_bisim {f₁ : α → σ₁ → σ₁ × β} {f₂ : α → σ₂ → σ₂ × β} {s₁ : σ₁} {s₂ : σ₂}
    (R : σ₁ → σ₂ → Prop) (h₀ : R s₁ s₂)
    (hR : ∀ {s q} a, R s q → R (f₁ a s).1 (f₂ a q).1 ∧ (f₁ a s).2 = (f₂ a q).2) :
    R (mapAccumr f₁ xs s₁).fst (mapAccumr f₂ xs s₂).fst
    ∧ (mapAccumr f₁ xs s₁).snd = (mapAccumr f₂ xs s₂).snd := by
  

Proof state:
α : Type u_2
n : ℕ
xs : Vector α n
σ₁ : Type
β : Type u_1
σ₂ : Type
f₁ : α → σ₁ → σ₁ × β
f₂ : α → σ₂ → σ₂ × β
s₁ : σ₁
s₂ : σ₂
R : σ₁ → σ₂ → Prop
h₀ : R s₁ s₂
hR : ∀ {s : σ₁} {q : σ₂} (a : α), R s q → R (f₁ a s).1 (f₂ a q).1 ∧ (f₁ a s).2 = (f₂ a q).2
⊢ R (mapAccumr f₁ xs s₁).1 (mapAccumr f₂ xs s₂).1 ∧ (mapAccumr f₁ xs s₁).2 = (mapAccumr f₂ xs s₂).2

Next tactic:
induction xs using Vector.revInductionOn generalizing s₁ s₂
theorem mapAccumr_bisim {f₁ : α → σ₁ → σ₁ × β} {f₂ : α → σ₂ → σ₂ × β} {s₁ : σ₁} {s₂ : σ₂}
    (R : σ₁ → σ₂ → Prop) (h₀ : R s₁ s₂)
    (hR : ∀ {s q} a, R s q → R (f₁ a s).1 (f₂ a q).1 ∧ (f₁ a s).2 = (f₂ a q).2) :
    R (mapAccumr f₁ xs s₁).fst (mapAccumr f₂ xs s₂).fst
    ∧ (mapAccumr f₁ xs s₁).snd = (mapAccumr f₂ xs s₂).snd := by
  induction xs using Vector.revInductionOn generalizing s₁ s₂
  

Proof state:
case nil
α : Type u_2
n : ℕ
xs : Vector α n
σ₁ : Type
β : Type u_1
σ₂ : Type
f₁ : α → σ₁ → σ₁ × β
f₂ : α → σ₂ → σ₂ × β
R : σ₁ → σ₂ → Prop
hR : ∀ {s : σ₁} {q : σ₂} (a : α), R s q → R (f₁ a s).1 (f₂ a q).1 ∧ (f₁ a s).2 = (f₂ a q).2
s₁ : σ₁
s₂ : σ₂
h₀ : R s₁ s₂
⊢ R (mapAccumr f₁ nil s₁).1 (mapAccumr f₂ nil s₂).1 ∧ (mapAccumr f₁ nil s₁).2 = (mapAccumr f₂ nil s₂).2
case snoc
α : Type u_2
n : ℕ
xs : Vector α n
σ₁ : Type
β : Type u_1
σ₂ : Type
f₁ : α → σ₁ → σ₁ × β
f₂ : α → σ₂ → σ₂ × β
R : σ₁ → σ₂ → Prop
hR : ∀ {s : σ₁} {q : σ₂} (a : α), R s q → R (f₁ a s).1 (f₂ a q).1 ∧ (f₁ a s).2 = (f₂ a q).2
n✝ : ℕ
xs✝ : Vector α n✝
x✝ : α
a✝ :
  ∀ {s₁ : σ₁} {s₂ : σ₂},
    R s₁ s₂ → R (mapAccumr f₁ xs✝ s₁).1 (mapAccumr f₂ xs✝ s₂).1 ∧ (mapAccumr f₁ xs✝ s₁).2 = (mapAccumr f₂ xs✝ s₂).2
s₁ : σ₁
s₂ : σ₂
h₀ : R s₁ s₂
⊢ R (mapAccumr f₁ (snoc xs✝ x✝) s₁).1 (mapAccumr f₂ (snoc xs✝ x✝) s₂).1 ∧
    (mapAccumr f₁ (snoc xs✝ x✝) s₁).2 = (mapAccumr f₂ (snoc xs✝ x✝) s₂).2

Next tactic:
next => exact ⟨h₀, rfl⟩
theorem mapAccumr_bisim {f₁ : α → σ₁ → σ₁ × β} {f₂ : α → σ₂ → σ₂ × β} {s₁ : σ₁} {s₂ : σ₂}
    (R : σ₁ → σ₂ → Prop) (h₀ : R s₁ s₂)
    (hR : ∀ {s q} a, R s q → R (f₁ a s).1 (f₂ a q).1 ∧ (f₁ a s).2 = (f₂ a q).2) :
    R (mapAccumr f₁ xs s₁).fst (mapAccumr f₂ xs s₂).fst
    ∧ (mapAccumr f₁ xs s₁).snd = (mapAccumr f₂ xs s₂).snd := by
  induction xs using Vector.revInductionOn generalizing s₁ s₂
  next => 

Proof state:
α : Type u_2
n : ℕ
xs : Vector α n
σ₁ : Type
β : Type u_1
σ₂ : Type
f₁ : α → σ₁ → σ₁ × β
f₂ : α → σ₂ → σ₂ × β
R : σ₁ → σ₂ → Prop
hR : ∀ {s : σ₁} {q : σ₂} (a : α), R s q → R (f₁ a s).1 (f₂ a q).1 ∧ (f₁ a s).2 = (f₂ a q).2
s₁ : σ₁
s₂ : σ₂
h₀ : R s₁ s₂
⊢ R (mapAccumr f₁ nil s₁).1 (mapAccumr f₂ nil s₂).1 ∧ (mapAccumr f₁ nil s₁).2 = (mapAccumr f₂ nil s₂).2

Next tactic:
exact ⟨h₀, rfl⟩
theorem mapAccumr_bisim {f₁ : α → σ₁ → σ₁ × β} {f₂ : α → σ₂ → σ₂ × β} {s₁ : σ₁} {s₂ : σ₂}
    (R : σ₁ → σ₂ → Prop) (h₀ : R s₁ s₂)
    (hR : ∀ {s q} a, R s q → R (f₁ a s).1 (f₂ a q).1 ∧ (f₁ a s).2 = (f₂ a q).2) :
    R (mapAccumr f₁ xs s₁).fst (mapAccumr f₂ xs s₂).fst
    ∧ (mapAccumr f₁ xs s₁).snd = (mapAccumr f₂ xs s₂).snd := by
  induction xs using Vector.revInductionOn generalizing s₁ s₂
  next => exact ⟨h₀, rfl⟩
  

Proof state:
case snoc
α : Type u_2
n : ℕ
xs : Vector α n
σ₁ : Type
β : Type u_1
σ₂ : Type
f₁ : α → σ₁ → σ₁ × β
f₂ : α → σ₂ → σ₂ × β
R : σ₁ → σ₂ → Prop
hR : ∀ {s : σ₁} {q : σ₂} (a : α), R s q → R (f₁ a s).1 (f₂ a q).1 ∧ (f₁ a s).2 = (f₂ a q).2
n✝ : ℕ
xs✝ : Vector α n✝
x✝ : α
a✝ :
  ∀ {s₁ : σ₁} {s₂ : σ₂},
    R s₁ s₂ → R (mapAccumr f₁ xs✝ s₁).1 (mapAccumr f₂ xs✝ s₂).1 ∧ (mapAccumr f₁ xs✝ s₁).2 = (mapAccumr f₂ xs✝ s₂).2
s₁ : σ₁
s₂ : σ₂
h₀ : R s₁ s₂
⊢ R (mapAccumr f₁ (snoc xs✝ x✝) s₁).1 (mapAccumr f₂ (snoc xs✝ x✝) s₂).1 ∧
    (mapAccumr f₁ (snoc xs✝ x✝) s₁).2 = (mapAccumr f₂ (snoc xs✝ x✝) s₂).2

Next tactic:
next xs x ih =>
    rcases (hR x h₀) with ⟨hR, _⟩
    simp only [mapAccumr_snoc, ih hR, true_and]
    congr 1