Theorem: SciLean.revDerivM.comp_rule (SciLean/Core/Monads/RevDerivMonad.lean)

State before:
ι : Sort ?u.27735
K : Type
inst✝⁹ : RCLike K
m : Type → Type
m' : outParam (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)
f : Y → m Z
g : X → Y
hf : HasAdjDiffM K f
hg : HasAdjDiff K g
⊢ (revDerivM K fun x => f (g x)) = fun x =>
    let ydg := revDeriv K g x;
    do
    let zdf ← revDerivM K f ydg.1
    pure
        (zdf.1, fun dz => do
          let dy ← zdf.2 dz
          pure (ydg.2 dy))
Tactic:
conv =>
  lhs
  rw[show ((fun x => f (g x))
           =
           fun x => pure (g x) >>= f) by simp]
  rw[revDerivM_bind f (fun x => pure (g x))
       hf (HasAdjDiffM_pure _ hg)]
  simp[revDerivM_pure g hg]
State after:
no goals

State before:
ι : Sort ?u.27735
K : Type
inst✝⁹ : RCLike K
m : Type → Type
m' : outParam (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)
f : Y → m Z
g : X → Y
hf : HasAdjDiffM K f
hg : HasAdjDiff K g
⊢ (fun x => f (g x)) = fun x => pure (g x) >>= f
Tactic:
simp
State after:
no goals