To prove: This is equivalent to the rule s1 = S'(a1), S' being a synthetic node inserted into the input tree.
A concrete example makes the formal statement more comprehensible. Suppose we have the rules:
int = INTEGER_LITERAL { /* Use LDC, BIPUSH, ICONST */ } long = int; // No code necessary, the JVM will widen the int to a long object = int { /* new Integer(int) */ } string = object { /* object.toString() */ }
TO_STRING->TO_OBJECT->INTEGER_LITERAL
int = INTEGER_LITERAL { /* as before }
object = TO_OBJECT(int) { /* new Integer(int) */ }
string = TO_STRING(object) { /* object.toString() */ }
What does it mean to be "equivalent" in the context of a BURM?
The costs of the antecedent rules add up in the same way: the cost of the int state is 1, the cost of the object state is 5 + 1, and the cost of the string state is 2 + 6. Note that each state only needs to obtain the (aggregate) cost of its immediate antecedent.
The partial order starts with a state, sPrime, that has no antecedents. There must be at least one such state per stage. Any states whose antecedent is sPrime are next, then their antecedents, and so on.
This is the way that the BURM's labler works; it begins with a pattern-matching rule, which has no antecedents. Then it finds transformational rules that depend on that primary state. For any transformational rule that may run, the labeler finds additional transformational rules, sequentially constructing a set of orderings of the set of states.
This set is ambiguous, in that it may contain cycles; the BURM guards against cycles by using the pigeonhole principle to assert that there are no more than k-1 possible antecedents at any stage; if the reducer requests additional antecedent states, then the ordering contains cycles.
TODO: The labeler can detect these cycles as well, and it should, since it has more information available for diagnostics.
The string state, which is our overall goal, notes that its antecedent is object. The string rule goes onto a rule stack, and the reducer investigates object's antecedents.
The object state's antecedent is int. The object goes onto the rule stack, and the reducer investigates int's antecedents.
int has no antecedent, so the reducer "reduces" int by running its rule, pops the object rule and "reduces," and finally pops the string rule and "reduces" to the goal state.
This is nothing more than an observation that the Principle of Optimality, a basic Dynamic Programming concept, holds for antecedent states because they're equivalent to a mutated tree, as demonstrated above.