This note describes two aspects of the cpc(1) compiler. First, we describe
some of the checks performed by the compiler to guarantee that the constraint
picture is well-formed. Second, we describe some implicit restrictions placed
on box-patterns that improve the efficiency of the resulting IPQL program in
those cases where the constraint programmer was not as complete as they might
possibly have been.

WELL-FORMEDNESS CHECKS

We first list the well-formedness conditions on constraint pictures:

1. All boxes "square" to page
2. No dangling arrows
3. All arrow endpoints associated with unique boxes
4. Every starred box pattern contained in at least one other box pattern
5. The containment graph on box patterns is acyclic
6. No box pattern is marked both a "subject" and an "object"

Conditions (1)-(3) are enforced by the editor. Condition (4) is checked by
cpc(1) in the routine compile.StarredBoxNotContained(). Condition (5) is
checked by cpc(1) in the routine compile.ContainmentCycle().

Boxes are marked as "subject" and/or "object" boxes by cpc(1) in the routine
compile.MarkLeftRight(); this routine also checks that no box is marked as
both a "subject" and as an "object". It works as follows. If a box is at the
tail of a syntax or semantics arrow, it is marked as a "subject"; if it is at
the head of such an arrow, it is marked as an "object". Furthermore, if there
is a simple predicate on the "type" attribute in the box's predicate, and if
that predicate can be used to establish whether the box is a "subject" or an
"object" it is used (see the procedure compile.SideFromType()). Finally, the
"transitive closure" of these markings is taken over containment arrows.

The compiler cpc(1) performs other well-formedness checks. Within each box
predicate, it checks that each attribute is compared to a value of the proper
type (see compile.CheckTypes()). It also guarantees that all uses of a
variable are compared with values of consistent types.

Finally, cpc(1) forms a set of "intervals" for each box pattern. There is one
interval in the set for each attribute named in the box's predicate. If any of
the intervals is *empty*, a static error occurs.

ADDITIONAL IMPLICIT RESTRICTIONS

The compiler installs implicit "type" and "atomic" intervals automatically. It
infers these intervals from the "context" of the box. For example, for any box
pattern marked as a "subject" during the well-formedness check, we can assert
that any instance box matching that box pattern must have a type that is a
strict subtype of subject. Similarly for boxes marked as "object" boxes.

Finally, if a box pattern has a semantics arrow incident upon it, then we can
assert that any instance box matching that box pattern must be atomic.
Similarly, if a box pattern has a containment arrow (starred or unstarred)
pointing *to* it, then we may assert that any instance box matching that box
pattern must *not* be atomic.

By installing these implicit intervals, the compiler reduces the boxes it must
consider. Moreover, the compiler may discover static errors that would not
have been discovered otherwise. For example, if some box pattern has a
semantics arrow incident on it and a containment arrow pointing at it, then no
instance box can match that box pattern, so the constraint picture is trivial,
i.e., it is matched either by every instance picture (if the inconsistent box
is thick) or by no instance picture (if the inconsisten box is thin and the
lower range value is > 1).
