l3lab/ntp-mathlib huggingface dataset:
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `X + y`
has Gaussian law with mean `μ + y` and variance `v`. -/
lemma gaussianReal_add_const {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (y : ℝ) :
    Measure.map (fun ω ↦ X ω + y) ℙ = gaussianReal (μ + y) v := by
  have hXm : AEMeasurable X := aemeasurable_of_map_neZero (by rw [hX]; infer_instance)
  change Measure.map ((fun ω ↦ ω + y) ∘ X) ℙ = gaussianReal (μ + y) v
  

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
y : ℝ
hXm : AEMeasurable X
⊢ Measure.map ((fun ω => ω + y) ∘ X) ℙ = gaussianReal (μ + y) v

Next tactic:
rw [← AEMeasurable.map_map_of_aemeasurable (measurable_id'.add_const _).aemeasurable hXm, hX,
    gaussianReal_map_add_const y]
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `y + X`
has Gaussian law with mean `μ + y` and variance `v`. -/
lemma gaussianReal_const_add {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (y : ℝ) :
    Measure.map (fun ω ↦ y + X ω) ℙ = gaussianReal (μ + y) v := by
  

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
y : ℝ
⊢ Measure.map (fun ω => y + X ω) ℙ = gaussianReal (μ + y) v

Next tactic:
simp_rw [add_comm y]
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `y + X`
has Gaussian law with mean `μ + y` and variance `v`. -/
lemma gaussianReal_const_add {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (y : ℝ) :
    Measure.map (fun ω ↦ y + X ω) ℙ = gaussianReal (μ + y) v := by
  simp_rw [add_comm y]
  

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
y : ℝ
⊢ Measure.map (fun ω => X ω + y) ℙ = gaussianReal (μ + y) v

Next tactic:
exact gaussianReal_add_const hX y
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `c * X`
has Gaussian law with mean `c * μ` and variance `c^2 * v`. -/
lemma gaussianReal_const_mul {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (c : ℝ) :
    Measure.map (fun ω ↦ c * X ω) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v) := by
  

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
c : ℝ
⊢ Measure.map (fun ω => c * X ω) ℙ = gaussianReal (c * μ) ({ val := c ^ 2, property := (_ : 0 ≤ c ^ 2) } * v)

Next tactic:
have hXm : AEMeasurable X := aemeasurable_of_map_neZero (by rw [hX]; infer_instance)
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `c * X`
has Gaussian law with mean `c * μ` and variance `c^2 * v`. -/
lemma gaussianReal_const_mul {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (c : ℝ) :
    Measure.map (fun ω ↦ c * X ω) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v) := by
  have hXm : AEMeasurable X := aemeasurable_of_map_neZero (by 

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
c : ℝ
⊢ NeZero (Measure.map X ℙ)

Next tactic:
rw [hX]
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `c * X`
has Gaussian law with mean `c * μ` and variance `c^2 * v`. -/
lemma gaussianReal_const_mul {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (c : ℝ) :
    Measure.map (fun ω ↦ c * X ω) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v) := by
  have hXm : AEMeasurable X := aemeasurable_of_map_neZero (by rw [hX]; 

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
c : ℝ
⊢ NeZero (gaussianReal μ v)

Next tactic:
infer_instance
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `c * X`
has Gaussian law with mean `c * μ` and variance `c^2 * v`. -/
lemma gaussianReal_const_mul {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (c : ℝ) :
    Measure.map (fun ω ↦ c * X ω) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v) := by
  have hXm : AEMeasurable X := aemeasurable_of_map_neZero (by rw [hX]; infer_instance)
  

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
c : ℝ
hXm : AEMeasurable X
⊢ Measure.map (fun ω => c * X ω) ℙ = gaussianReal (c * μ) ({ val := c ^ 2, property := (_ : 0 ≤ c ^ 2) } * v)

Next tactic:
change Measure.map ((fun ω ↦ c * ω) ∘ X) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v)
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `c * X`
has Gaussian law with mean `c * μ` and variance `c^2 * v`. -/
lemma gaussianReal_const_mul {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (c : ℝ) :
    Measure.map (fun ω ↦ c * X ω) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v) := by
  have hXm : AEMeasurable X := aemeasurable_of_map_neZero (by rw [hX]; infer_instance)
  change Measure.map ((fun ω ↦ c * ω) ∘ X) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v)
  

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
c : ℝ
hXm : AEMeasurable X
⊢ Measure.map ((fun ω => c * ω) ∘ X) ℙ = gaussianReal (c * μ) ({ val := c ^ 2, property := (_ : 0 ≤ c ^ 2) } * v)

Next tactic:
rw [← AEMeasurable.map_map_of_aemeasurable (measurable_id'.const_mul c).aemeasurable hXm, hX]
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `c * X`
has Gaussian law with mean `c * μ` and variance `c^2 * v`. -/
lemma gaussianReal_const_mul {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (c : ℝ) :
    Measure.map (fun ω ↦ c * X ω) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v) := by
  have hXm : AEMeasurable X := aemeasurable_of_map_neZero (by rw [hX]; infer_instance)
  change Measure.map ((fun ω ↦ c * ω) ∘ X) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v)
  rw [← AEMeasurable.map_map_of_aemeasurable (measurable_id'.const_mul c).aemeasurable hXm, hX]
  

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
c : ℝ
hXm : AEMeasurable X
⊢ Measure.map (fun x => c * x) (gaussianReal μ v) =
    gaussianReal (c * μ) ({ val := c ^ 2, property := (_ : 0 ≤ c ^ 2) } * v)

Next tactic:
exact gaussianReal_map_const_mul c
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `X * c`
has Gaussian law with mean `c * μ` and variance `c^2 * v`. -/
lemma gaussianReal_mul_const {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (c : ℝ) :
    Measure.map (fun ω ↦ X ω * c) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v) := by
  

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
c : ℝ
⊢ Measure.map (fun ω => X ω * c) ℙ = gaussianReal (c * μ) ({ val := c ^ 2, property := (_ : 0 ≤ c ^ 2) } * v)

Next tactic:
simp_rw [mul_comm _ c]
/-- If `X` is a real random variable with Gaussian law with mean `μ` and variance `v`, then `X * c`
has Gaussian law with mean `c * μ` and variance `c^2 * v`. -/
lemma gaussianReal_mul_const {X : Ω → ℝ} (hX : Measure.map X ℙ = gaussianReal μ v) (c : ℝ) :
    Measure.map (fun ω ↦ X ω * c) ℙ = gaussianReal (c * μ) (⟨c^2, sq_nonneg _⟩ * v) := by
  simp_rw [mul_comm _ c]
  

Proof state:
μ : ℝ
v : ℝ≥0
Ω : Type
inst✝ : MeasureSpace Ω
X : Ω → ℝ
hX : Measure.map X ℙ = gaussianReal μ v
c : ℝ
⊢ Measure.map (fun ω => c * X ω) ℙ = gaussianReal (c * μ) ({ val := c ^ 2, property := (_ : 0 ≤ c ^ 2) } * v)

Next tactic:
exact gaussianReal_const_mul hX c
/-- `Option.map₂` in terms of monadic operations. Note that this can't be taken as the definition
because of the lack of universe polymorphism. -/
theorem map₂_def {α β γ : Type u} (f : α → β → γ) (a : Option α) (b : Option β) :
    map₂ f a b = f <$> a <*> b :=
  by 

Proof state:
α✝ : Type ?u.229
β✝ : Type ?u.232
γ✝ : Type ?u.235
f✝ : α✝ → β✝ → γ✝
a✝ : Option α✝
b✝ : Option β✝
c : Option γ✝
α β γ : Type u
f : α → β → γ
a : Option α
b : Option β
⊢ map₂ f a b = Seq.seq (f <$> a) fun x => b

Next tactic:
cases a
/-- `Option.map₂` in terms of monadic operations. Note that this can't be taken as the definition
because of the lack of universe polymorphism. -/
theorem map₂_def {α β γ : Type u} (f : α → β → γ) (a : Option α) (b : Option β) :
    map₂ f a b = f <$> a <*> b :=
  by cases a <;> 

Proof state:
case none
α✝ : Type ?u.229
β✝ : Type ?u.232
γ✝ : Type ?u.235
f✝ : α✝ → β✝ → γ✝
a : Option α✝
b✝ : Option β✝
c : Option γ✝
α β γ : Type u
f : α → β → γ
b : Option β
⊢ map₂ f none b = Seq.seq (f <$> none) fun x => b

Next tactic:
rfl
/-- `Option.map₂` in terms of monadic operations. Note that this can't be taken as the definition
because of the lack of universe polymorphism. -/
theorem map₂_def {α β γ : Type u} (f : α → β → γ) (a : Option α) (b : Option β) :
    map₂ f a b = f <$> a <*> b :=
  by cases a <;> 

Proof state:
case some
α✝ : Type ?u.229
β✝ : Type ?u.232
γ✝ : Type ?u.235
f✝ : α✝ → β✝ → γ✝
a : Option α✝
b✝ : Option β✝
c : Option γ✝
α β γ : Type u
f : α → β → γ
b : Option β
val✝ : α
⊢ map₂ f (some val✝) b = Seq.seq (f <$> some val✝) fun x => b

Next tactic:
rfl
@[simp]
theorem map₂_none_right (f : α → β → γ) (a : Option α) : map₂ f a none = none := by 

Proof state:
α : Type u_1
β : Type u_3
γ : Type u_2
f✝ : α → β → γ
a✝ : Option α
b : Option β
c : Option γ
f : α → β → γ
a : Option α
⊢ map₂ f a none = none

Next tactic:
cases a
@[simp]
theorem map₂_none_right (f : α → β → γ) (a : Option α) : map₂ f a none = none := by cases a <;> 

Proof state:
case none
α : Type u_1
β : Type u_3
γ : Type u_2
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
f : α → β → γ
⊢ map₂ f none none = none

Next tactic:
rfl
@[simp]
theorem map₂_none_right (f : α → β → γ) (a : Option α) : map₂ f a none = none := by cases a <;> 

Proof state:
case some
α : Type u_1
β : Type u_3
γ : Type u_2
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
f : α → β → γ
val✝ : α
⊢ map₂ f (some val✝) none = none

Next tactic:
rfl
@[simp]
theorem map₂_coe_right (f : α → β → γ) (a : Option α) (b : β) : map₂ f a b = a.map fun a => f a b :=
  by 

Proof state:
α : Type u_1
β : Type u_3
γ : Type u_2
f✝ : α → β → γ
a✝ : Option α
b✝ : Option β
c : Option γ
f : α → β → γ
a : Option α
b : β
⊢ map₂ f a (some b) = Option.map (fun a => f a b) a

Next tactic:
cases a
@[simp]
theorem map₂_coe_right (f : α → β → γ) (a : Option α) (b : β) : map₂ f a b = a.map fun a => f a b :=
  by cases a <;> 

Proof state:
case none
α : Type u_1
β : Type u_3
γ : Type u_2
f✝ : α → β → γ
a : Option α
b✝ : Option β
c : Option γ
f : α → β → γ
b : β
⊢ map₂ f none (some b) = Option.map (fun a => f a b) none

Next tactic:
rfl
@[simp]
theorem map₂_coe_right (f : α → β → γ) (a : Option α) (b : β) : map₂ f a b = a.map fun a => f a b :=
  by cases a <;> 

Proof state:
case some
α : Type u_1
β : Type u_3
γ : Type u_2
f✝ : α → β → γ
a : Option α
b✝ : Option β
c : Option γ
f : α → β → γ
b : β
val✝ : α
⊢ map₂ f (some val✝) (some b) = Option.map (fun a => f a b) (some val✝)

Next tactic:
rfl
theorem mem_map₂_iff {c : γ} : c ∈ map₂ f a b ↔ ∃ a' b', a' ∈ a ∧ b' ∈ b ∧ f a' b' = c :=
  by 

Proof state:
α : Type u_2
β : Type u_3
γ : Type u_1
f : α → β → γ
a : Option α
b : Option β
c✝ : Option γ
c : γ
⊢ c ∈ map₂ f a b ↔ ∃ a' b', a' ∈ a ∧ b' ∈ b ∧ f a' b' = c

Next tactic:
simp [map₂]
@[simp]
theorem map₂_eq_none_iff : map₂ f a b = none ↔ a = none ∨ b = none :=
  by 

Proof state:
α : Type u_2
β : Type u_3
γ : Type u_1
f : α → β → γ
a : Option α
b : Option β
c : Option γ
⊢ map₂ f a b = none ↔ a = none ∨ b = none

Next tactic:
cases a
@[simp]
theorem map₂_eq_none_iff : map₂ f a b = none ↔ a = none ∨ b = none :=
  by cases a <;> 

Proof state:
case none
α : Type u_2
β : Type u_3
γ : Type u_1
f : α → β → γ
b : Option β
c : Option γ
⊢ map₂ f none b = none ↔ none = none ∨ b = none

Next tactic:
cases b
@[simp]
theorem map₂_eq_none_iff : map₂ f a b = none ↔ a = none ∨ b = none :=
  by cases a <;> 

Proof state:
case some
α : Type u_2
β : Type u_3
γ : Type u_1
f : α → β → γ
b : Option β
c : Option γ
val✝ : α
⊢ map₂ f (some val✝) b = none ↔ some val✝ = none ∨ b = none

Next tactic:
cases b
@[simp]
theorem map₂_eq_none_iff : map₂ f a b = none ↔ a = none ∨ b = none :=
  by cases a <;> cases b <;> 

Proof state:
case none.none
α : Type u_2
β : Type u_3
γ : Type u_1
f : α → β → γ
c : Option γ
⊢ map₂ f none none = none ↔ none = none ∨ none = none

Next tactic:
simp
@[simp]
theorem map₂_eq_none_iff : map₂ f a b = none ↔ a = none ∨ b = none :=
  by cases a <;> cases b <;> 

Proof state:
case none.some
α : Type u_2
β : Type u_3
γ : Type u_1
f : α → β → γ
c : Option γ
val✝ : β
⊢ map₂ f none (some val✝) = none ↔ none = none ∨ some val✝ = none

Next tactic:
simp
@[simp]
theorem map₂_eq_none_iff : map₂ f a b = none ↔ a = none ∨ b = none :=
  by cases a <;> cases b <;> 

Proof state:
case some.none
α : Type u_2
β : Type u_3
γ : Type u_1
f : α → β → γ
c : Option γ
val✝ : α
⊢ map₂ f (some val✝) none = none ↔ some val✝ = none ∨ none = none

Next tactic:
simp
@[simp]
theorem map₂_eq_none_iff : map₂ f a b = none ↔ a = none ∨ b = none :=
  by cases a <;> cases b <;> 

Proof state:
case some.some
α : Type u_2
β : Type u_3
γ : Type u_1
f : α → β → γ
c : Option γ
val✝¹ : α
val✝ : β
⊢ map₂ f (some val✝¹) (some val✝) = none ↔ some val✝¹ = none ∨ some val✝ = none

Next tactic:
simp
theorem map₂_swap (f : α → β → γ) (a : Option α) (b : Option β) :
    map₂ f a b = map₂ (fun a b => f b a) b a := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α → β → γ
a✝ : Option α
b✝ : Option β
c : Option γ
f : α → β → γ
a : Option α
b : Option β
⊢ map₂ f a b = map₂ (fun a b => f b a) b a

Next tactic:
cases a
theorem map₂_swap (f : α → β → γ) (a : Option α) (b : Option β) :
    map₂ f a b = map₂ (fun a b => f b a) b a := by cases a <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α → β → γ
a : Option α
b✝ : Option β
c : Option γ
f : α → β → γ
b : Option β
⊢ map₂ f none b = map₂ (fun a b => f b a) b none

Next tactic:
cases b
theorem map₂_swap (f : α → β → γ) (a : Option α) (b : Option β) :
    map₂ f a b = map₂ (fun a b => f b a) b a := by cases a <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α → β → γ
a : Option α
b✝ : Option β
c : Option γ
f : α → β → γ
b : Option β
val✝ : α
⊢ map₂ f (some val✝) b = map₂ (fun a b => f b a) b (some val✝)

Next tactic:
cases b
theorem map₂_swap (f : α → β → γ) (a : Option α) (b : Option β) :
    map₂ f a b = map₂ (fun a b => f b a) b a := by cases a <;> cases b <;> 

Proof state:
case none.none
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
f : α → β → γ
⊢ map₂ f none none = map₂ (fun a b => f b a) none none

Next tactic:
rfl
theorem map₂_swap (f : α → β → γ) (a : Option α) (b : Option β) :
    map₂ f a b = map₂ (fun a b => f b a) b a := by cases a <;> cases b <;> 

Proof state:
case none.some
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
f : α → β → γ
val✝ : β
⊢ map₂ f none (some val✝) = map₂ (fun a b => f b a) (some val✝) none

Next tactic:
rfl
theorem map₂_swap (f : α → β → γ) (a : Option α) (b : Option β) :
    map₂ f a b = map₂ (fun a b => f b a) b a := by cases a <;> cases b <;> 

Proof state:
case some.none
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
f : α → β → γ
val✝ : α
⊢ map₂ f (some val✝) none = map₂ (fun a b => f b a) none (some val✝)

Next tactic:
rfl
theorem map₂_swap (f : α → β → γ) (a : Option α) (b : Option β) :
    map₂ f a b = map₂ (fun a b => f b a) b a := by cases a <;> cases b <;> 

Proof state:
case some.some
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
f : α → β → γ
val✝¹ : α
val✝ : β
⊢ map₂ f (some val✝¹) (some val✝) = map₂ (fun a b => f b a) (some val✝) (some val✝¹)

Next tactic:
rfl
theorem map_map₂ (f : α → β → γ) (g : γ → δ) :
    (map₂ f a b).map g = map₂ (fun a b => g (f a b)) a b := by 

Proof state:
α : Type u_3
β : Type u_4
γ : Type u_2
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
δ : Type u_1
f : α → β → γ
g : γ → δ
⊢ Option.map g (map₂ f a b) = map₂ (fun a b => g (f a b)) a b

Next tactic:
cases a
theorem map_map₂ (f : α → β → γ) (g : γ → δ) :
    (map₂ f a b).map g = map₂ (fun a b => g (f a b)) a b := by cases a <;> 

Proof state:
case none
α : Type u_3
β : Type u_4
γ : Type u_2
f✝ : α → β → γ
b : Option β
c : Option γ
δ : Type u_1
f : α → β → γ
g : γ → δ
⊢ Option.map g (map₂ f none b) = map₂ (fun a b => g (f a b)) none b

Next tactic:
cases b
theorem map_map₂ (f : α → β → γ) (g : γ → δ) :
    (map₂ f a b).map g = map₂ (fun a b => g (f a b)) a b := by cases a <;> 

Proof state:
case some
α : Type u_3
β : Type u_4
γ : Type u_2
f✝ : α → β → γ
b : Option β
c : Option γ
δ : Type u_1
f : α → β → γ
g : γ → δ
val✝ : α
⊢ Option.map g (map₂ f (some val✝) b) = map₂ (fun a b => g (f a b)) (some val✝) b

Next tactic:
cases b
theorem map_map₂ (f : α → β → γ) (g : γ → δ) :
    (map₂ f a b).map g = map₂ (fun a b => g (f a b)) a b := by cases a <;> cases b <;> 

Proof state:
case none.none
α : Type u_3
β : Type u_4
γ : Type u_2
f✝ : α → β → γ
c : Option γ
δ : Type u_1
f : α → β → γ
g : γ → δ
⊢ Option.map g (map₂ f none none) = map₂ (fun a b => g (f a b)) none none

Next tactic:
rfl
theorem map_map₂ (f : α → β → γ) (g : γ → δ) :
    (map₂ f a b).map g = map₂ (fun a b => g (f a b)) a b := by cases a <;> cases b <;> 

Proof state:
case none.some
α : Type u_3
β : Type u_4
γ : Type u_2
f✝ : α → β → γ
c : Option γ
δ : Type u_1
f : α → β → γ
g : γ → δ
val✝ : β
⊢ Option.map g (map₂ f none (some val✝)) = map₂ (fun a b => g (f a b)) none (some val✝)

Next tactic:
rfl
theorem map_map₂ (f : α → β → γ) (g : γ → δ) :
    (map₂ f a b).map g = map₂ (fun a b => g (f a b)) a b := by cases a <;> cases b <;> 

Proof state:
case some.none
α : Type u_3
β : Type u_4
γ : Type u_2
f✝ : α → β → γ
c : Option γ
δ : Type u_1
f : α → β → γ
g : γ → δ
val✝ : α
⊢ Option.map g (map₂ f (some val✝) none) = map₂ (fun a b => g (f a b)) (some val✝) none

Next tactic:
rfl
theorem map_map₂ (f : α → β → γ) (g : γ → δ) :
    (map₂ f a b).map g = map₂ (fun a b => g (f a b)) a b := by cases a <;> cases b <;> 

Proof state:
case some.some
α : Type u_3
β : Type u_4
γ : Type u_2
f✝ : α → β → γ
c : Option γ
δ : Type u_1
f : α → β → γ
g : γ → δ
val✝¹ : α
val✝ : β
⊢ Option.map g (map₂ f (some val✝¹) (some val✝)) = map₂ (fun a b => g (f a b)) (some val✝¹) (some val✝)

Next tactic:
rfl
theorem map₂_map_left (f : γ → β → δ) (g : α → γ) :
    map₂ f (a.map g) b = map₂ (fun a b => f (g a) b) a b := by 

Proof state:
α : Type u_4
β : Type u_3
γ : Type u_2
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
δ : Type u_1
f : γ → β → δ
g : α → γ
⊢ map₂ f (Option.map g a) b = map₂ (fun a b => f (g a) b) a b

Next tactic:
cases a
theorem map₂_map_left (f : γ → β → δ) (g : α → γ) :
    map₂ f (a.map g) b = map₂ (fun a b => f (g a) b) a b := by cases a <;> 

Proof state:
case none
α : Type u_4
β : Type u_3
γ : Type u_2
f✝ : α → β → γ
b : Option β
c : Option γ
δ : Type u_1
f : γ → β → δ
g : α → γ
⊢ map₂ f (Option.map g none) b = map₂ (fun a b => f (g a) b) none b

Next tactic:
rfl
theorem map₂_map_left (f : γ → β → δ) (g : α → γ) :
    map₂ f (a.map g) b = map₂ (fun a b => f (g a) b) a b := by cases a <;> 

Proof state:
case some
α : Type u_4
β : Type u_3
γ : Type u_2
f✝ : α → β → γ
b : Option β
c : Option γ
δ : Type u_1
f : γ → β → δ
g : α → γ
val✝ : α
⊢ map₂ f (Option.map g (some val✝)) b = map₂ (fun a b => f (g a) b) (some val✝) b

Next tactic:
rfl
theorem map₂_map_right (f : α → γ → δ) (g : β → γ) :
    map₂ f a (b.map g) = map₂ (fun a b => f a (g b)) a b := by 

Proof state:
α : Type u_2
β : Type u_4
γ : Type u_3
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
δ : Type u_1
f : α → γ → δ
g : β → γ
⊢ map₂ f a (Option.map g b) = map₂ (fun a b => f a (g b)) a b

Next tactic:
cases b
theorem map₂_map_right (f : α → γ → δ) (g : β → γ) :
    map₂ f a (b.map g) = map₂ (fun a b => f a (g b)) a b := by cases b <;> 

Proof state:
case none
α : Type u_2
β : Type u_4
γ : Type u_3
f✝ : α → β → γ
a : Option α
c : Option γ
δ : Type u_1
f : α → γ → δ
g : β → γ
⊢ map₂ f a (Option.map g none) = map₂ (fun a b => f a (g b)) a none

Next tactic:
rfl
theorem map₂_map_right (f : α → γ → δ) (g : β → γ) :
    map₂ f a (b.map g) = map₂ (fun a b => f a (g b)) a b := by cases b <;> 

Proof state:
case some
α : Type u_2
β : Type u_4
γ : Type u_3
f✝ : α → β → γ
a : Option α
c : Option γ
δ : Type u_1
f : α → γ → δ
g : β → γ
val✝ : β
⊢ map₂ f a (Option.map g (some val✝)) = map₂ (fun a b => f a (g b)) a (some val✝)

Next tactic:
rfl
@[simp]
theorem map_uncurry (f : α → β → γ) (x : Option (α × β)) :
    x.map (uncurry f) = map₂ f (x.map Prod.fst) (x.map Prod.snd) := by 

Proof state:
α : Type u_2
β : Type u_1
γ : Type u_3
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
f : α → β → γ
x : Option (α × β)
⊢ Option.map (uncurry f) x = map₂ f (Option.map Prod.fst x) (Option.map Prod.snd x)

Next tactic:
cases x
@[simp]
theorem map_uncurry (f : α → β → γ) (x : Option (α × β)) :
    x.map (uncurry f) = map₂ f (x.map Prod.fst) (x.map Prod.snd) := by cases x <;> 

Proof state:
case none
α : Type u_2
β : Type u_1
γ : Type u_3
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
f : α → β → γ
⊢ Option.map (uncurry f) none = map₂ f (Option.map Prod.fst none) (Option.map Prod.snd none)

Next tactic:
rfl
@[simp]
theorem map_uncurry (f : α → β → γ) (x : Option (α × β)) :
    x.map (uncurry f) = map₂ f (x.map Prod.fst) (x.map Prod.snd) := by cases x <;> 

Proof state:
case some
α : Type u_2
β : Type u_1
γ : Type u_3
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
f : α → β → γ
val✝ : α × β
⊢ Option.map (uncurry f) (some val✝) = map₂ f (Option.map Prod.fst (some val✝)) (Option.map Prod.snd (some val✝))

Next tactic:
rfl
theorem map₂_assoc {f : δ → γ → ε} {g : α → β → δ} {f' : α → ε' → ε} {g' : β → γ → ε'}
    (h_assoc : ∀ a b c, f (g a b) c = f' a (g' b c)) :
    map₂ f (map₂ g a b) c = map₂ f' a (map₂ g' b c) :=
  by 

Proof state:
α : Type u_5
β : Type u_6
γ : Type u_4
f✝ : α → β → γ
a : Option α
b : Option β
c : Option γ
δ : Type u_1
ε : Type u_2
ε' : Type u_3
f : δ → γ → ε
g : α → β → δ
f' : α → ε' → ε
g' : β → γ → ε'
h_assoc : ∀ (a : α) (b : β) (c : γ), f (g a b) c = f' a (g' b c)
⊢ map₂ f (map₂ g a b) c = map₂ f' a (map₂ g' b c)

Next tactic:
cases a
theorem map₂_assoc {f : δ → γ → ε} {g : α → β → δ} {f' : α → ε' → ε} {g' : β → γ → ε'}
    (h_assoc : ∀ a b c, f (g a b) c = f' a (g' b c)) :
    map₂ f (map₂ g a b) c = map₂ f' a (map₂ g' b c) :=
  by cases a <;> 

Proof state:
case none
α : Type u_5
β : Type u_6
γ : Type u_4
f✝ : α → β → γ
b : Option β
c : Option γ
δ : Type u_1
ε : Type u_2
ε' : Type u_3
f : δ → γ → ε
g : α → β → δ
f' : α → ε' → ε
g' : β → γ → ε'
h_assoc : ∀ (a : α) (b : β) (c : γ), f (g a b) c = f' a (g' b c)
⊢ map₂ f (map₂ g none b) c = map₂ f' none (map₂ g' b c)

