Lectures onType Theory
Chapter 182
Chapter 182Optional

Differentiable Semantics and Forward-Mode Automatic Differentiation

Prerequisites. Direct starred prerequisites: none. No later core chapter depends on this route.

Let g:R2R be given by a program, and suppose we want g/x1 at a point. Two answers present themselves and both fail.

Symbolic differentiation rewrites the expression g into an expression for its derivative. It works for the grammar of arithmetic expressions, and it stops working as soon as the program contains a function-valued subterm: there is no rule for differentiating λf.f(fx), because the expression to be differentiated is not built from +, , and named smooth constants, and the intermediate object f has no derivative until it is instantiated.

Numerical differencing evaluates (g(x+εe1)g(x))/ε. It applies to any program, and it certifies nothing: for every finite set of tolerances and step sizes there are two smooth functions agreeing on all of them whose derivatives at x differ, so agreement of a transformation with a difference quotient at finitely many points is not evidence that the transformation computes a derivative.

What is wanted is a source-to-source transformation, defined by induction on the program including its higher-order subterms, together with a theorem stating what the transformed program denotes. This chapter fixes one source language, defines that transformation, and proves the theorem at first-order input and output types, higher-order subterms being permitted inside. The proof is a logical relation between what the program denotes and what its transform denotes; the interesting clause is at function types, and it is forced, not chosen.

The invariant to be maintained

Before any syntax, fix what the transformed program is supposed to compute.

Definition 182.1 — Tangent pairing

Let g:RnR. A function h:(R×R)nR×R is a tangent representation of g when for all smooth f1,,fn:RR and all xR, h(f1(x),f1(x),,fn(x),fn(x))=(g(f1(x),,fn(x)), (g(f1,,fn))(x)).

Equation 182.1 is a statement about composition, not about a single point, and that is what makes it usable as an induction hypothesis: it says that h transports first-order Taylor data through g. Instantiating it recovers the familiar quantities.

Example 182.2 — Partial derivatives from the invariant

Take n=2, fix aR2, and let f1(x):=x, f2(x):=a2, evaluated at x=a1. Then f1=1 and f2=0, and equation 182.1 reads h(a1,1,a2,0)=(g(a), gx1(a)). Choosing f1=0, f2=1 gives the other partial derivative, and a general pair of tangents gives the directional derivative. So a single h satisfying equation 182.1 contains all first-order derivative information about g, and one evaluation of h yields one directional derivative at the cost of one evaluation of g up to a constant factor.

Remark 182.3 — Why a difference quotient cannot replace this

Let g1(x):=0 and g2(x):=ε0sin(x/ε02) for a fixed ε0>0. For any finite set E of step sizes one may choose ε0 so that g2 agrees with g1 to within any prescribed tolerance on all quotients formed from E at 0, while g2(0)=1/ε0 is arbitrarily large. Agreement of a transformation with difference quotients on finitely many inputs is therefore consistent with an arbitrarily wrong derivative, which is why the correctness statement below is an equation between denotations rather than a numerical comparison.

The source language

Definition 182.4 — Types and terms

Fix for each n0 a set Opn of n-ary operation symbols, containing a symbol c for each cR in Op0 and containing +,Op2. Types and terms are τ,σ ::= real  (τ1τn)  τσ, t,s ::= x  op(t1,,tn)  t1,,tn case t of x1,,xns  λx:τ.t  ts. The typing rules are the expected ones: a variable has its declared type; opOpn applied to n terms of type real has type real; a tuple of terms of types τi has the product type; case eliminates a product by binding its components; abstraction and application are as in chapter 2. We write Γt:τ and use let x=t in s for (λx.s)t.

Definition 182.5 — Set-theoretic denotation

Assume given for each opOpn a smooth function [[op]]:RnR, with [[c]]=c, [[+]] addition and [[]] multiplication. Interpret [[real]]:=R, products as products of sets, and [[τσ]] as the set of all functions [[τ]][[σ]]. A context Γ=x1:τ1,,xm:τm denotes the product of the [[τi]], and a derivation of Γt:τ denotes a function [[t]]:[[Γ]][[τ]] by the usual clauses: variables project, op applies [[op]], tuples pair, case substitutes the components, abstraction curries, and application evaluates.

Interpreting τσ by all functions is deliberately crude: it makes [[t]] defined for every term, and it makes no claim of smoothness at function types, where no claim is yet available. The correctness theorem below never mentions [[τσ]] except through the logical relation.

