Oz supports fine-grained constraints for the description of records as they are typically used in natural language processing with constraint-based grammars.
In Oz 1, one could only describe records whose label and arity was fully known, i.e., determined ones, using an equation like the following.
X = s(np:N vp:V)
The most important additional record constraint in Oz 2 is the
feature constraint X^Y = Z
. Such a constraint blocks
until Y
is determined and then constrains X
to denote a record whose arity includes feature Y
and
whose subtree at Y
is Z
. These constraints
are immediately available for further processing. For instance,
telling the constraints
X^np = N1 X^np = N2
results in equating N1
and N2
.
Nesting feature constraints yields what computational linguists call path equations:
VP^head^subject = NP^head
It is possible to fix the label of a record without giving any of its features. The constraint:
{TellRecord F X}
blocks until F
is a determined literal and then a
tells the store that X
is a record with label
F
.
There is a convenient notation for a labelling and a number of feature constraints which resembles the construction of a determined record. The statement:
X = f(a:Y b:Z ...)
is equivalent to the constraints:
{TellRecord f X} X^a = Y X^b = Z
As soon as the store contains a labelling or a feature constraint
for X
, this variable is known to denote a record. While
the type test {IsRecord X}
blocks until X
is
determined, the test:
{IsRecordC X}
reduces as soon as possible.
The procedures for record inspection:
{Label X} {HasFeature X f}
need no longer block until X
is determined. They
reduce as soon as the label of X
is known, respectively
as soon as X
is constrained to have
feature f
.
There is a record propagator which detects when new features have been added to a record.
{Record.monitorArity X P Ls}
connects the record X
to the stream Ls
(i.e., a non-terminated list). As soon as X
becomes known to have a feature F
, this feature appears
on the stream. Record.monitorArity
is a primitive from
which user-defined propagators can be derived: By observing
Ls
, one can react to new arity information.
P
is a nullary procedure that kills the primitive
propagator and disconnects R
from L
.