Search in sources :

Example 66 with Operator

use of gov.sandia.n2a.language.Operator in project n2a by frothga.

the class EquationSet method dump.

public String dump(boolean showNamespace, String pad) {
    Renderer renderer = new Renderer() {

        public boolean render(Operator op) {
            if (!(op instanceof AccessVariable))
                return false;
            AccessVariable av = (AccessVariable) op;
            if (av.reference == null || av.reference.variable == null) {
                if (showNamespace)
                    result.append("<unresolved!>");
                result.append(av.name);
            } else {
                if (showNamespace)
                    result.append("<" + av.reference.variable.container.prefix() + ">");
                result.append(av.reference.variable.nameString());
            }
            return true;
        }
    };
    renderer.result.append(pad + name + "\n");
    pad = pad + " ";
    if (connectionBindings != null) {
        for (ConnectionBinding c : connectionBindings) {
            renderer.result.append(pad + c.alias + " = ");
            EquationSet s = c.endpoint;
            if (showNamespace) {
                renderer.result.append("<");
                if (s.container != null) {
                    renderer.result.append(s.container.prefix());
                }
                renderer.result.append(">");
            }
            renderer.result.append(s.name + "\n");
        }
    }
    for (Variable v : variables) {
        // If no equations, then this is an implicit variable, so no need to list here.
        if (v.equations.size() == 0)
            continue;
        // Phase indicators are always present, and thus uninformative.
        if (v.name.equals("$connect") || v.name.equals("$init") || v.name.equals("$live"))
            continue;
        renderer.result.append(pad + v.nameString());
        renderer.result.append(" =" + v.combinerString());
        if (v.equations.size() == 1) {
            renderer.result.append(" ");
            v.equations.first().render(renderer);
            renderer.result.append("\n");
        } else {
            renderer.result.append("\n");
            for (EquationEntry e : v.equations) {
                renderer.result.append(pad + " ");
                e.render(renderer);
                renderer.result.append("\n");
            }
        }
    }
    for (EquationSet e : parts) {
        renderer.result.append(e.dump(showNamespace, pad));
    }
    return renderer.result.toString();
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) AccessVariable(gov.sandia.n2a.language.AccessVariable) Renderer(gov.sandia.n2a.language.Renderer)

Example 67 with Operator

use of gov.sandia.n2a.language.Operator in project n2a by frothga.

the class Variable method convertToGlobal.

/**
 *        If resolution path starts with a connection, then convert it to a walk through containers instead.
 */
public void convertToGlobal() {
    reference.convertToGlobal(this);
    visit(new Visitor() {

        public boolean visit(Operator op) {
            if (op instanceof AccessVariable) {
                AccessVariable av = (AccessVariable) op;
                av.reference.convertToGlobal(Variable.this);
                return false;
            }
            return true;
        }
    });
}
Also used : Operator(gov.sandia.n2a.language.Operator) Visitor(gov.sandia.n2a.language.Visitor) AccessVariable(gov.sandia.n2a.language.AccessVariable)

Example 68 with Operator

use of gov.sandia.n2a.language.Operator in project n2a by frothga.

the class Variable method simplify.