Next tactic:
cases b
theorem map₂_assoc {f : δ → γ → ε} {g : α → β → δ} {f' : α → ε' → ε} {g' : β → γ → ε'}
    (h_assoc : ∀ a b c, f (g a b) c = f' a (g' b c)) :
    map₂ f (map₂ g a b) c = map₂ f' a (map₂ g' b c) :=
  by cases a <;> 

Proof state:
case some
α : Type u_5
β : Type u_6
γ : Type u_4
f✝ : α → β → γ
b : Option β
c : Option γ
δ : Type u_1
ε : Type u_2
ε' : Type u_3
f : δ → γ → ε
g : α → β → δ
f' : α → ε' → ε
g' : β → γ → ε'
h_assoc : ∀ (a : α) (b : β) (c : γ), f (g a b) c = f' a (g' b c)
val✝ : α
⊢ map₂ f (map₂ g (some val✝) b) c = map₂ f' (some val✝) (map₂ g' b c)

Next tactic:
cases b
theorem map₂_assoc {f : δ → γ → ε} {g : α → β → δ} {f' : α → ε' → ε} {g' : β → γ → ε'}
    (h_assoc : ∀ a b c, f (g a b) c = f' a (g' b c)) :
    map₂ f (map₂ g a b) c = map₂ f' a (map₂ g' b c) :=
  by cases a <;> cases b <;> 

Proof state:
case none.none
α : Type u_5
β : Type u_6
γ : Type u_4
f✝ : α → β → γ
c : Option γ
δ : Type u_1
ε : Type u_2
ε' : Type u_3
f : δ → γ → ε
g : α → β → δ
f' : α → ε' → ε
g' : β → γ → ε'
h_assoc : ∀ (a : α) (b : β) (c : γ), f (g a b) c = f' a (g' b c)
⊢ map₂ f (map₂ g none none) c = map₂ f' none (map₂ g' none c)

Next tactic:
cases c