Search in sources :

Example 11 with AccessVariable

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

the class EquationSet method findInitOnlyRecursive.

public boolean findInitOnlyRecursive() {
    boolean changed = false;
    for (EquationSet s : parts) {
        if (s.findInitOnlyRecursive())
            changed = true;
    }
    ReplaceInit replaceInit = new ReplaceInit();
    for (final Variable v : variables) {
        // Note: some variables get tagged "initOnly" by other means, so don't re-process
        if (v.hasAny(new String[] { "initOnly", "constant", "dummy" }))
            continue;
        // Count equations
        int firesDuringInit = 0;
        int firesDuringUpdate = 0;
        // If we have a single update equation, then we may still be initOnly if it depends only on constants or other initOnly variables. Save the update equation for analysis.
        EquationEntry update = null;
        for (EquationEntry e : v.equations) {
            if (e.condition == null) {
                firesDuringInit++;
                firesDuringUpdate++;
                update = e;
            } else {
                // init
                replaceInit.init = 1;
                replaceInit.live = 1;
                Operator test = e.condition.deepCopy().transform(replaceInit).simplify(v);
                boolean fires = true;
                if (test instanceof Constant) {
                    Constant c = (Constant) test;
                    if (c.value instanceof Scalar && ((Scalar) c.value).value == 0)
                        fires = false;
                }
                if (fires)
                    firesDuringInit++;
                // update
                replaceInit.init = 0;
                replaceInit.live = 1;
                test = e.condition.deepCopy().transform(replaceInit).simplify(v);
                fires = true;
                if (test instanceof Constant) {
                    Constant c = (Constant) test;
                    if (c.value instanceof Scalar && ((Scalar) c.value).value == 0)
                        fires = false;
                }
                if (fires) {
                    firesDuringUpdate++;
                    update = e;
                }
            }
        }
        if (firesDuringUpdate == 0) {
            if (firesDuringInit > 0 && v.derivative == null) {
                v.addAttribute("initOnly");
                changed = true;
            }
        } else if (// last chance to be "initOnly": must be exactly one equation that is not a combining operator
        firesDuringUpdate == 1 && v.assignment == Variable.REPLACE) {
            // Determine if our single update equation depends only on constants and initOnly variables
            class VisitInitOnly extends Visitor {

                // until something falsifies it
                boolean isInitOnly = true;

                public boolean visit(Operator op) {
                    if (isInitOnly) {
                        if (op instanceof AccessVariable) {
                            AccessVariable av = (AccessVariable) op;
                            // constant has already been replaced. Therefore, only the "initOnly" attribute matters here.
                            if (av.reference == null || av.reference.variable == null)
                                isInitOnly = false;
                            Variable r = av.reference.variable;
                            if (!r.hasAttribute("initOnly"))
                                isInitOnly = false;
                            // Also verify that the variables we depend on are available during the appropriate phase of init
                            if (// Note that temporaries are always available.
                            isInitOnly && !r.hasAttribute("temporary")) {
                                if (// we are a $variable, so we can only depend on $index and $init
                                v.name.startsWith("$")) {
                                    if (!"$index,$init,$live".contains(r.name))
                                        isInitOnly = false;
                                } else // we are a regular variable, so can only depend on $variables
                                {
                                    if (!r.name.startsWith("$"))
                                        isInitOnly = false;
                                }
                            }
                        } else if (op instanceof Function) {
                            Function f = (Function) op;
                            if (!f.canBeInitOnly())
                                isInitOnly = false;
                        }
                    }
                    return isInitOnly;
                }
            }
            VisitInitOnly visitor = new VisitInitOnly();
            if (update.condition != null)
                update.condition.visit(visitor);
            if (visitor.isInitOnly) {
                update.expression.visit(visitor);
                if (visitor.isInitOnly) {
                    v.addAttribute("initOnly");
                    changed = true;
                }
            }
        }
        if (firesDuringUpdate > 0 && v.derivative != null && !v.hasAttribute("initOnly"))
            v.addAttribute("updates");
        else
            v.removeAttribute("updates");
    }
    return changed;
}
Also used : Operator(gov.sandia.n2a.language.Operator) Function(gov.sandia.n2a.language.Function) AccessVariable(gov.sandia.n2a.language.AccessVariable) AccessVariable(gov.sandia.n2a.language.AccessVariable) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 12 with AccessVariable

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

the class EquationSet method determineTypesEval.

public boolean determineTypesEval() {
    boolean changed = false;
    for (final Variable v : variables) {
        if (v.hasAttribute("constant"))
            continue;
        if ((v.name.startsWith("$") || v.name.contains(".$")) && !v.name.startsWith("$up."))
            continue;
        Type value;
        if (// and v is not "constant", but that is covered above
        v.derivative != null) {
            // this should exist, so no need to verify result
            value = find(new Variable(v.name, v.order + 1)).type;
        } else {
            Instance instance = new Instance() {

                // all AccessVariable objects will reach here first, and get back the Variable.type field
                public Type get(VariableReference r) throws EvaluationException {
                    return r.variable.type;
                }
            };
            // can return null if no equation's condition is true
            value = v.eval(instance);
        }
        if (value != null && value.betterThan(v.reference.variable.type)) {
            v.reference.variable.type = value;
            // convenience, so that a reference knows its type, not merely its target
            v.type = value;
            changed = true;
        }
    }
    for (EquationSet s : parts) {
        if (s.determineTypesEval())
            changed = true;
    }
    return changed;
}
Also used : Type(gov.sandia.n2a.language.Type) AccessVariable(gov.sandia.n2a.language.AccessVariable) Instance(gov.sandia.n2a.language.type.Instance)

Example 13 with AccessVariable

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

the class EquationSet method dump.

