Theorem: SciLean.revDeriv2.let_rule
Proof state before:
case h.h
K I : Type
inst✝²¹ : RCLike K
W : Type
inst✝²⁰ : SemiInnerProductSpace K W
X : Type
inst✝¹⁹ : SemiInnerProductSpace K X
Y : Type
inst✝¹⁸ : SemiInnerProductSpace K Y
Z : Type
inst✝¹⁷ : SemiInnerProductSpace K Z
ι : Type
inst✝¹⁶ : IndexType ι
inst✝¹⁵ : LawfulIndexType ι
inst✝¹⁴ : DecidableEq ι
E : Type
EI : I → Type
inst✝¹³ : StructType E I EI
inst✝¹² : IndexType I
inst✝¹¹ : LawfulIndexType I
inst✝¹⁰ : DecidableEq I
inst✝⁹ : SemiInnerProductSpace K E
inst✝⁸ : (i : I) → SemiInnerProductSpace K (EI i)
XI : I → Type
inst✝⁷ : StructType X I XI
inst✝⁶ : (i : I) → SemiInnerProductSpace K (XI i)
YI : I → Type
inst✝⁵ : StructType Y I YI
inst✝⁴ : (i : I) → SemiInnerProductSpace K (YI i)
ZI : I → Type
inst✝³ : StructType Z I ZI
inst✝² : (i : I) → SemiInnerProductSpace K (ZI i)
WI : I → Type
inst✝¹ : StructType W I WI
inst✝ : (i : I) → SemiInnerProductSpace K (WI i)
f : W → X → Y → Z
g : W → X → Y
hf : HasAdjDiff K fun x => f x.1 x.2.1 x.2.2
hg : HasAdjDiff K fun x => g x.1 x.2
x : W
y : X
⊢ (let y_1 := g x y;
      f x y y_1,
      fun dy dw' =>
      (dw' +
          (semiAdjoint K
              (cderiv K
                (fun x =>
                  let y := g x.1 x.2;
                  f x.1 x.2 y)
                (x, y))
              dy).1,
        (semiAdjoint K
            (cderiv K
              (fun x =>
                let y := g x.1 x.2;
                f x.1 x.2 y)
              (x, y))
            dy).2)) =
    let ydg :=
      (g x y, fun dy dw' =>
        (dw' + (semiAdjoint K (cderiv K (fun x => g x.1.1 x.1.2) ((x, y), ())) dy).1,
          (semiAdjoint K (cderiv K (fun x => g x.1.1 x.1.2) ((x, y), ())) dy).2));
    let zdf :=
      (f x y ydg.1, fun dy dw' =>
        (dw' + (semiAdjoint K (cderiv K (fun x => f x.1 x.2.1 x.2.2) (x, y, ydg.1)) dy).1,
          (semiAdjoint K (cderiv K (fun x => f x.1 x.2.1 x.2.2) (x, y, ydg.1)) dy).2));
    (zdf.1, fun dz dx =>
      let dxyz := zdf.2 dz dx;
      let dxy := ydg.2 dxyz.2.2 (dxyz.1, dxyz.2.1);
      dxy.1)
Tactic:
conv => lhs; fun_trans
Proof state after:
case h.h
K I : Type
inst✝²¹ : RCLike K
W : Type
inst✝²⁰ : SemiInnerProductSpace K W
X : Type
inst✝¹⁹ : SemiInnerProductSpace K X
Y : Type
inst✝¹⁸ : SemiInnerProductSpace K Y
Z : Type
inst✝¹⁷ : SemiInnerProductSpace K Z
ι : Type
inst✝¹⁶ : IndexType ι
inst✝¹⁵ : LawfulIndexType ι
inst✝¹⁴ : DecidableEq ι
E : Type
EI : I → Type
inst✝¹³ : StructType E I EI
inst✝¹² : IndexType I
inst✝¹¹ : LawfulIndexType I
inst✝¹⁰ : DecidableEq I
inst✝⁹ : SemiInnerProductSpace K E
inst✝⁸ : (i : I) → SemiInnerProductSpace K (EI i)
XI : I → Type
inst✝⁷ : StructType X I XI
inst✝⁶ : (i : I) → SemiInnerProductSpace K (XI i)
YI : I → Type
inst✝⁵ : StructType Y I YI
inst✝⁴ : (i : I) → SemiInnerProductSpace K (YI i)
ZI : I → Type
inst✝³ : StructType Z I ZI
inst✝² : (i : I) → SemiInnerProductSpace K (ZI i)
WI : I → Type
inst✝¹ : StructType W I WI
inst✝ : (i : I) → SemiInnerProductSpace K (WI i)
f : W → X → Y → Z
g : W → X → Y
hf : HasAdjDiff K fun x => f x.1 x.2.1 x.2.2
hg : HasAdjDiff K fun x => g x.1 x.2
x : W
y : X
⊢ (f x y (g x y), fun dy dw' =>
      (dw' +
          ((semiAdjoint K
                (fun dx8 => cderiv K (fun xy0xy1xy2 => f xy0xy1xy2.1 xy0xy1xy2.2.1 xy0xy1xy2.2.2) (x, y, g x y) dx8)
                dy).1 +
            (semiAdjoint K (fun x_1 => cderiv K (fun x => g x.1 x.2) (x, y) x_1)
                (semiAdjoint K
                      (fun dx8 =>
                        cderiv K (fun xy0xy1xy2 => f xy0xy1xy2.1 xy0xy1xy2.2.1 xy0xy1xy2.2.2) (x, y, g x y) dx8)
                      dy).2.2).1),
        (semiAdjoint K
                (fun dx8 => cderiv K (fun xy0xy1xy2 => f xy0xy1xy2.1 xy0xy1xy2.2.1 xy0xy1xy2.2.2) (x, y, g x y) dx8)
                dy).2.1 +
          (semiAdjoint K (fun x_1 => cderiv K (fun x => g x.1 x.2) (x, y) x_1)
              (semiAdjoint K
                    (fun dx8 => cderiv K (fun xy0xy1xy2 => f xy0xy1xy2.1 xy0xy1xy2.2.1 xy0xy1xy2.2.2) (x, y, g x y) dx8)
                    dy).2.2).2)) =
    let ydg :=
      (g x y, fun dy dw' =>
        (dw' + (semiAdjoint K (cderiv K (fun x => g x.1.1 x.1.2) ((x, y), ())) dy).1,
          (semiAdjoint K (cderiv K (fun x => g x.1.1 x.1.2) ((x, y), ())) dy).2));
    let zdf :=
      (f x y ydg.1, fun dy dw' =>
        (dw' + (semiAdjoint K (cderiv K (fun x => f x.1 x.2.1 x.2.2) (x, y, ydg.1)) dy).1,
          (semiAdjoint K (cderiv K (fun x => f x.1 x.2.1 x.2.2) (x, y, ydg.1)) dy).2));
    (zdf.1, fun dz dx =>
      let dxyz := zdf.2 dz dx;
      let dxy := ydg.2 dxyz.2.2 (dxyz.1, dxyz.2.1);
      dxy.1)