```//[[Documentation]]

*Guards

**Rules with a Guard

Guards specify applicability conditions of rewrite rules.  The syntax of a rule with a guard is:
>'''Head''' :- '''Guard''' | '''Body'''

where '''Guard''' is a multiset of ''type constraints'' of the form
'''c'''(\$'''p'''&size(10){1};, ..., \$'''p'''&size(10){'''n'''};).

Type constraints constrains the shapes of processes
(or the names of unary atoms)
received by the process contexts \$'''p'''&size(10){1};, ..., \$'''p'''&size(10){'''n'''};.
The ''type constraint name'' '''c''' is drawn from a built-in set and specifies which kind of constraints is imposed.

A constraint of the form ''uniq''(\$'''p'''&size(10){1};, ..., \$'''p'''&size(10){'''n'''};) is
also allowed.  This is a control structure rather than a type constraint
and used to avoid infinite rule application (see below).

***Examples

Here is an example rule with guard:

waitint(X), \$p[X] :- int(\$p) | ok.

This can be abbreviated to

waitint(\$p) :- int(\$p) | ok.

and can be thought of representing the following infinite number of rules:

waitint(0)  :- ok.
waitint(1)  :- ok.
waitint(-1) :- ok.
waitint(2)  :- ok.
waitint(-2) :- ok.
...

The following are examples of some type constraints that can be written in '''Guard''':

-&color(#8B4513){int(\$p)}; ... specifies that \$p must be an integer atom.
-&color(#8B4513){4(\$p)}; ... specifies that \$p must be a unary integer atom of value 4 (i.e., 4(X)).
-&color(#8B4513){\$p < \$q}; ... specifies that \$p and \$q are integer atoms
such that the value of \$p is less than that of \$q.
-&color(#8B4513){\$r = \$p +. \$q}; ... specifies that \$p, \$q, and \$r are floating
point number atoms such that the sum of the values of \$p and \$q is equal to the value of \$r.

***Notes

Each type constraint name (such as int or <)
has its own mode of usage
that specifies which of its arguments are input arguments.
The effect of the constraint specified by a type constraint
is enabled only after the shapes (or values)
of its input arguments are all determined.
For example, \$r = \$p + \$q proceeds only when \$p and \$q are determined.

The same abbreviation scheme as defined for atoms
applies to type constraints when a process context name
\$'''p'''&size(10){'''k'''};
occurs exactly twice in the rule.
For example, p(\$n) :- \$n>\$z, 0(\$z) | ok can be abbreviated
to p(\$n) :- \$n>0 | ok.

**Typed Process Contexts

A process context constrained in '''Guard'''
is said to be a ''typed process context''.
// As a syntactic sugar,
// typed process context names can be written as link names.
// For inscance, the above example can be written as:
//  waitint(X) :- int(X) | ok.
// // ( Res = gen(N) :- N > 0 | Res = [N|gen(N-1)] ), p(gen(10))
// However, the original form, waitint(\$p) :- int(\$p) | ok, is preferred
// because, unlike link names, typed process context names has no constraints
// on the number of their occurrences.

**Avoiding Infinite Rule Application

A constraint of the form
''uniq''(\$'''p'''&size(10){1};, ..., \$'''p'''&size(10){'''n'''};)
succeeds if each \$'''p'''&size(10){'''k'''}; is a '''ground''' structure
(connected graph with exactly one free link; see below)
and the rule has not
been applied to the tuple
\$'''p'''&size(10){1};, ..., \$'''p'''&size(10){'''n'''};
before.

As a special case of '''n'''=0,
''uniq'' succeeds if the rule in question has not been used
before.  The ''uniq''() test is a general tool for avoiding
infinite application of rules whose right-hand side is a
super(multi)set of the left-hand side.

**Guard Library

The following type constraints can be used in guards.
The + (input) sign preceding a process context name means that the name should
appear in the head, while the - (output) sign means that the name should not
appear in the head.

***Type checking

:int(+\$i)|check if \$i[X] is an integer.
:float(+\$f)|check if \$f[X] is a floating-point number.
:unary(+\$u)|check if \$u[X] is a unary atom.  Note that ''int'' and ''float'' are subtypes of ''unary''.
:ground(+\$g)|check if \$g[X1,...,Xn] (n>0) is a connected graph whose free links are exactly X1,...,Xn.  Note that ''unary'' is a subtype of ''ground''.

***Comparison

:'='(+\$u,+\$v)|check if \$u[X1,...,Xn] and \$v[Y1,...,Yn] are connected graphs with the same structure.
:'\='(+\$u,+\$v)|check if \$u[X1,...,Xn] and \$v[Y1,...,Ym] are connected graphs with different structures.
:'=='(+\$u,+\$v)|check if \$u[X] and \$v[Y] are unary atoms with the same name.
:'\=='(+\$u,+\$v)|check if \$u[X] and \$v[Y] are unary atoms with different names
(if either of them are not unary, the check fails.)
:'<.'(+\$float,+\$float)|float comparison;   also: ''&color(#8B4513){'>.'};'', ''&color(#8B4513){'=<.'};'', ''&color(#8B4513){'>=.'};'', ''&color(#8B4513){'=:=.'};'', ''&color(#8B4513){'=\=.'};''.
:'<'(+\$int,+\$int)|integer comparison; also: ''&color(#8B4513){'>'};'', ''&color(#8B4513){'=<'};'', ''&color(#8B4513){'>='};'', ''&color(#8B4513){'=:='};'', ''&color(#8B4513){'=\='};''.
***Assignment

:'='(+\$u,-\$v)|make sure that \$u[X] and \$v[Y] are unary atoms with the same name.
:'='(-\$u,+\$v)|same as above.
:int(+\$float,-\$int)|cast to int.
:float(+\$int,-\$float)|cast to float.
:345(-\$int)|defined for every integer (not only with 345).
:'-3.14'(-\$float)|defined for every float.
:'+'(+\$int,+\$int,-\$int)|integer operation;  also: ''&color(#8B4513){'-'};'', ''&color(#8B4513){'*'};'', ''&color(#8B4513){'/'};'', ''&color(#8B4513){mod};''.
:'+.'(+\$float,+\$float,-\$float)|float operation;    also: ''&color(#8B4513){'-.'};'', ''&color(#8B4513){'*.'};'', ''&color(#8B4513){'/.'};''.

***Others
:uniq(+\$g1,...,+\$gn)|uniqueness constraint; checks if the rule has not been applied to the tuple \$g1[X1], ..., \$gn[Xn] (n>=0).

```