Theorem: Bind.bind.arg_a0a1.HasAdjDiffM_rule (SciLean/Core/Monads/RevDerivMonad.lean)

State before:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
⊢ HasAdjDiffM K fun x => a0 x >>= a1 x
Tactic:
let g := fun x => do
  let y ← a0 x
  pure (x,y)
State after:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
⊢ HasAdjDiffM K fun x => a0 x >>= a1 x

State before:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
⊢ HasAdjDiffM K fun x => a0 x >>= a1 x
Tactic:
let f := fun xy : X×Y => a1 xy.1 xy.2
State after:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
⊢ HasAdjDiffM K fun x => a0 x >>= a1 x

State before:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
⊢ HasAdjDiffM K fun x => a0 x >>= a1 x
Tactic:
rw[show (fun x => Bind.bind (a0 x) (a1 x))
        =
        fun x => g x >>= f by simp[f,g]]
State after:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
⊢ HasAdjDiffM K fun x => g x >>= f

State before:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
⊢ HasAdjDiffM K fun x => g x >>= f
Tactic:
have hg : HasAdjDiffM K (fun x => do let y ← a0 x; pure (x,y)) :=
  by apply RevDerivMonad.HasAdjDiffM_pair a0 ha0
State after:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
hg :
  HasAdjDiffM K fun x => do
    let y ← a0 x
    pure (x, y)
⊢ HasAdjDiffM K fun x => g x >>= f

State before:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
hg :
  HasAdjDiffM K fun x => do
    let y ← a0 x
    pure (x, y)
⊢ HasAdjDiffM K fun x => g x >>= f
Tactic:
have hf : HasAdjDiffM K f := by fun_prop
State after:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
hg :
  HasAdjDiffM K fun x => do
    let y ← a0 x
    pure (x, y)
hf : HasAdjDiffM K f
⊢ HasAdjDiffM K fun x => g x >>= f

State before:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
hg :
  HasAdjDiffM K fun x => do
    let y ← a0 x
    pure (x, y)
hf : HasAdjDiffM K f
⊢ HasAdjDiffM K fun x => g x >>= f
Tactic:
apply RevDerivMonad.HasAdjDiffM_bind _ _ hf hg
State after:
no goals

State before:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
⊢ (fun x => a0 x >>= a1 x) = fun x => g x >>= f
Tactic:
simp[f,g]
State after:
no goals

State before:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
⊢ HasAdjDiffM K fun x => do
    let y ← a0 x
    pure (x, y)
Tactic:
apply RevDerivMonad.HasAdjDiffM_pair a0 ha0
State after:
no goals

State before:
ι : Sort ?u.63862
K : Type
inst✝⁹ : RCLike K
m m' : Type → Type
inst✝⁸ : Monad m
inst✝⁷ : Monad m'
inst✝⁶ : RevDerivMonad K m m'
inst✝⁵ : LawfulMonad m
inst✝⁴ : LawfulMonad m'
X : Type
inst✝³ : SemiInnerProductSpace K X
Y : Type
inst✝² : SemiInnerProductSpace K Y
Z : Type
inst✝¹ : SemiInnerProductSpace K Z
E : ι → Type
inst✝ : (i : ι) → SemiInnerProductSpace K (E i)
a0 : X → m Y
a1 : X → Y → m Z
ha0 : HasAdjDiffM K a0
ha1 : HasAdjDiffM K fun xy => a1 xy.1 xy.2
g : X → m (X × Y) :=
  fun x => do
    let y ← a0 x
    pure (x, y)
f : X × Y → m Z := fun xy => a1 xy.1 xy.2
hg :
  HasAdjDiffM K fun x => do
    let y ← a0 x
    pure (x, y)
⊢ HasAdjDiffM K f
Tactic:
fun_prop
State after:
no goals