The tangent macro

Definition 182.6 — The macro D

On types, D(real):=(realreal),D(τσ):=DτDσ,D(τ1τn):=(Dτ1Dτn). On terms, D is the identity on variables and commutes with every constructor, D(λx:τ.t):=λx:Dτ.Dt,D(ts):=(Dt)(Ds), and similarly for tuples and case, except at operations: D(op(t1,,tn)):= case Dt1 of x1,x1case Dtn of xn,xnop(x), i=1niop(x)xi, where x abbreviates x1,,xn and iop is a chosen term of the language, with free variables among x1,,xn, such that [[iop]]=[[op]]/xi. For a context Γ, write DΓ for the context with each type replaced by its image.

Lemma 182.7 — The macro preserves typing

If Γt:τ then DΓDt:Dτ.

Proof of Lemma 182.7 — The macro preserves typing

Proof. Induction on the typing derivation. Every clause but the operation clause replaces each type by its image and leaves the rule shape unchanged, so the same rule applies. For op(t1,,tn), the induction hypothesis gives DΓDti:(realreal); each case then binds xi,xi at type real, the terms op(x1,,xn) and iop(x1,,xn) have type real by the operation rule, and the displayed pair has type (realreal)=D(real). ◻

Example 182.8 — A first-order program

Let t:=x1x2+x1 with x1,x2:real. Writing a,a for the pair bound to x1 and b,b for the pair bound to x2, the macro gives, after the case bindings are performed, Dt=ab+a,  (ba+ab)+a, using 1(x1,x2)=x2, 2(x1,x2)=x1, and 1+=2+=1. Evaluating at a=1,b=0 gives (ab+a, b+1), which is the value together with (x1x2+x1)/x1, as example 182.2 predicts.

Example 182.9 — A program with a higher-order subterm

Let t:=(λf:realreal. f(fx))(λy:real. yy), so x:realt:real and [[t]](x)=x4. The macro does not differentiate the higher-order subterm symbolically; it applies itself structurally, giving Dt=(λf:D(realreal). f(fx))(λy:(realreal). yDy), where yDy abbreviates the operation clause at . Evaluating Dt at a,1: the inner function sends u,u to u2,2uu, so two applications give a2,2a and then a4,2a22a=a4,4a3. The derivative of x4 is obtained without any rule for differentiating λf.f(fx), which is the point: D is defined on all terms, including those a symbolic differentiator has no rule for.

Exercise 182.1

★☆☆ Apply D to t:=ς(x1x2) for a unary operation ς with 1ς=ς, and evaluate the result at a,1,b,0. Check the answer against the chain rule.

Exercise 182.2

★★☆ Show that D(let x=t in s) and let x=Dt in Ds are the same term, and explain why the analogous statement for a symbolic differentiator that substitutes t for x before differentiating changes the number of operations executed.

Correctness

The macro is defined by structural recursion, so its correctness proof must be by structural induction; and the statement to be proved cannot be equation 182.1 itself, because that statement mentions only real and the induction passes through function types. The standard repair is to define, for every type, a relation between what a term denotes and what its transform denotes, arranged so that the function-type clause is preserved by application. Here the relation is between smooth curves, since equation 182.1 is itself a statement about curves.

Definition 182.10 — The tangent relation

For each type τ define Sτ(R[[τ]])×(R[[Dτ]]) by induction on τ: Sreal:={(f, x(f(x),f(x))) : f:RR smooth},S(τ1τn):={((f1,,fn),(g1,,gn)) : (fi,gi)Sτi for each i},Sτσ:={(F,G) : for all (a,b)Sτ,(xF(x)(a(x)), xG(x)(b(x)))Sσ}. For a context Γ=x1:τ1,,xm:τm, write (γ,δ)SΓ when the i-th components are related by Sτi for each i.

The clause at τσ is the only one with a choice in it, and there is no choice: the induction step for application must turn related functions and related arguments into related results, and the displayed clause is exactly that requirement read as a definition. Note also what the clause does not say: it does not assign a derivative to a higher-order value. It relates a curve of functions to a curve of functions, and two different curves in [[D(τσ)]] may be related to the same curve in [[τσ]].

Lemma 182.11 — Fundamental lemma

Let Γt:τ and let (γ,δ)SΓ. Then (x[[t]](γ(x)), x[[Dt]](δ(x)))Sτ.

