For reference, we repeat here plugin requirements spread through the chapter. Plugin Requirement 12.1.16 (Basic change structures on base types)

For each base type ι, the plugin defines a basic change structure on ⟦ι ⟧ that we writeeι. □ Plugin Requirement 12.1.19 (Base change types)

For each base type ι, the plugin defines a change type ∆ι such that ∆ ⟦ι ⟧ = ⟦ ∆ι ⟧. □ Plugin Requirement 12.2.9 (Typing ofDC⟦ – ⟧)

For all ⊢Cc: τ , the plugin defines DC⟦ c ⟧ satisfying ⊢ DC⟦ c ⟧ : ∆τ .

□ Plugin Requirement 12.2.10 (Correctness ofDC⟦ – ⟧)

For all ⊢Cc: τ ,DC⟦ c ⟧is a derivative for ⟦ c ⟧.

Chapter 12. Changes and differentiation, formally 95

12.5

Chapter conclusion

In this chapter, we have formally defined changes for values and environments of our language, and when changes are valid. Through these definitions, we have explained that D ⟦ t ⟧ is correct, that is, that it maps changes to the input environment to changes to the output environment. All of this assumes, among other things, that language plugins define valid changes for their base types and derivatives for their primitives.

In next chapter we discuss operations we provide to construct and use changes. These operations will be especially useful to provide derivatives of primitives.

Chapter 13

Change structures

In the previous chapter, we have shown that evaluating the result of differentiation produces a valid change dv from the old output v1to the new one v2. To compute v2from v1and dv, in this chapter we introduce formally the operator ⊕ mentioned earlier.

To define differentiation on primitives, plugins need a few operations on changes, not just ⊕, ⊖, ⊚ and 0.

To formalize these operators and specify their behavior, we extend the notion of basic change structure into the notion of change structure in Sec. 13.1. The change structure for function spaces is not entirely intuitive, so we motivate it in Sec. 13.2. Then, we show how to take change structures on A and B and define new ones on A → B in Sec. 13.3. Using these structures, we finally show that starting from change structures for base types, we define change structures for all types τ and contexts Γ in Sec. 13.4, completing the core theory of changes.

13.1

Formalizing ⊕ and change structures

In this section, we define what is a change structure on a set V. A change structureVbextends a basic change structureVewith change operators ⊕, ⊖, ⊚ and 0. Change structures also require change operators to respect validity, as described below. Key properties of change structures follow in Sec. 13.1.2.

As usual, we’ll use metavariables v, v1, v2, . . .will range over elements of V, while dv, dv1, dv2, . . . will range over elements of ∆V.

Let’s first recall change operators. Operator ⊕ (“oplus”) updates a value with a change: If dv is a valid change from v1to v2, then v1⊕ dv(read as “v1updated by dv” or “v1oplus dv”) is guaranteed to return v2. Operator ⊖ (“ominus”) produces a difference between two values: v2⊖ v1is a valid change from v1to v2. Operator 0 (“nil”) produces nil changes: 0v is a nil change for v. Finally, change composition ⊚ (“ocompose”) “pastes changes together”: if dv1is a valid change from v1to v2and dv2is a valid change from v2to v3, then dv1⊚ dv2(read “dv1composed with dv2”) is a valid change from v1to v3.

We summarize these descriptions in the following definition. Definition 13.1.1

A change structurebVover a set V requires:

(a) A basic change structure for V (hence change set ∆V and validity dv ▷ v1,→ v2: V). 97

98 Chapter 13. Change structures (b) An update operation ⊕ : V → ∆V → V that updates a value with a change. Update must

agree with validity: for all dv ▷ v1,→ v2: V we require v1⊕ dv= v2.

(c) A nil change operation 0 : V → ∆V, that must produce nil changes: for all v : V we require 0v ▷ v ,→ v : V .

(d) a difference operation ⊖ : V → V → ∆V that produces a change across two values: for all v1, v2: V we require v2⊖ v1▷ v1,→ v2: V.

(e) a change composition operation ⊚ : ∆V → ∆V → ∆V, that composes together two changes relative to a base value. Change composition must preserve validity: for all dv1▷ v1,→ v2: V

and dv2▷ v2,→ v3: V we require dv1⊚ dv2▷ v1,→ v3: V. □

Notation 13.1.2

Operators ⊕ and ⊖ can be subscripted to highlight their base set, but we will usually omit such subscripts. Moreover, ⊕ is left-associative, so that v ⊕ dv1⊕ dv2means (v ⊕ dv1) ⊕ dv2.

Finally, whenever we have a change structure such asbA,bB,bV, and so on, we write respectively

A, B, V to refer to its base set. □

13.1.1

Example: Group changes

As an example, we show next that each group induces a change structure on its carrier. This change structure also subsumes basic change structures we saw earlier on integers.

Definition 13.1.3 (Change structure on groupsG)

Given any group (G, e, +, −) we can define a change structurebGon carrier set G as follows. (a) The change set is G.

(b) Validity is defined as dg ▷ g1,→ g2: G if and only if g2= g1+ dg.

