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();
}
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;
}
});
}
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;
}
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;
}
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();
}
}
Aggregations