Proof of Lemma 182.11 — Fundamental lemma

Proof. Induction on the derivation of Γt:τ.

Variable. Both sides are the corresponding components of γ and δ, related by hypothesis.

Abstraction. Let t=λx:σ.s with Γ,x:σs:ρ. Let (a,b)Sσ. Then ((γ,a),(δ,b))SΓ,x:σ, so the induction hypothesis gives that x[[s]](γ(x),a(x)) and x[[Ds]](δ(x),b(x)) are related by Sρ. These are exactly the two curves required by the clause at σρ applied to the curves x[[t]](γ(x)) and x[[Dt]](δ(x)).

Application. Immediate from the clause at σρ and the two induction hypotheses.

Tuples and case. Componentwise from the product clause; for case, the induction hypothesis for the scrutinee gives related component curves, which extend the environments as in the abstraction case.

Operations. Let t=op(t1,,tn). By the induction hypothesis, for each i there is a smooth fi:RR with [[ti]](γ(x))=fi(x) and [[Dti]](δ(x))=(fi(x),fi(x)). Reading definition 182.6 at these values, the first component of [[Dt]](δ(x)) is [[op]](f1(x),,fn(x)), which is [[t]](γ(x)), and the second is i=1n[[op]]xi(f1(x),,fn(x))fi(x)=chainrule([[op]](f1,,fn))(x). The composite [[op]](f1,,fn) is smooth, being a composite of smooth functions, so the pair lies in Sreal. ◻

Theorem 182.12 — Correctness at a first-order interface

Let Γt:real where every variable of Γ=x1:real,,xn:real has type real. Let f:=(f1,,fn) be an n-tuple of smooth functions RR and write f(x) for the tuple of their values at x. Then [[t]]f is smooth and [[Dt]](f1(x),f1(x),,fn(x),fn(x))=([[t]](f(x)), ([[t]]f)(x)). That is, [[Dt]] is a tangent representation of [[t]] in the sense of definition 182.1. In particular [[Dt]](a1,1,a2,0,,an,0)=([[t]](a), [[t]]/x1(a)) whenever [[t]] is differentiable in its first argument at a.

Proof of Theorem 182.12 — Correctness at a first-order interface

Proof. Consider the two curves γ(x):=f(x),δ(x):=(f1(x),f1(x),,fn(x),fn(x)). They satisfy (γ,δ)SΓ by definition 182.10. Apply lemma 182.11 and read off the clause Sreal: the first curve is smooth, and the second is the pair consisting of it and its derivative. The final sentence is example 182.2, taking f1=id and every other fi constant. ◻

Remark 182.13 — The exact boundary of the theorem

Theorem 182.12 constrains t only at its interface: the free variables and the result have type real. Function types may occur anywhere inside t, as in example 182.9, and the proof passes through them by definition 182.10. What the theorem does not provide is a derivative of a higher-order term. The relation Sτσ is not the graph of a function, and a term of type (realreal)real typically has several transforms all satisfying the relation. The statement also says nothing about recursion, iteration, conditionals on real comparisons, probabilistic primitives, or nonsmooth operations: each of these would add a term former, and each would need its own clause in definition 182.10 and its own case in lemma 182.11.

Theorem 182.14 — Higher order and all first-order types; imported

Let k,R1 and let D(k,R) be the macro of definition 182.6 with D(k,R)(real) the type of tuples of (R+kk) reals and with the operation clause given by the multivariate Faà di Bruno formula.

  1. For every t with x1:real,,xn:realt:real, the function [[D(k,R)t]] is the (k,R)-Taylor representation of [[t]]: it transports all partial derivatives of order at most R of any n-tuple of smooth maps RkR through [[t]].

  2. For every first-order type τ, every first-order context Γ, and every Γt:τ, the translation D(k,R) coincides with the (k,R)-jet bundle functor, modulo canonical isomorphisms [[D(k,R)τ]]D(k,R)[[τ]].

Clause (i) is Theorem 4.3 and clause (ii) is Theorem 6.6 of Huot, Staton, and Vákár, Higher Order Automatic Differentiation of Higher Order Functions, arXiv:2101.06757. Their proofs interpret the language in diffeological spaces — sets equipped with a family of plots RkX closed under smooth reparametrization — and run the argument of lemma 182.11 inside a category glued along plots; clause (ii) additionally uses that smooth maps out of a connected Rk into a disjoint union of manifolds factor through one summand. Theorem 182.12 is the case k=R=1 with first-order interface, proved above over ordinary sets because at that instance the relation of definition 182.10 is already reflexive on the curves it needs. What is imported is exactly (i) and (ii); nothing is imported about recursion, partiality, or nonsmooth primitives, which those authors exclude, and nothing about implementation cost.