public String dump(boolean showNamespace, String prefix) {
    Renderer renderer;
    if (showNamespace) {
        class Prefixer extends Renderer {

            public boolean render(Operator op) {
                if (!(op instanceof AccessVariable))
                    return false;
                AccessVariable av = (AccessVariable) op;
                if (av.reference == null || av.reference.variable == null) {
                    result.append("<unresolved!>" + av.name);
                } else {
                    result.append("<" + av.reference.variable.container.prefix() + ">" + av.reference.variable.nameString());
                }
                return true;
            }
        }
        renderer = new Prefixer();
    } else {
        renderer = new Renderer();
    }
    renderer.result.append(prefix + name + "\n");
    prefix = prefix + " ";
    if (connectionBindings != null) {
        for (ConnectionBinding c : connectionBindings) {
            renderer.result.append(prefix + 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 (// If no equations, then this is an implicit variable, so no need to list here.
        v.equations.size() > 0) {
            renderer.result.append(prefix + 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(prefix + " ");
                    e.render(renderer);
                    renderer.result.append("\n");
                }
            }
        }
    }
    for (EquationSet e : parts) {
        renderer.result.append(e.dump(showNamespace, prefix));
    }
    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 14 with AccessVariable

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

the class Variable method simplify.

public boolean simplify() {
    if (equations == null)
        return false;
    changed = false;
    TreeSet<EquationEntry> nextEquations = new TreeSet<EquationEntry>();
    TreeSet<EquationEntry> alwaysTrue = new TreeSet<EquationEntry>();
    for (EquationEntry e : equations) {
        if (e.expression != null) {
            e.expression = e.expression.simplify(this);
        }
        if (e.condition != null) {
            e.condition = e.condition.simplify(this);
            e.ifString = e.condition.render();
        }
        if (e.condition instanceof Constant) {
            Constant c = (Constant) e.condition;
            if (c.value instanceof Scalar) {
                double value = ((Scalar) c.value).value;
                if (value == 0) {
                    // Drop equation because it will never fire.
                    changed = true;
                    continue;
                }
                alwaysTrue.add(e);
            }
        } else if (e.ifString.isEmpty() && e.expression instanceof AccessVariable && ((AccessVariable) e.expression).reference.variable == this) {
            // Drop this default equation because it is redundant. Simulator always copies value to next cycle when no equation fires.
            changed = true;
            continue;
        }
        nextEquations.add(e);
    }
    if (// Default equation will never be included in alwaysTrue.
    alwaysTrue.size() == 1) {
        changed = true;
        equations = alwaysTrue;
        // Make the equation unconditional, since it always fires anyway.
        EquationEntry e = equations.first();
        e.condition = null;
        e.ifString = "";
    } else {
        equations = nextEquations;
    }
    return changed;
}
Also used : AccessVariable(gov.sandia.n2a.language.AccessVariable) TreeSet(java.util.TreeSet) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 15 with AccessVariable

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

the class ExportJob method analyze.

/**
 *        Find references to $index in connection endpoints, and set up info for ConnectionContext.
 */
public void analyze(EquationSet s) {
    for (EquationSet p : s.parts) analyze(p);
    for (final Variable v : s.variables) {
        Visitor visitor = new Visitor() {

            public boolean visit(Operator op) {
                if (op instanceof AccessVariable) {
                    VariableReference r = ((AccessVariable) op).reference;
                    Variable rv = r.variable;
                    if (rv.container != v.container && !r.resolution.isEmpty()) {
                        Object o = r.resolution.get(r.resolution.size() - 1);
                        if (o instanceof ConnectionBinding) {
                            ConnectionBinding c = (ConnectionBinding) o;
                            // This is somewhat of a hack, but ConnectionContext assumes the mappings A->0 and B->1.
                            if (c.alias.equals("A"))
                                r.index = 0;
                            if (c.alias.equals("B"))
                                r.index = 1;
                        }
                    }
                }
                return true;
            }
        };
        v.visit(visitor);
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator) EquationSet(gov.sandia.n2a.eqset.EquationSet) AccessVariable(gov.sandia.n2a.language.AccessVariable) Variable(gov.sandia.n2a.eqset.Variable) Visitor(gov.sandia.n2a.language.Visitor) AccessVariable(gov.sandia.n2a.language.AccessVariable) VariableReference(gov.sandia.n2a.eqset.VariableReference) ConnectionBinding(gov.sandia.n2a.eqset.EquationSet.ConnectionBinding)

Aggregations

AccessVariable (gov.sandia.n2a.language.AccessVariable)16 Operator (gov.sandia.n2a.language.Operator)12 Variable (gov.sandia.n2a.eqset.Variable)7 Scalar (gov.sandia.n2a.language.type.Scalar)7 ArrayList (java.util.ArrayList)6 Constant (gov.sandia.n2a.language.Constant)5 Visitor (gov.sandia.n2a.language.Visitor)5 TreeSet (java.util.TreeSet)5 EquationSet (gov.sandia.n2a.eqset.EquationSet)4 Type (gov.sandia.n2a.language.Type)4 VariableReference (gov.sandia.n2a.eqset.VariableReference)3 Instance (gov.sandia.n2a.language.type.Instance)3 ConnectionBinding (gov.sandia.n2a.eqset.EquationSet.ConnectionBinding)2 Transformer (gov.sandia.n2a.language.Transformer)2 Output (gov.sandia.n2a.language.function.Output)2 Text (gov.sandia.n2a.language.type.Text)2 InstanceTemporaries (gov.sandia.n2a.backend.internal.InstanceTemporaries)1 Population (gov.sandia.n2a.backend.internal.Population)1 Symbol (gov.sandia.n2a.backend.xyce.netlist.Symbol)1 XyceRenderer (gov.sandia.n2a.backend.xyce.netlist.XyceRenderer)1