The first way, called subasm-call is visualized in Figure 3. If an asm A uses B as sub-asm, it means that B - possibly together with arguments, if the arity of B>0 - is used as a rule in the body of A. If this rule fires, the rules of asm B fire, which may result in updating locations of functions declared in A. The sub-asm-use relation between asms may contain cycles; lazy evaluation techniques are used to avoid an infinite number of rules. The call as subasm is illustrated in the figure. The sub-asm B and its parent asm A step simultaneously; formally they can be seen as one single ASM.
The second way, called function call is visualized in Figure 4. Asm A uses B as a function, if B is defined as in A. In this case, B - possibly together with arguments, if the arity of B>0 - is used as a term in the body of A. Recursion is allowed, so that the function-use relation between asms may contain cycles. The call as function is illustrated in the figure. During the run of the function-asm B, its parent A doesn't make any step; from A's point of view B's run happens in zero time. As depicted in the figure, B behaves like a ``normal'' asm, the iterations shown here are caused by the steps of the B-asm itself.
In each of the above cases, we call A the parent-asm of B, if A uses B as sub-asm or as function. In any case, the asm must be declared in the parent asm. As part of its meta information, an asm can be marked as a function or as a sub-asm, so that it can only be used by other asms in the specified way. For example, if B and C are asms defined as follows
then B can only be used as function and C as sub-asm in other asms. This is reflected by corresponding declarations of B and C: