This section presents a simplified implementation of conversions and conversionals to convey the general ideas. Later sections describe the actual conversions that are implemented. Note however that the conversionals introduced here have the same names and same behaviours as those in the actual system.
Let
convn be an ML
concrete type alias for the type of
conversions.
In this section, assume that
convn is an
alias for the type
term -> term, where
term is a type of
terms that we want to rewrite.
Later on, I describe the type that
convn is
actually an alias for.
If c is of type
convn, then we
can use c to rewrite t of type
term by simply running the
ML
evaluator on the application
.
For the purposes of the section only, let me introduce a basic conversion
called
RuleC : term -> convn. The conversion
RuleC
expects its term argument to be of form a = b where the free
variables of b are a subset of those in a.
If the conversion
RuleC 'a = b'
is applied to a term t,
RuleC tries to find a
substitution
such
that
. If it succeeds, it returns the term
.
If a substitution cannot be found,
RuleC raises an exception
.
The conversion
RuleC 'a = b' therefore rewrites instances of a to
corresponding instances of b. For example:
RuleC 'x + 0 = x'
when applied to the term
yields the term
.
RuleC cannot by itself rewrite subterms of a term; if
RuleC 'x + 0 = x'
is applied to the term
, it fails. There
are a variety of higher-order conversions that map a conversion such
as
RuleC over all subterms of a term. An example of a
conversional is
SweepUpC : convn -> convn . If c is a
conversion, then
SweepUpC c is also a conversion. if
SweepUpC c is applied to some term t, an attempt is made to apply c once to each subterm of t working from the leaves of term t up to its root. SweepUpC c only fails every every application of c fails. So if
is applied to term
, it succeeds and returns the term
.
The basic conversion for sequencing conversions is
ANDTHENC : convn -> convn
-> convn. In , we reserve all-capital names for infix
functions so a normal application of
ANDTHENC to conversions
and
has form
ANDTHENC
. When applied to a
term t,
ANDTHENC
first applies
to t. If
succeeds, returning a term
, then
is applied to
and the result is returned. If either
or
fails, then
ANDTHENC
also fails. By analogy with tacticals being
higher-order tactics,
ANDTHENC is called a conversional.
The
ORELSEC : convn -> convn -> convn conversional is
for combining alternative conversions. When
ORELSEC
is
applied to a term t, it first tries applying
to t, and
if this succeeds returns the result. If the application of
fails,
then it tries applying
to t, failing if
fails.
The definition for SweepUpC is:
![]()
SubC : convn -> convn when applied to a conversion c
and a term t, applies c to each of the immediate subterms of t.
It fails only when c fails on every immediate subterm
. Hence, it
always fails when t is a leaf node and has no immediate subterms.
ORTHENC
is similar to
ANDTHENC
in
that it first tries
and then
. However
ORTHENC only
fails if both
and
fail. So, a call of
SweepUpC c on
argument t first tries to apply
SweepUpC c to the immediate
subterms of t and then then tries to apply c to t itself.
Note that without the
t argument on the left and right sides
of the definition,
SweepUpC in ML's call-by-value evaluation scheme
would recurse indefinitely.
The definition for ORTHENC is:
let c1 ORTHENC c2 = (c1 ANDTHENC TryC c2) ORELSEC c2 where TryC c is defined as c ORELSE IdC and IdC: convn, when applied to any t, always returns t.
Other conversionals that are commonly used in the work described in this thesis are:
![]()
![]()