public boolean simplify() {
    changed = false;
    TreeSet<EquationEntry> nextEquations = new TreeSet<EquationEntry>();
    EquationEntry defaultEquation = null;
    EquationEntry alwaysTrue = null;
    visited = null;
    for (EquationEntry e : equations) {
        if (e.expression != null) {
            e.expression = e.expression.simplify(this, false);
        }
        if (e.condition == null) {
            defaultEquation = e;
        } else {
            e.condition = e.condition.simplify(this, false);
            e.ifString = e.condition.render();
        }
        if (e.expression instanceof AccessVariable) {
            if (// Vacuous assignment
            ((AccessVariable) e.expression).reference.variable == this) {
                // Simulator always copies value to next cycle when no equation fires,
                // so there is never need for an explicit equation to do this.
                changed = true;
                e.expression.releaseDependencies(this);
                if (e.condition == null)
                    defaultEquation = null;
                else
                    e.condition.releaseDependencies(this);
                continue;
            }
        } else if (e.condition instanceof Constant) {
            if (// Will never fire
            e.condition.getDouble() == 0) {
                // Drop equation
                changed = true;
                if (e.expression != null)
                    e.expression.releaseDependencies(this);
                continue;
            } else // Will always fire
            {
                if (alwaysTrue == null)
                    alwaysTrue = e;
            }
        }
        nextEquations.add(e);
    }
    if (// alwaysTrue requires an explicit (non-null) condition. The default equation is never selected.
    !nextEquations.isEmpty() && nextEquations.first() == alwaysTrue) {
        changed = true;
        equations.clear();
        equations.add(alwaysTrue);
        for (EquationEntry e : nextEquations) {
            if (e == alwaysTrue)
                continue;
            if (e.expression != null)
                e.expression.releaseDependencies(this);
            if (e.condition != null)
                e.condition.releaseDependencies(this);
        }
        // Make the equation unconditional, since it always fires anyway.
        EquationEntry e = equations.first();
        e.condition = null;
        e.ifString = "";
    } else {
        equations = nextEquations;
        if (equations.isEmpty()) {
            if (hasAttribute("temporary")) {
                changed = true;
                addAttribute("constant");
                EquationEntry e = new EquationEntry(this, "");
                equations.add(e);
                // This is the default value for a temporary when no equation fires.
                e.expression = new Constant(0);
            }
        } else if (equations.size() > 1) {
            // contract with the user allows us to choose another equation instead.
            if (defaultEquation != null && defaultEquation.expression instanceof Constant) {
                nextEquations = new TreeSet<EquationEntry>();
                nextEquations.add(defaultEquation);
                // Add any equations that don't match the default equation.
                for (EquationEntry e : equations) {
                    if (!(e.expression instanceof Constant) || !((Constant) defaultEquation.expression).value.equals(((Constant) e.expression).value)) {
                        nextEquations.add(e);
                    }
                }
                equations = nextEquations;
            }
        }
    }
    // Check if we have become eligible to execute in the global context.
    // Only applies to external write references.
    // for convenience
    Variable rv = reference.variable;
    if (rv.container != container && rv.hasAttribute("global") && !hasAny("global", "local")) {
        class CheckGlobal implements Visitor {

            boolean allGlobal = true;

            public boolean visit(Operator op) {
                if (op instanceof AccessVariable) {
                    AccessVariable av = (AccessVariable) op;
                    Variable target = av.reference.variable;
                    if (!target.hasAttribute("global"))
                        allGlobal = false;
                }
                return allGlobal;
            }
        }
        CheckGlobal check = new CheckGlobal();
        visit(check);
        if (check.allGlobal) {
            changed = true;
            addAttribute("global");
            convertToGlobal();
        }
    }
    // This is a special case needed by some models that use pins.
    if (// Note: uses can be null when "externalWrite" is set. This can happen during EquationSet.simplify().
    uses != null && hasAttribute("externalWrite")) {
        // Determine if self is constant.
        boolean constant = equations.isEmpty();
        boolean replaced = false;
        double value = 0;
        if (!constant && equations.size() == 1) {
            EquationEntry e = equations.first();
            if (e.condition == null && e.expression.isScalar()) {
                constant = true;
                replaced = true;
                value = e.expression.getDouble();
            }
        }
        if (constant) {
            // Scan all our writers to see if they are constant.
            for (Variable u : uses.keySet()) {
                if ((assignment == ADD || assignment == MULTIPLY || assignment == DIVIDE) && !u.isSingletonRelativeTo(container)) {
                    // Can't predict how many of these operations there will be at run time,
                    // so can't predict result.
                    constant = false;
                    break;
                }
                if (!u.hasAttribute("constant")) {
                    constant = false;
                    break;
                }
                double uvalue = u.equations.first().expression.getDouble();
                switch(assignment) {
                    case ADD:
                        value += uvalue;
                        break;
                    case MULTIPLY:
                        value *= uvalue;
                        break;
                    case DIVIDE:
                        value /= uvalue;
                        break;
                    case MIN:
                        value = Math.min(value, uvalue);
                        break;
                    case MAX:
                        value = Math.max(value, uvalue);
                        break;
                    default:
                        // REPLACE
                        if (value != uvalue) {
                            if (replaced) {
                                // Can only set the value once.
                                constant = false;
                            } else {
                                replaced = true;
                                value = uvalue;
                            }
                        }
                }
                if (!constant)
                    break;
            }
        }
        if (constant) {
            changed = true;
            EquationEntry e;
            if (equations.isEmpty()) {
                e = new EquationEntry(this, "");
                equations.add(e);
            } else {
                e = equations.first();
            }
            e.expression = new Constant(value);
            addAttribute("constant");
            removeAttribute("externalWrite");
            removeDependencies();
        }
    }
    return changed;
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) AccessVariable(gov.sandia.n2a.language.AccessVariable) Visitor(gov.sandia.n2a.language.Visitor) TreeSet(java.util.TreeSet) Constant(gov.sandia.n2a.language.Constant)