Perturbation confusion

Implementations of forward differentiation usually do not implement definition 182.6. They implement a run-time operator D on closures, defined by Dfx:=tg(f(x+1ϵ)), where x+1ϵ builds a dual number and tg extracts its tangent component. The two settings differ, and the difference is not cosmetic.

Example 182.15 — Confusion with one ε

Evaluate D(λx. xD(λy. x+y)1)1. Mathematically the inner derivative is 1 for every x, so the function being differentiated is xx and the answer is 1. With a single ϵ, the outer call binds x:=1+1ϵ, the inner call binds y:=1+1ϵ, and the inner body is (1+1ϵ)+(1+1ϵ)=2+2ϵ, whose tangent is 2. The outer body is then (1+1ϵ)2=2+2ϵ, whose tangent is 2. The answer is wrong by a factor of two, and the cause is that one symbol ϵ was used for two different derivative calculations.

The repair is to allocate a fresh tag at each invocation of D and to let tgϵ1 pass through dual numbers tagged ϵ2ϵ1. That repairs example 182.15 and every first-order nesting. It is not sufficient in general.

Example 182.16 — Confusion surviving fresh tags; imported counterexample

Define the offset operator sufx:=f(x+u), of type R(RR)RR. Then for all f and y, Ds0fy=u[f(y+u)]u=0=f(y)=Dfy, so D^:=Ds0 ought to equal D. Manzyuk, Pearlmutter, Radul, Rush, and Siskind [MPR^+19] exhibit h and y for which D^(D^h)y differs from D(Dh)y under the fresh-tag discipline extended to function-valued results by post-composition, tgϵg¯:=tgϵg¯. The cause is that Ds0 returns a function, so the tag allocated by the outer invocation is captured in a closure and is later reused by an invocation that should have received a distinct tag. Their paper analyses the failure and proposes two repairs, one delaying tag creation by eta expansion and one wrapping the outputs of derivative operators.

Remark 182.17 — Why the macro is not exposed to this

Definition 182.6 allocates no tags, because it has no run-time derivative operator: differentiation happens once, at translation time, and the translated program is an ordinary program of the same language. The counterexamples above are therefore not counterexamples to theorem 182.12; they are counterexamples to the claim that a run-time D with dynamically allocated tags implements the same mathematics. They belong here because they delimit the theorem: what has been proved is a statement about D and [[]], and an implementation that departs from definition 182.6 — by taking derivatives of closures at run time, for instance — is outside its scope and needs its own correctness argument. A reader who wants nested derivatives inside the frozen language obtains them by applying D twice, which produces a term with no tags in it at all.

Exercise 182.3

★★☆ Compute D(Dt) for t:=xx and evaluate it at the value that example 182.2 prescribes for a second derivative. Check the result against 2(x2)/x2=2, and identify which component of the four-fold nested pair carries it.

Exercise 182.4

★★☆ Redo example 182.15 with distinct tags ϵ1 for the outer invocation and ϵ2 for the inner one, using the rule tgϵ1(a+bϵ2)=(tgϵ1a)+(tgϵ1b)ϵ2 for ϵ1ϵ2, and verify that the answer is 1. Then state precisely which step of your calculation would fail if the inner invocation reused ϵ1.

Comparisons

Syntactic differentiation. Chapter 181 differentiates a term without any notion of smooth function: its sxu places one linear copy of u at one occurrence of x and sums. The comparison is exact at one point and misleading elsewhere. Both operations satisfy a product rule and a chain rule, and both are defined by structural recursion. But the resource derivative is about use counting and its correctness criteria are confluence and the Taylor identity of that chapter, while D is about numerical tangents and its correctness criterion is theorem 182.12. No theorem transfers in either direction.

Coherent differentiation. Ehrhard’s coherent differentiation develops a summability structure in which only certain pairs of terms may be added, so that differentiation makes sense without the unrestricted sums of chapter 181. It separates the two settings: the present chapter never adds two program values, because definition 182.6 produces pairs rather than sums, and the addition that appears in the operation clause is the addition of the object language at type real.