(c) Change update coincides with +: g1⊕ dg= g1+ dg. Hence ⊕ agrees perfectly with validity: for all g1 ∈ G, all changes dg are valid from g1to g1⊕ dg(that is dg ▷ g1,→ g1⊕ dg: G). (d) We define difference as g2⊖ g1 = (−g1)+ g2. Verifying g2⊖ g1▷ g1 ,→ g2 : G reduces to

verifying g1+ ((−g1)+ g2)= g2, which follows from group axioms.

(e) The only nil change is the identity element: 0g = e. Validity 0g ▷ g ,→ g : G reduces to g+ e = g which follows from group axioms.

(f) Change composition also coincides with +: dg1⊚dg2= dg1+dg2. Let’s prove that composition respects validity. Our hypothesis is dg1 ▷ g1,→ g2: G and dg2▷ g2 ,→ g3 : G. Because ⊕ agrees perfectly with validity, the hypothesis is equivalent to g2= g1⊕ dg1and

g3= g2⊕ dg2= (g1⊕ dg1) ⊕ dg2. Our thesis is dg1⊚ dg2▷ g1,→ g3: G, that is

g3= g1⊕ (dg1⊚ dg2). Hence the thesis reduces to

(g1⊕ dg1) ⊕ dg2= g1⊕ (dg1⊚ dg2),

hence to g1+ (dg1+ dg2)= (g1+ dg1)+ dg2, which is just the associative law for group G.□ As we show later, group change structures are useful to support aggregation.

Chapter 13. Change structures 99

13.1.2

Properties of change structures

To understand better the definition of change structures, we present next a few lemmas following from this definition.

Lemma 13.1.4 (⊖ inverts ⊕) ⊕inverts ⊖, that is

v1⊕ (v2⊖ v1)= v2,

for change structureVband any values v1, v2: V. □

Proof. For change structures, we know v2⊖ v1▷ v1,→ v2: V, and v1⊕ (v2⊖ v1)= v2follows. More in detail: Change dv = v2⊖ v1is a valid change from v1to v2(because ⊖ produces valid changes, v2⊖ v1▷ v1,→ v2: V), so updating dv’s source v1with dv produces dv’s destination v2 (because ⊕ agrees with validity, that is if dv ▷ v1,→ v2: V then v1⊕ dv= v2). □ Lemma 13.1.5 (A change can’t be valid for two destinations with the same source) Given a change dv : ∆V and a source v1 : V, dv can only be valid with v1as source for a single destination. That is, if dv ▷ v1,→ v2a : V and dv ▷ v1,→ v2b : V then v2a = v2b. □ Proof. The proof follows, intuitively, because ⊕ also maps change dv and its source v1to its destina- tion, and ⊕ is a function.

More technically, since ⊕ respects validity, the hypotheses mean that v2a= v1⊕ dv= v2b as

required. □

Beware that, changes can be valid for multiple sources, and associate them to different destination. For instance, integer 0 is a valid change for all integers.

If a change dv has source v, dv’s destination equals v ⊕ dv. So, to specify that dv is valid with source v, without mentioning dv’s destination, we introduce the following definition.

Definition 13.1.6 (One-sided validity)

We define relation VAas {(v, dv) ∈ A × ∆A | dv ▷ v ,→ v ⊕ dv : V }. □ We use this definition right away:

Lemma 13.1.7 (⊚ and ⊕ interact correctly)

If (v1, dv1) ∈ VV and (v1⊕ dv1, dv2) ∈ VVthen v1⊕ (dv1⊚ dv2)= v1⊕ dv1⊕ dv2. Proof. We know that ⊚ preserves validity, so under the hypotheses (v1, dv1) ∈ VV and (v1 ⊕ dv1, dv2) ∈ VVwe get that dv = dv1⊚ dv2is a valid change from v1to v1⊕ dv1⊕ dv2:

dv1⊚ dv2▷ v1,→ v1: V ⊕ dv1⊕ dv2.

Hence, updating dv’s source v1with dv produces dv’s destination v1⊕ dv1⊕ dv2:

v1⊕ (dv1⊚ dv2)= v1⊕ dv1⊕ dv2. fl

We can define 0 in terms of other operations, and prove they satisfy their requirements for change structures.

Lemma 13.1.8 (0 can be derived from ⊖)

If we define 0v = v ⊖ v, then 0 produces valid changes as required (0v▷ v ,→ v : V ), for any change

structurebVand value v : V.

100 Chapter 13. Change structures Moreover, nil changes are a right identity element for ⊕:

Corollary 13.1.9 (Nil changes are identity elements)

Any nil change dv for a value v is a right identity element for ⊕, that is we have v ⊕ dv = v for every set V with a basic change structure, every element v ∈ V and every nil change dv for v. □ Proof. This follows from Lemma 13.4.4 and the definition of nil changes. □ The converse of this theorem does not hold: there exists changes dv such that v ⊕ dv = v yet dv is not a valid change from v to v. More in general, v1⊕ dv = v2does not imply that dv is a valid change. For instance, under earlier definitions for changes on naturals, if we take v = 0 and dv= −5, we have v ⊕ dv = v even though dv is not valid; examples of invalid changes on functions are discussed at Sec. 12.3.2 and Sec. 15.2. However, we prefer to define “dv is a nil change” as we do, to imply that dv is valid, not just a neutral element.

In document Optimizing and Incrementalizing Higher-order Collection Queries by AST Transformation (Page 112-118)