Capítulo 4. Presentación de resultados
4.3 Prácticas efectivas de la directora
4.3.1 Prácticas administrativas
One of the types of variations that can arise in recursive programs is that a loop in one can be unrolled in aotl-ter, or more generally, a recursion can be unfolded. This variation arises in our program examples when we convert the impure programs to pure ones (leaving no side effects to mutable objects). In this situation, special cases of a recursion sometimes translate to the general recursive case. This means that the general case is redundantly performed once, before the recursion is called.
For example, the code in Figure 427 destructively inserts Entry 'into the ordered asso-ciative list *Event-Queue*. It first tests for the special case in which Entry belongs on the front of the list (either because the list is empty or its first element has a lower priority than Entry). In this case, it destructively places Entry on the front of *Event-Queue* using push. Insert-Queue then performs the general case in which *Event-Queue* is searched for the place to insert Entry and then Entry i's spliced in at that place.
When this program is translated 'into its non-destructive version, shown in Figure 428, the special case head insertion becomes the same as the normal splice-in operation.
Insert-Queue-Pure can be rewritten as Folded-Insert-Queue, shown n Figure 429, in which the recursion is folded back up.
To deal with this type of variation, we provided an additional monitor to the flow graph parser, which looks for an opportunity to view a program that contains an nfolded recursion as one in which the recursion is folded back up. By generating this alternative view, the parser is then able to recognize the program as if it did not have a unfolded recursion. This augmentation of the parser with a new monitor tailors it to solve a problem specific to its application to the program recognition problem. This section describes the new monitor and how the new view is generated.
156
(defun Insert-Queue-Pure (Entry) (setq *Event-Queue*
(cond ((Empty-or-Low-Priority-Head? Entry *Event-Queue*) (cons Entry *Event-Queue*))
(t (cons (car *Event-Queue*)
(Splice-in Entry (cdr *Event-Queue*))))))) (defun Splice-In (Entry Next)
(cond ((Empty-or-Low-Priority-Head? Entry Next) (cons Entry Next))
(t (cons (car Next)
(Splice-In Entry (cdr Next))M)
Figure 428: Functional version of Insert-Queue.
(defun Folded-Insert-Queue (Entry)
(setq *Event-Queue* (Splice-In Entry *Event-Queue*))) (defun Splice-In (Entry Next)
(cond ((Empty-or-Low-Priority-Head? Entry Next) (cons Entry Next))
(t (cons (car Next)
(Splice-In Entry (cdr Next))))))
Figure 429: Version of Insert-Queue-Pure in which recursion is folded up.
157
,,e: ce2 ce: cel success-ci failure-ce
- -.1 I
I
I
I
I
I
I
I
I
I
I
I
I
I
I
I
I I
I
I I
I
I
I
I
I
I
I
I
I
I
I
I
--. i
Figure 430: Flow graph representing Isert-Queue-Pure.
I ce: ce2
ce-from:
ce2
158
[ce3j
Recursion information.- [recur-ce.- ce5, feedback-ce.- ce4, outside-ce.- ce3l
Figure 431: Partial ordering relationships between the control environments of Insert-Queue-Pure's flow graph.
Figure 430 shows the flow graph representation of Insert-Queue-Pure A dashed box is drawn around the boundary of the sub-flow graph representing its recursion. GRASPR generates an alternative view of this flow graph in which the recursion boundary is expanded outward and the redundant computation is collapsed together.
The way it works is based on the observation that when GRASPR tries to recognize an unfolded program, most of the constraints (structural as well as attribute conditions) are satisfied. Te only ones that are not are those that refer to the program's recursion in-formation (e.g., those constraining two ports to 'input-correspond or those referring to the feedback-ce of the recursion).
So, constraints are placed into two classes: regular ad recursion. When an item fails only its recursion constraints, it is suspended, which means it is placed in a holding data structure used by the new monitor. The monitor watches for another complete item, called a partner, to be added to the chart that can collapse with the suspended 'item. An item 1, can collapse with another item 1. if they are recognizing the same non-terminal type in control environments that are analogous. (This relation is defined below.) Collapsing two items means creating a new item which is the same as te sspended item, but whose constraints are checked in te context of the partner item.
Intuitively, two control environments are analogous if they contain operations that would collapse together if the recursion were folded back up. For example, Figure 4-31 shows the partial ordering of the control environments and recursion information for Insert-Queue-pure. The analogous pairs of control environments are el, ce5), (ce2, ce3), and (e3, ce4).
The aalogy relations are symmetric, but not reflexive, or transitive. Analogy relations between control environments are computed from the surface plan during its translation to an attributed flow graph.
Once a suspended item is collapsed with a partner, the new "collapsed" item is added to the agenda. Its constraints are satisfied because they refer to attributes of the sub-flow
159
graph matched by the partner item. The collapsed item's left-l-land side control environment attributes are computed by applying the rule's attribute-transfer rules in the context of the partner item and then translating them to the analogous control environment. Attribute-transfer rules that use recursion information in their computation are handled specially. In particular, if the rule computes the outside-ce of the innermost recursion containing some node, the control environment analogous to the recur-ce of this recursion is transferred.)
When a collapsed item is used to extend another item, it imposes new edge connection constraints on the items for adjacent non-terminals. Suppose a collapsed item I havi g partner IP extends another item to create an item IC, where IA is representing the derivation of non-terminal A in the right-hand side of IC's rule. If an item 1B for a non-terminal adjacent to A as a partner 1q, then p and Iq should be connected together in t1le same way as IA and IB.
The suspend-collapse-resume mechanism for recursion folding can be generalized to a
"try-liarder" technique for handling more types of near-misses besides those that fail recur-sion constraints. More classes of constraints can be 'identified. When an item fails certain classes of constraints, something might be done to cause them to be satisfied (e.g., changing an attribute) or weakened (e.g., changing a co-occurence condition between two nodes to a F condition). Then the item can be resumed simply by putting it back on the agenda. Te changes can be reported as conditions or assumptions under which some cliche' is recognized in the program.