Proofs: Expression DAG
These are the human proofs of Expression DAG, at full length.
Hash consing keeps the DAG invariant, identifiers decide equality, and the walks are correct full
This proof shows: correctness, termination.
For a node of a store , write for its unfolded tree: is the leaf if is a leaf, and the tree with root and subtrees if . This is well defined by induction on once every child identifier is less than its parent, the second clause of (H).
Lemma 1 (MAKE keeps the invariant). If (H) holds and every identifier in kids is a node of , then after MAKE (H) holds, and the returned node has key .
Proof. If the key is in the table (line L2), nothing changes, and the table maps the key to a node whose key it is, by (H). Otherwise line L3 appends node , where was the number of nodes, with that key, and line L4 adds the single entry from the key to . The key was not in the table, and by (H) the table contained exactly the keys of nodes , so no earlier node has this key; the table now contains exactly the keys of nodes , each mapped to its node. Every child identifier is an existing node, so it is less than . The arity conditions are those of the constructors that call MAKE.
Theorem 1 (identifiers decide tree equality). If (H) holds, then for nodes and , if and only if .
Proof. If the trees are equal. For the converse we use induction on . Suppose . Then the roots agree, so , and for leaves . If they are leaves, their keys are equal. If they are operator nodes with children and , then for , and by (H), so by induction , and again the keys of and are equal. By (H) the table maps that key to and also to , so .
So equal, which compares identifiers, decides syntactic identity of the unfolded trees. Since constants are stored as reduced fractions, equal constants have equal keys.
Lemma 2 (order). The list of nodes reachable from , sorted by identifier, lists each such node once and each node after all of its children.
Proof. The search adds a node to the set when it first meets it, and pushes it once, so each reachable node is found and listed once. A child of a reachable node is reachable, and its identifier is smaller, so it comes earlier in the sorted list.
Theorem 2 (EVAL). EVAL returns , the value of the unfolded tree, if defines every symbol of .
Proof. We show for each reachable , by induction along the order of Lemma 2. Lines E2 and E3 are the values of the leaves. At line E4 both children were handled earlier, so and are the values of the subtrees, and the operator combines them as in the definition of . Line E5 returns .
Theorem 3 (SUBS and DIFF). , and is the partial derivative of with respect to at .
Proof. Both walks go along the order of Lemma 2 and build results with MAKE, which by Lemma 1 keeps (H) and returns a node with the requested key, so the tree of the result is the tree with the requested root and subtrees. For SUBS, induction along the order shows : the symbol becomes , other leaves stay, and an operator node is rebuilt from the results of its children. For DIFF, the same induction with the sum, product and power rules shows that has the value of the derivative of ; the smart constructors only fold constants and apply , , and , which keep the value. For powers, is written with replaced by when and by when , and the derivative is 0 when . Nodes that MAKE creates during the walk are not in the list of Lemma 2, which was computed first, so the walk does not visit them.
Termination and cost. The search and each walk touch each of the reachable nodes once and do work per node, apart from MAKE calls, of which there are per node, and the sort, which takes . Each MAKE does one table lookup and at most one insertion. So every operation terminates, and SUBS and DIFF add nodes.