Symbolic differentiation is actually quite straightforward, once you see the trick; in fact, you can think of it as a special case of symbolic *simplification*.

Suppose you want to take the derivative of `sin(x*x)`

with respect to `x`

, which I’ll denote `diff(sin(x*x), x)`

. How would you start? The chain rule - we now have `diff(x*x, x) * cos(x*x)`

, since we know that \frac{d \sin y}{dy} := \cos y. Now, let’s take out `diff(x*x, x)`

- treating `*`

as a binary function and applying the chain rule, we get `x*diff(x,x) + diff(x,x)*x`

. Finally, we take out each `diff(x,x)`

, replacing with `1`

. Our result now looks something like `(x*1 + 1*x) * cos(x*x)`

. There’s a bit more simplification to do here - removing the unnecessary `*1`

s, we get `(x + x) * cos(x*x)`

.

How do we automate this, though? The answer is surprisingly straightforward; we just encode the rules we implicitly used here a bit more formally:

```
diff(sin(x), t) => diff(x, t) * cos(x)
diff(x*y, t) => diff(x,t)*y + x*diff(y,t)
diff(x, x) => 1
x*1 => x
1*x => x
```

This clearly isn’t exhaustive, but by listing more and more rules, we can take symbolic derivatives on arbitrary terms.

Conveniently enough, there’s a general strategy we can use to check if the left-hand-side for a rule applies at a location of a concrete term: pattern matching.

Given an arbitrary symbolic term, we run through and find instantiations of a given left-hand side, and then replace each with the corresponding right-hand side until there are no more rules left to apply. This is precisely how symbolic differentiation in Rewrite.jl works.

As a quick side note, you may be disappointed with the fact that we have two rules for the multiplicative identity, `x*1 => x`

and `1*x => x`

. Shouldn’t this symmetry be taken care of, since we know `*`

is commutative? Yes, I’d say so. If you’re interested, I’ll be presenting this in more depth at JuliaCon in a couple weeks.

(Thanks for the ping, @ChrisRackauckas!)