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

State before:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
⊢ (revDerivM K fun x =>
      let y := g x;
      f x y) =
    fun x =>
    let ydg := revDeriv K g x;
    do
    let zdf ← revDerivM K (fun xy => f xy.1 xy.2) (x, ydg.1)
    pure
        (zdf.1, fun dz => do
          let dxy ← zdf.2 dz
          let dx : X := ydg.2 dxy.2
          pure (dxy.1 + dx))
Tactic:
let f' := (fun xy : X×Y => f xy.1 xy.2)
State after:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
⊢ (revDerivM K fun x =>
      let y := g x;
      f x y) =
    fun x =>
    let ydg := revDeriv K g x;
    do
    let zdf ← revDerivM K (fun xy => f xy.1 xy.2) (x, ydg.1)
    pure
        (zdf.1, fun dz => do
          let dxy ← zdf.2 dz
          let dx : X := ydg.2 dxy.2
          pure (dxy.1 + dx))

State before:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
⊢ (revDerivM K fun x =>
      let y := g x;
      f x y) =
    fun x =>
    let ydg := revDeriv K g x;
    do
    let zdf ← revDerivM K (fun xy => f xy.1 xy.2) (x, ydg.1)
    pure
        (zdf.1, fun dz => do
          let dxy ← zdf.2 dz
          let dx : X := ydg.2 dxy.2
          pure (dxy.1 + dx))
Tactic:
let g' := (fun x => (x,g x))
State after:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
g' : X → X × Y := fun x => (x, g x)
⊢ (revDerivM K fun x =>
      let y := g x;
      f x y) =
    fun x =>
    let ydg := revDeriv K g x;
    do
    let zdf ← revDerivM K (fun xy => f xy.1 xy.2) (x, ydg.1)
    pure
        (zdf.1, fun dz => do
          let dxy ← zdf.2 dz
          let dx : X := ydg.2 dxy.2
          pure (dxy.1 + dx))

State before:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
g' : X → X × Y := fun x => (x, g x)
⊢ (revDerivM K fun x =>
      let y := g x;
      f x y) =
    fun x =>
    let ydg := revDeriv K g x;
    do
    let zdf ← revDerivM K (fun xy => f xy.1 xy.2) (x, ydg.1)
    pure
        (zdf.1, fun dz => do
          let dxy ← zdf.2 dz
          let dx : X := ydg.2 dxy.2
          pure (dxy.1 + dx))
Tactic:
have hg' : HasAdjDiff K g' := by rw[show g' = (fun x => (x,g x)) by rfl]; fun_prop
State after:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
g' : X → X × Y := fun x => (x, g x)
hg' : HasAdjDiff K g'
⊢ (revDerivM K fun x =>
      let y := g x;
      f x y) =
    fun x =>
    let ydg := revDeriv K g x;
    do
    let zdf ← revDerivM K (fun xy => f xy.1 xy.2) (x, ydg.1)
    pure
        (zdf.1, fun dz => do
          let dxy ← zdf.2 dz
          let dx : X := ydg.2 dxy.2
          pure (dxy.1 + dx))

State before:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
g' : X → X × Y := fun x => (x, g x)
hg' : HasAdjDiff K g'
⊢ (revDerivM K fun x =>
      let y := g x;
      f x y) =
    fun x =>
    let ydg := revDeriv K g x;
    do
    let zdf ← revDerivM K (fun xy => f xy.1 xy.2) (x, ydg.1)
    pure
        (zdf.1, fun dz => do
          let dxy ← zdf.2 dz
          let dx : X := ydg.2 dxy.2
          pure (dxy.1 + dx))
Tactic:
conv =>
  lhs
  rw[show ((fun x => f x (g x))
           =
           fun x => pure (g' x) >>= f') by simp]
  rw[revDerivM_bind f' (fun x => pure (g' x)) hf (HasAdjDiffM_pure g' hg')]
  simp[revDerivM_pure (K:=K) g' hg']
  fun_trans; simp
State after:
no goals

State before:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
g' : X → X × Y := fun x => (x, g x)
⊢ HasAdjDiff K g'
Tactic:
rw[show g' = (fun x => (x,g x)) by rfl]
State after:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
g' : X → X × Y := fun x => (x, g x)
⊢ HasAdjDiff K fun x => (x, g x)

State before:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
g' : X → X × Y := fun x => (x, g x)
⊢ HasAdjDiff K fun x => (x, g x)
Tactic:
fun_prop
State after:
no goals

State before:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
g' : X → X × Y := fun x => (x, g x)
⊢ g' = fun x => (x, g x)
Tactic:
rfl
State after:
no goals

State before:
ι : Sort ?u.38037
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 : X → Y → m Z
g : X → Y
hf : HasAdjDiffM K fun xy => f xy.1 xy.2
hg : HasAdjDiff K g
f' : X × Y → m Z := fun xy => f xy.1 xy.2
g' : X → X × Y := fun x => (x, g x)
hg' : HasAdjDiff K g'
⊢ (fun x => f x (g x)) = fun x => pure (g' x) >>= f'
Tactic:
simp
State after:
no goals