s_(zero) s_(sd(N:Nat, M:Nat)) p(s_(zero)) _+_(N:Nat, M:Nat)
The application of an operator declared with mixfix form also has a mixfix syntax: the operator's mixfix name with each underscore replaced by the corresponding term from the argument list. The mixfix form of the above examples is
s zero s sd(N:Nat, M:Nat) p(s zero) N:Nat + M:Nat
The kind of a term
is the result kind of its topmost operator. For
example, the kind of p(s zero) is [Nat], since
Nat is the result sort of p. If a module's grammar is
unambiguous (see the discussion on parsing in the following section), then each
term has a single kind. But we can also associate sorts to terms.
In general, even if the grammar is unambiguous, a term may have several sorts, due
to the subsort ordering. Specifically, constants have the sort they are
declared with and any supersort of it. Given a term of the form
,
if
has sort
for
and there is an operator declaration
, then the term
has sort
and any of its supersorts. For example, in our example
NUMBERS module the term s s 0 has sorts NzNat and
Nat.
A very desirable property of a module is that each term has a least sort
that can be assigned to it. Such a
least sort gives us the most detailed information on how to classify
such a term as a data element. For example, the least sort of the
term s s 0 is NzNat, and this gives us the most
precise classification of such a term in the sort hierarchy. Given an
arbitrary signature
, we can have terms that fail to have a
least sort. However, if
satisfies a
simple syntactic property called
preregularity [43],
we can guarantee that any
-term will have a least sort.
We call
preregular if for each
, given an
-argument
function symbol
and sorts
such that
is a well-formed
-term,
then there is a least sort
among all the sorts
appearing
in (possibly overloaded) operator declarations of the form
in
such that
for
we have
. For example, the
signature
sorts A B C D . subsorts A < B C < D . op a : -> A . op f : B -> B . op f : C -> C .
fails to be preregular, because for the sort A the term f(X:A) is a well-formed term, but there is no least sort for the result of f with arguments greater or equal to A, since either B or C can be chosen as result sorts, and they are incomparable in the sort hierarchy. As a consequence, both f(X:A) and f(a) do not have a least sort: they have sorts B, C, and D, and B and C are minimal sorts among those sorts.
As already mentioned in Section 3.4 for the assoc
attribute and further explained in Section 4.4.1, operators
can be declared with equational axioms such as associativity
(assoc), commutativity (comm), and identity
(id:). This means that, if we denote by
the
corresponding associativity and/or commutativity, and/or identity
equations, we are not really interested in syntactic terms
, but
rather in equivalence classes modulo
, that is, in the
equivalence class
of each term
, since all representatives of the
class are viewed as equivalent representations. Preregularity
modulo
now means that we can assign a least sort not just
to any well-formed term
, but also to its equivalence class
. As further explained in Section 13.2.5, Maude
assumes that modules are preregular modulo whatever axioms such as
assoc, comm, and id: have been declared for operators,
checks syntactic conditions ensuring preregularity modulo
, and
generates warnings when a module fails to satisfy such preregularity conditions.
A ground term
is a term containing no variables: only constants and
operators. Intuitively, ground terms denote either data in case no equations
apply to the term (for example, s zero is data) or functional
expressions indicating how an equationally defined function is applied to data (for
example, (s zero) + (s zero)). Ground terms modulo equations
constitute the initial algebra associated with a specification, as discussed later in
Section 4.3.