14.1 The Representation of SpeciesExpressions

A SpeciesExpression can either be an ExpressionTree, or failed, if it is not yet initialized. The representation of SpeciesExpression must allow destructive modification for our purposes, as used the constructors Plus and Times. We chose to ‘box’ the actual description of the expression using a Record.

441implementation: SpeciesExpression 441  (430)  442
Rep == Record(failed?: Boolean, tree: ExpressionTree);
import from Rep, Symbol, String;
import from ExpressionTreeLeaf, ExpressionTree, List ExpressionTree;

Uses ExpressionTree 624a, ExpressionTreeLeaf 623, and String 65.
ToDo 69
mrx 16 16-Dec-2006: Should I introduce a new type ACSymbol just to get rid of the following conditional?
442implementation: SpeciesExpression 441+   (430)  441  443
selfsym: Symbol == - "Self";
plussym: Symbol == - "Plus";
timessym: Symbol == - "Times";
exptsym: Symbol == - "Expt";
compsym: Symbol == - "Compose";

new(): %             == {
        selfop == ExpressionTreePrefix selfsym;
        per [true, selfop.[extree(leaf(1$Integer))$ExpressionTree]];
}

new(n: Integer): %   == {
        selfop == ExpressionTreePrefix selfsym;
        per [true, selfop.[extree(leaf n)$ExpressionTree]];
}

set!(f: %, g: %): () == {
        (rep f).failed? := (rep g).failed?;
        (rep f).tree    := (rep g).tree;
}
import from List %;
(f: %) + (g: %): % == apply(plussym, [f, g]);
(f: %) * (g: %): % == apply(timessym, [f, g]);
(f: %) ^ (g: %): % == apply(exptsym, [f, g]);
compose(f: %, g: %): % == apply(compsym, [f, g]);

leaf(n: Integer): % == per [false, extree(leaf n)$ExpressionTree];
leaf(s: String): % == per [false, extree(leaf s)$ExpressionTree];
leaf(x: Symbol): % == per [false, extree(leaf x)$ExpressionTree];

apply(opsym: Symbol, args: List %): % == {
        op == ExpressionTreePrefix opsym;
        per [false, op.[extree f for f in args]]
}

extree(f: %): ExpressionTree == (rep f).tree;

coerce(t: ExpressionTree): % == per [false, t];

Uses Compose 182a, ExpressionTree 624a, ExpressionTreePrefix 622, Integer 66, Plus 166a, String 65, and Times 175a.

In general, it is impossible to decide whether two SpeciesExpressions are equal. Thus we have to rely on heuristics and special cases.

ToDo 70
mrx 17 The test for equality is likely to become the most complex function of this domain. Maybe one could start to make it exact for rational SpeciesExpressions. Of course, it might make more sense to go for holonomic SpeciesExpressions immediately…
443implementation: SpeciesExpression 441+   (430)  442
(f: %) = (g: %): Boolean == extree f = extree g;