Example 69 with Operator

use of gov.sandia.n2a.language.Operator in project n2a by frothga.

the class Variable method dependsOnEvent.

protected boolean dependsOnEvent(Variable from) {
    // Prevent infinite recursion
    Variable p = from;
    while (p != null) {
        if (p == this)
            return false;
        p = p.visited;
    }
    visited = from;
    // Scan temporary variables we depend on
    if (uses != null) {
        for (Variable u : uses.keySet()) {
            if (!u.hasAttribute("temporary"))
                continue;
            if (u.dependsOnEvent(this))
                return true;
        }
    }
    // Scan equations
    class EventVisitor implements Visitor {

        boolean found;

        public boolean visit(Operator op) {
            if (op instanceof Event)
                found = true;
            return !found;
        }
    }
    EventVisitor visitor = new EventVisitor();
    visit(visitor);
    return visitor.found;
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) Visitor(gov.sandia.n2a.language.Visitor) Event(gov.sandia.n2a.language.function.Event)

Example 70 with Operator

use of gov.sandia.n2a.language.Operator in project n2a by frothga.

the class Draw method determineExponentNext.

public void determineExponentNext() {
    for (int i = 0; i < operands.length; i++) {
        Operator op = operands[i];
        op.exponentNext = op.exponent;
        op.determineExponentNext();
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator)

Aggregations

Operator (gov.sandia.n2a.language.Operator)104 AccessVariable (gov.sandia.n2a.language.AccessVariable)41 Constant (gov.sandia.n2a.language.Constant)37 Visitor (gov.sandia.n2a.language.Visitor)26 Variable (gov.sandia.n2a.eqset.Variable)17 ArrayList (java.util.ArrayList)16 Type (gov.sandia.n2a.language.Type)14 Scalar (gov.sandia.n2a.language.type.Scalar)14 Output (gov.sandia.n2a.language.function.Output)13 EquationSet (gov.sandia.n2a.eqset.EquationSet)12 EquationEntry (gov.sandia.n2a.eqset.EquationEntry)10 Input (gov.sandia.n2a.language.function.Input)10 Text (gov.sandia.n2a.language.type.Text)10 Matrix (gov.sandia.n2a.language.type.Matrix)9 TreeSet (java.util.TreeSet)9 ReadMatrix (gov.sandia.n2a.language.function.ReadMatrix)8 Add (gov.sandia.n2a.language.operator.Add)8 BuildMatrix (gov.sandia.n2a.language.BuildMatrix)7 Event (gov.sandia.n2a.language.function.Event)7 Instance (gov.sandia.n2a.language.type.Instance)7