Implementation comparisons. Typed array languages with index sets, such as Dex, implement forward mode with a type discipline that tracks which index sets a tangent belongs to. That design is a comparison only: no array language theorem is imported here, and theorem 182.12 says nothing about arrays. Elliott’s compositional derivation, the survey of Baydin, Pearlmutter, Radul, and Siskind [BPRS18], and the matrix calculus course of Edelman and Johnson [EJ23] supply the dual-number, computation-graph, and finite-difference prelude that section 182.1 compresses into one invariant.

Suggested first pass.

None of these problems is a prerequisite for a later chapter. Begin with exercise 182.5, then exercise 182.6; the implementation project exercise 182.8 may be attempted at any time.

Exercise 182.5

★★☆ Suppose the clause Sτσ of definition 182.10 were replaced by “F=G pointwise after erasing tangent components”. Show that lemma 182.11 then fails, by exhibiting a term whose application case cannot be discharged. Then show that the displayed clause is the weakest one that discharges the application case.

Exercise 182.6

★★★ Add to definition 182.4 a conditional on reals, written if t<0 then s1 else s2, with the evident denotation, and extend D by applying itself to both branches. Exhibit a closed term of type realreal for which theorem 182.12 becomes false, and identify the step of the proof of lemma 182.11 that breaks. Then state a restriction on the guard under which the proof goes through again, and prove the restricted statement.

Exercise 182.7

★★☆ Prove that for first-order τ and σ the relation Sτσ determines its second component uniquely: if (F,G) and (F,G) are both in Srealreal then G=G on the curves that occur. Then exhibit two distinct transforms of one term of type (realreal)real that are both related to it, showing that uniqueness fails at second order.

Exercise 182.8

★★★ Practical project.forward-tangent-macro Implement in Agda or Kappa the language of definition 182.4, its evaluator, and the macro D of definition 182.6. Represent terms with typed de Bruijn indices so that lemma 182.7 is enforced by construction, and provide the operations c,+,,ς with their derivative terms.

The invariant to maintain is the one used in the proof of lemma 182.11: at every operation node the transformed program computes the pair whose components are op(x) and iiop(x)xi, and no other node inspects a tangent component. The concrete result is a function taking a term t with n real inputs, a point a, and a seed vector, and returning the pair produced by evaluating Dt.

Acceptance test. For t=x1x2+x1 at a=(3,5) with seeds (1,0) and (0,1), the tool returns (18,6) and (18,3); for the higher-order term of example 182.9 at a=2 with seed 1 it returns (16,32); for the twice-transformed term D(D(xx)) the second-order component is 2 at every point; and the term of example 182.15, written in the frozen language by applying D twice rather than by a run-time operator, returns 1 rather than the 2 of the confused evaluation. A mutation that drops the summation in the operation clause, keeping only the i=1 summand, must fail the first test on the seed (0,1).

The program evaluates finitely many closed terms at finitely many points. It illustrates theorem 182.12 and does not prove it; in particular agreement at the tested points is not evidence about any other point, which is the content of remark 182.3.

Bibliographic notes

The source language, the macro, and both correctness theorems are those of Huot, Staton, and Vákár, Higher Order Automatic Differentiation of Higher Order Functions, arXiv:2101.06757, whose Theorems 4.3 and 6.6 are imported as theorem 182.14; definition 182.1 is their equation (2.1) and definition 182.10 is the case k=R=1 of their logical relation. The observation that the argument can be run over ordinary sets for a simple language, without the diffeological axioms, is due to Barthe and coauthors and is recorded in that paper; the proof of lemma 182.11 above takes that route, which is why no diffeological space appears in this chapter’s own theorem. Correctness for typed automatic differentiation in the presence of partial features is treated by Nunes and Vákár under explicit source-language restrictions; none of those extensions is claimed here.

The perturbation-confusion examples of section 182.5 are from Manzyuk, Pearlmutter, Radul, Rush, and Siskind [MPR^+19], whose analysis of the offset operator is reproduced in outline in example 182.16; the one-tag example goes back to Siskind and Pearlmutter. That paper owns no theorem in this chapter: it is used to delimit theorem 182.12, as remark 182.17 states. Blondel and Roulet’s book-length treatment supplies the one-feature-at-a-time example ladder and the modern terminology; the survey [BPRS18] and the course notes [EJ23] supply the numerical background.

Search the book

Type to search the local edition.