use of gov.sandia.n2a.language.Split in project n2a by frothga.
the class EquationSet method resolveRHS.
public void resolveRHS(LinkedList<String> unresolved) {
for (EquationSet s : parts) {
s.resolveRHS(unresolved);
}
class Resolver extends Transformer {
public Variable from;
public LinkedList<String> unresolved;
public String fromName() {
String result = from.container.prefix();
if (!result.isEmpty())
result += ".";
return result + from.nameString();
}
public Operator transform(Operator op) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
Variable query = new Variable(av.getName(), av.getOrder());
query.reference = new VariableReference();
EquationSet dest = resolveEquationSet(query, false);
if (dest == null) {
unresolved.add(av.name + "\t" + fromName());
} else {
query.reference.variable = dest.find(query);
if (query.reference.variable == null) {
if (query.name.equals("(connection)")) {
// create a phantom variable. TODO: should this be an attribute instead?
query.reference.variable = new Variable("(connection)");
// the container itself is really the target
query.reference.variable.container = dest;
// because instance variables are bound before the part is put into service, and remain constant for its entire life
query.reference.variable.addAttribute("initOnly");
// TODO: when $connect() is implemented, instances should become first class variables in the equation set, and this circular reference will be created by resolveLHS()
query.reference.variable.reference = query.reference;
} else if (// accountable endpoint
query.name.equals("$count")) {
if (dest.accountableConnections == null)
dest.accountableConnections = new TreeSet<AccountableConnection>();
String alias = av.name.split("\\.", 2)[0];
AccountableConnection ac = new AccountableConnection(EquationSet.this, alias);
if (!dest.accountableConnections.add(ac))
ac = dest.accountableConnections.floor(ac);
if (ac.count == null) {
// Create a fully-functional variable.
// However, it never gets formally added to dest, because dest should never evaluate it.
// Rather, it is maintained by the backend's connection system.
ac.count = new Variable(prefix() + ".$count");
ac.count.type = new Scalar(0);
ac.count.container = dest;
ac.count.equations = new TreeSet<EquationEntry>();
query.reference.variable = ac.count;
query.reference.variable.reference = query.reference;
} else {
query.reference.variable = ac.count;
}
} else {
unresolved.add(av.name + "\t" + fromName());
}
} else {
Variable target = query.reference.variable;
from.addDependencyOn(target);
if (from.container != target.container) {
target.addAttribute("externalRead");
if (target.hasAttribute("temporary")) {
Backend.err.get().println("WARNING: Variable " + target.container.prefix() + "." + target.nameString() + " has an external read, so cannot be temporary.");
target.removeAttribute("temporary");
}
}
}
}
av.reference = query.reference;
return av;
}
if (op instanceof Split) {
Split split = (Split) op;
int count = split.names.length;
split.parts = new ArrayList<EquationSet>(count);
for (int i = 0; i < count; i++) {
String temp = split.names[i];
EquationSet part = container.parts.floor(new EquationSet(temp));
if (part.name.equals(temp))
split.parts.add(part);
else
unresolved.add(temp + "\t" + fromName());
}
}
return null;
}
}
Resolver resolver = new Resolver();
for (Variable v : variables) {
resolver.from = v;
resolver.unresolved = unresolved;
v.transform(resolver);
}
}
use of gov.sandia.n2a.language.Split in project n2a by frothga.
the class InternalBackendData method analyze.
public void analyze(final EquationSet s) {
boolean headless = AppData.properties.getBoolean("headless");
if (!headless)
System.out.println(s.name);
if (s.connectionBindings != null) {
// Note that populations have already been allocated in the constructor.
endpoints = countLocalObject;
countLocalObject += s.connectionBindings.size();
}
fastExit = s.metadata.getFlag("backend", "all", "fastExit");
for (// we want the sub-lists to be ordered correctly
Variable v : // we want the sub-lists to be ordered correctly
s.ordered) {
if (!headless) {
String className = "null";
if (v.type != null)
className = v.type.getClass().getSimpleName();
String dimensionName = "";
if (v.unit != null)
dimensionName = v.unit.toString();
System.out.println(" " + v.nameString() + " " + v.attributeString() + " " + className + " " + dimensionName);
}
if (v.name.equals("$connect"))
connect = v;
else if (v.name.equals("$index"))
index = v;
else if (v.name.equals("$init"))
init = v;
else if (v.name.equals("$live"))
live = v;
else if (v.name.equals("$n") && v.order == 0)
n = v;
else if (v.name.equals("$p") && v.order == 0)
p = v;
else if (v.name.equals("$type"))
type = v;
else if (v.name.equals("$xyz") && v.order == 0)
xyz = v;
else if (v.name.equals("$t")) {
if (v.order == 0)
t = v;
else if (v.order == 1)
dt = v;
}
boolean initOnly = v.hasAttribute("initOnly");
boolean emptyCombiner = v.isEmptyCombiner();
boolean updates = !initOnly && v.equations.size() > 0 && !emptyCombiner && (v.derivative == null || v.hasAttribute("updates"));
boolean temporary = v.hasAttribute("temporary");
boolean unusedTemporary = temporary && !v.hasUsers();
if (v.hasAttribute("externalWrite"))
v.externalWrite = true;
if (v.hasAttribute("global")) {
v.global = true;
v.visit(new Visitor() {
public boolean visit(Operator op) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
if (av.reference.resolution.size() > 0)
addReferenceGlobal(av.reference, s);
return false;
}
if (op instanceof Output) {
Output o = (Output) op;
if (!o.hasColumnName) {
o.index = countGlobalObject++;
namesGlobalObject.add("columnName" + o.index);
}
// Continue descent, because parameters of output() may contain variable references
return true;
}
return true;
}
});
if (// eliminate non-computed values, unless they refer to a variable outside the immediate equation set
!v.hasAny(new String[] { "constant", "accessor", "readOnly" }) || v.hasAll(new String[] { "constant", "reference" })) {
if (updates)
globalUpdate.add(v);
if (!unusedTemporary && !emptyCombiner)
globalInit.add(v);
if (v.hasAttribute("reference")) {
addReferenceGlobal(v.reference, s);
} else if (!temporary && !v.hasAttribute("dummy")) {
if (!v.hasAttribute("preexistent"))
globalMembers.add(v);
boolean external = false;
if (v.externalWrite || v.assignment != Variable.REPLACE) {
external = true;
globalBufferedExternalWrite.add(v);
}
if (external || (v.hasAttribute("externalRead") && updates)) {
external = true;
globalBufferedExternal.add(v);
}
if (!external && v.hasAttribute("cycle")) {
globalBufferedInternal.add(v);
if (!initOnly)
globalBufferedInternalUpdate.add(v);
}
}
}
} else // local
{
v.visit(new Visitor() {
public boolean visit(Operator op) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
if (av.reference.resolution.size() > 0)
addReferenceLocal(av.reference, s);
return false;
}
if (op instanceof Output) {
Output o = (Output) op;
if (!o.hasColumnName) {
o.index = countLocalObject++;
namesLocalObject.add("columnName" + o.index);
}
// Continue descent, because parameters of output() may contain variable references
return true;
}
return true;
}
});
if (!v.hasAny(new String[] { "constant", "accessor", "readOnly" }) || v.hasAll(new String[] { "constant", "reference" })) {
if (updates)
localUpdate.add(v);
if (!unusedTemporary && !emptyCombiner && !forbiddenLocalInit.contains(v.name))
localInit.add(v);
if (v.hasAttribute("reference")) {
addReferenceLocal(v.reference, s);
} else if (!temporary && !v.hasAttribute("dummy")) {
if (!v.hasAttribute("preexistent"))
localMembers.add(v);
boolean external = false;
if (v.externalWrite || v.assignment != Variable.REPLACE) {
external = true;
localBufferedExternalWrite.add(v);
}
if (external || (v.hasAttribute("externalRead") && updates)) {
external = true;
localBufferedExternal.add(v);
}
if (!external && v.hasAttribute("cycle")) {
localBufferedInternal.add(v);
if (!initOnly)
localBufferedInternalUpdate.add(v);
}
}
}
}
}
for (// we need these to be in order by differential level, not by dependency
Variable v : // we need these to be in order by differential level, not by dependency
s.variables) {
if (v.derivative != null && !v.hasAny(new String[] { "constant", "initOnly" })) {
if (v.hasAttribute("global"))
globalIntegrated.add(v);
else
localIntegrated.add(v);
}
}
if (dt != null && dt.hasAttribute("constant")) {
setDt = true;
// However, if the nearest container that defines $t' matches our value, then don't set $t'.
if (s.container != null) {
Variable pdt = s.container.findDt();
if (pdt != null && pdt.hasAttribute("constant")) {
double value = dt.equations.first().expression.getDouble();
double pvalue = pdt.equations.first().expression.getDouble();
setDt = value != pvalue;
}
}
}
determineOrderInit("$init", s, localInit);
determineOrderInit("$init", s, globalInit);
singleton = s.isSingleton(true);
populationCanGrowOrDie = s.lethalP || s.lethalType || s.canGrow();
if (n != null && !singleton) {
populationCanResize = globalMembers.contains(n);
// See EquationSet.forceTemporaryStorageForSpecials() for a related issue.
if (!populationCanResize && populationCanGrowOrDie && n.hasUsers()) {
Backend.err.get().println("WARNING: $n can change (due to structural dynamics) but it was detected as a constant. Equations that depend on $n may give incorrect results.");
}
}
if (index != null && !singleton) {
indexNext = allocateGlobalFloat("indexNext");
indexAvailable = allocateGlobalObject("indexAvailable");
}
if (// track instances
singleton || s.connected || s.needInstanceTracking || populationCanResize) {
// The reason populationCanResize forces use of the instances array is to enable pruning of parts when $n decreases.
// The reason to "track instances" for a singleton is to allocate a slot for direct storage of the single instance in valuesObject.
instances = allocateGlobalObject("instances");
if (// in addition, track newly created instances
s.connected) {
if (!singleton)
firstborn = allocateGlobalFloat("firstborn");
newborn = allocateLocalFloat("newborn");
}
}
// Just give name of connection part itself.
if (s.connectionBindings != null) {
singleConnection = true;
for (ConnectionBinding cb : s.connectionBindings) {
if (cb.endpoint.container != s.container || !cb.endpoint.isSingleton(true)) {
singleConnection = false;
break;
}
}
}
if (p != null) {
Pdependencies = new ArrayList<Variable>();
PdependenciesTemp = new ArrayList<Variable>();
for (Variable t : s.ordered) {
boolean temporary = t.hasAttribute("temporary");
if ((temporary || localMembers.contains(t)) && p.dependsOn(t) != null) {
Pdependencies.add(t);
if (temporary)
PdependenciesTemp.add(t);
}
}
determineOrderInit("$connect", s, Pdependencies);
// determineOrderInit() is not needed for PdepenciesTemp, because temps are already in the correct order.
// Default is no polling
String pollString = "-1";
if (p.metadata != null)
pollString = p.metadata.getOrDefault(pollString, "poll");
poll = new UnitValue(pollString).get();
if (poll >= 0) {
pollDeadline = allocateGlobalFloat("pollDeadline");
pollSorted = allocateGlobalObject("pollSorted");
}
}
if (type != null) {
for (EquationEntry e : type.equations) {
Split split = (Split) e.expression;
split.index = type.reference.variable.container.splits.indexOf(split.parts);
}
}
if (xyz != null) {
XYZdependencies = new ArrayList<Variable>();
XYZdependenciesTemp = new ArrayList<Variable>();
for (Variable t : s.ordered) {
boolean temporary = t.hasAttribute("temporary");
if ((temporary || localMembers.contains(t)) && xyz.dependsOn(t) != null) {
XYZdependencies.add(t);
if (temporary)
XYZdependenciesTemp.add(t);
}
}
}
populationIndex = 0;
if (// check for null specifically to guard against the Wrapper equation set (which is not fully constructed)
s.container != null && s.container.parts != null) {
populationIndex = s.container.parts.indexOf(s);
}
if (// connection-specific stuff
s.connectionBindings != null) {
int size = s.connectionBindings.size();
// endpoints is allocated at the top of this function, because it is needed for reference handling in the variable analysis loop
projectDependencies = new Object[size];
projectReferences = new Object[size];
count = new int[size];
k = new Variable[size];
max = new Variable[size];
min = new Variable[size];
project = new Variable[size];
radius = new Variable[size];
for (int i = 0; i < s.connectionBindings.size(); i++) {
ConnectionBinding c = s.connectionBindings.get(i);
count[i] = -1;
k[i] = s.find(new Variable(c.alias + ".$k"));
max[i] = s.find(new Variable(c.alias + ".$max"));
min[i] = s.find(new Variable(c.alias + ".$min"));
project[i] = s.find(new Variable(c.alias + ".$project"));
radius[i] = s.find(new Variable(c.alias + ".$radius"));
if (c.endpoint.accountableConnections != null) {
AccountableConnection query = new AccountableConnection(s, c.alias);
AccountableConnection ac = c.endpoint.accountableConnections.floor(query);
if (// Only true if this endpoint is accountable.
ac.equals(query)) {
// Allocate space for counter in target part
InternalBackendData endpointBed = (InternalBackendData) c.endpoint.backendData;
count[i] = endpointBed.allocateLocalFloat(s.prefix() + ".$count");
if (// $count is referenced explicitly, so need to finish setting it up
ac.count != null) {
ac.count.readIndex = ac.count.writeIndex = count[i];
}
}
}
// Note that countLocalObject has already been incremented above
namesLocalObject.add(c.alias);
if (project[i] != null) {
ArrayList<Variable> dependencies = new ArrayList<Variable>();
// Always assign, even if empty.
projectDependencies[i] = dependencies;
for (Variable t : s.ordered) {
if (project[i].dependsOn(t) != null) {
dependencies.add(t);
}
}
final TreeSet<VariableReference> references = new TreeSet<VariableReference>();
class ProjectVisitor implements Visitor {
public boolean visit(Operator op) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
if (av.reference.resolution.size() > 0)
references.add(av.reference);
return false;
}
return true;
}
}
ProjectVisitor visitor = new ProjectVisitor();
project[i].visit(visitor);
for (Variable v : dependencies) v.visit(visitor);
if (references.size() > 0)
projectReferences[i] = references;
}
c.resolution = translateResolution(c.resolution, s);
}
}
// Locals
for (Variable v : localMembers) {
// in the object array rather than the float array.
if (v.type instanceof Scalar && v.reference.variable == v) {
v.readIndex = v.writeIndex = allocateLocalFloat(v.nameString());
} else {
v.readIndex = v.writeIndex = allocateLocalObject(v.nameString());
}
}
for (Variable v : localBufferedExternal) {
if (v.type instanceof Scalar && v.reference.variable == v) {
v.writeIndex = allocateLocalFloat("next_" + v.nameString());
} else {
v.writeIndex = allocateLocalObject("next_" + v.nameString());
}
}
for (Variable v : localBufferedInternal) {
v.writeTemp = true;
if (v.type instanceof Scalar && v.reference.variable == v) {
v.writeIndex = allocateLocalTempFloat("next_" + v.nameString());
} else {
v.writeIndex = allocateLocalTempObject("next_" + v.nameString());
}
}
// Globals
for (Variable v : globalMembers) {
if (v.type instanceof Scalar && v.reference.variable == v) {
v.readIndex = v.writeIndex = allocateGlobalFloat(v.nameString());
} else {
v.readIndex = v.writeIndex = allocateGlobalObject(v.nameString());
}
}
for (Variable v : globalBufferedExternal) {
if (v.type instanceof Scalar && v.reference.variable == v) {
v.writeIndex = allocateGlobalFloat("next_" + v.nameString());
} else {
v.writeIndex = allocateGlobalObject("next_" + v.nameString());
}
}
for (Variable v : globalBufferedInternal) {
v.writeTemp = true;
if (v.type instanceof Scalar && v.reference.variable == v) {
v.writeIndex = allocateGlobalTempFloat("next_" + v.nameString());
} else {
v.writeIndex = allocateGlobalTempObject("next_" + v.nameString());
}
}
// fully temporary values
for (Variable v : s.variables) {
if (!v.hasAttribute("temporary"))
continue;
v.readTemp = v.writeTemp = true;
if (v.hasAttribute("global")) {
if (v.type instanceof Scalar && v.reference.variable == v) {
v.readIndex = v.writeIndex = allocateGlobalTempFloat(v.nameString());
} else {
v.readIndex = v.writeIndex = allocateGlobalTempObject(v.nameString());
}
} else {
if (v.type instanceof Scalar && v.reference.variable == v) {
v.readIndex = v.writeIndex = allocateLocalTempFloat(v.nameString());
} else {
v.readIndex = v.writeIndex = allocateLocalTempObject(v.nameString());
}
}
}
if (live.hasAttribute("constant"))
liveStorage = LIVE_CONSTANT;
else if (live.hasAttribute("accessor"))
liveStorage = LIVE_ACCESSOR;
else
// $live is "initOnly"
liveStorage = LIVE_STORED;
for (VariableReference r : localReference) r.resolution = translateResolution(r.resolution, s);
for (VariableReference r : globalReference) r.resolution = translateResolution(r.resolution, s);
}
use of gov.sandia.n2a.language.Split in project n2a by frothga.
the class EquationSet method resolveRHS.
public void resolveRHS(LinkedList<UnresolvedVariable> unresolved) {
for (EquationSet s : parts) {
s.resolveRHS(unresolved);
}
class Resolver implements Visitor {
public Variable from;
public LinkedList<UnresolvedVariable> unresolved;
public String fromName() {
String result = from.container.prefix();
if (!result.isEmpty())
result += ".";
return result + from.nameString();
}
public boolean visit(Operator op) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
Variable query = new Variable(av.getName(), av.getOrder());
VariableReference r = new VariableReference();
query.reference = r;
av.reference = r;
// modifies "r" with actual resolution path
EquationSet dest = resolveEquationSet(query, false);
r.removeLoops();
// dependencies from "from" to each part in the resolution path
r.addDependencies(from);
if (dest == null) {
unresolved.add(new UnresolvedVariable(av.name, fromName()));
} else {
// "query" contains the modified variable name, needed for lookup within "dest"
r.variable = dest.find(query);
if (r.variable == null) {
if (query.hasAttribute("instance")) {
// Configure reference to destination container itself.
// Recycle the query variable as a pseudo target (one that doesn't actually exist in the container).
r.variable = query;
query.container = dest;
query.equations = new TreeSet<EquationEntry>();
query.type = new Instance();
// Only for use by Internal backend. It's easier to set this here than to scan for "instance" variables in InternalBackendData.analyze().
query.readIndex = -2;
} else if (// accountable endpoint
query.name.equals("$count")) {
int last = r.resolution.size() - 1;
Object o = null;
if (last >= 0)
o = r.resolution.get(last);
if (!(o instanceof ConnectionBinding)) {
unresolved.add(new UnresolvedVariable(av.name, fromName()));
} else {
ConnectionBinding cb = (ConnectionBinding) o;
if (dest.accountableConnections == null)
dest.accountableConnections = new TreeSet<AccountableConnection>();
AccountableConnection ac = new AccountableConnection(r.penultimateContainer(EquationSet.this), cb.alias);
if (!dest.accountableConnections.add(ac))
ac = dest.accountableConnections.floor(ac);
if (ac.count == null) {
// Create a fully-functional variable.
// However, it never gets formally added to dest, because dest should never evaluate it.
// Rather, it is maintained by the backend's connection system.
ac.count = new Variable(prefix() + ".$count");
ac.count.type = new Scalar(0);
ac.count.container = dest;
ac.count.equations = new TreeSet<EquationEntry>();
ac.count.reference = new VariableReference();
ac.count.reference.variable = ac.count;
}
r.variable = ac.count;
}
} else {
unresolved.add(new UnresolvedVariable(av.name, fromName()));
}
} else {
from.addDependencyOn(r.variable);
}
}
return false;
}
if (op instanceof Split) {
Split split = (Split) op;
split.parts = new ArrayList<EquationSet>(split.names.length);
EquationSet self = from.reference.variable.container;
// Could be null, if self is top-level model.
EquationSet family = self.container;
for (String partName : split.names) {
EquationSet part;
if (// This allows for $type in top-level model, where no higher container is available to search in.
partName.equals(self.name))
// This allows for $type in top-level model, where no higher container is available to search in.
part = self;
else
part = family.findPart(partName);
if (part != null) {
split.parts.add(part);
Variable query = new Variable("$type");
Variable type = part.find(query);
if (type == null) {
type = query;
part.add(type);
// double-buffer it
type.addAttribute("externalWrite");
type.unit = AbstractUnit.ONE;
type.equations = new TreeSet<EquationEntry>();
type.reference = new VariableReference();
type.reference.variable = type;
}
if (type != from)
type.addDependencyOn(from);
} else {
unresolved.add(new UnresolvedVariable(partName, fromName()));
}
}
return false;
}
return true;
}
}
Resolver resolver = new Resolver();
resolver.unresolved = unresolved;
for (Variable v : variables) {
resolver.from = v;
v.visit(resolver);
}
}
use of gov.sandia.n2a.language.Split in project n2a by frothga.
the class JobC method multiconditional.
public void multiconditional(Variable v, CRenderer context, String pad) throws Exception {
boolean init = context.part.getInit();
boolean isType = v.name.equals("$type");
if (v.hasAttribute("temporary"))
context.result.append(pad + type(v) + " " + mangle(v) + ";\n");
// Select the default equation
EquationEntry defaultEquation = null;
for (EquationEntry e : v.equations) {
if (// TODO: also handle $init==1, or any other equivalent expression
init && e.ifString.equals("$init")) {
defaultEquation = e;
break;
}
if (e.ifString.length() == 0)
defaultEquation = e;
}
// Initialize static objects, and dump dynamic objects needed by conditions
for (EquationEntry e : v.equations) {
if (init) {
prepareStaticObjects(e.expression, context, pad);
if (e.condition != null)
prepareStaticObjects(e.condition, context, pad);
}
if (e.condition != null)
prepareDynamicObjects(e.condition, context, init, pad);
}
// Write the conditional equations
boolean haveIf = false;
String padIf = pad;
for (EquationEntry e : v.equations) {
if (e == defaultEquation)
continue;
if (init) {
if (e.ifString.length() == 0)
continue;
} else // not init
{
if (e.ifString.equals("$init"))
continue;
}
if (e.condition != null) {
String ifString;
if (haveIf) {
ifString = "elseif (";
} else {
ifString = "if (";
haveIf = true;
padIf = pad + " ";
}
context.result.append(pad + ifString);
e.condition.render(context);
context.result.append(")\n");
context.result.append(pad + "{\n");
}
if (isType) {
// per the N2A language document.
if (!(e.expression instanceof Split)) {
Backend.err.get().println("Unexpected expression for $type");
throw new Backend.AbortRun();
}
int index = context.part.splits.indexOf(((Split) e.expression).parts);
context.result.append(padIf + resolve(v.reference, context, true) + " = " + (index + 1) + ";\n");
} else {
prepareDynamicObjects(e.expression, context, init, pad);
context.result.append(padIf);
renderEquation(context, e);
}
if (haveIf)
context.result.append(pad + "}\n");
}
// Write the default equation
if (defaultEquation == null) {
if (isType) {
if (haveIf) {
context.result.append(pad + "else\n");
context.result.append(pad + "{\n");
}
// always reset $type to 0
context.result.append(padIf + resolve(v.reference, context, true) + " = 0;\n");
if (haveIf)
context.result.append(pad + "}\n");
} else {
// to copy forward the current buffered value.
if (v.assignment == Variable.REPLACE && v.reference.variable == v && v.equations.size() > 0 && v.hasAny("cycle", "externalRead") && !v.hasAttribute("initOnly")) {
if (haveIf) {
context.result.append(pad + "else\n");
context.result.append(pad + "{\n");
}
// copy previous value
context.result.append(padIf + resolve(v.reference, context, true) + " = " + resolve(v.reference, context, false) + ";\n");
if (haveIf)
context.result.append(pad + "}\n");
}
}
} else {
if (haveIf) {
context.result.append(pad + "else\n");
context.result.append(pad + "{\n");
}
if (isType) {
ArrayList<EquationSet> split = ((Split) defaultEquation.expression).parts;
int index = context.part.splits.indexOf(split);
context.result.append(padIf + resolve(v.reference, context, true) + " = " + (index + 1) + ";\n");
} else {
prepareDynamicObjects(defaultEquation.expression, context, init, pad);
context.result.append(padIf);
renderEquation(context, defaultEquation);
}
if (haveIf)
context.result.append(pad + "}\n");
}
}
use of gov.sandia.n2a.language.Split in project n2a by frothga.
the class EquationSet method collectSplits.
/**
* Scans all conditional forms of $type, and stores the patterns in the splits field.
* Depends on results of: resolveLHS(), resolveRHS()
*/
public void collectSplits() {
for (EquationSet s : parts) {
s.collectSplits();
}
if (splits == null)
splits = new ArrayList<ArrayList<EquationSet>>();
if (splitSources == null)
splitSources = new HashSet<EquationSet>();
for (Variable v : variables) {
// The actual variable. It is possible for an equation in one part to indicate a type split in another part.
Variable type = v.reference.variable;
if (!type.name.equals("$type"))
continue;
EquationSet container = type.container;
if (// in case we are referencing $type in another equation set that has not yet been processed
container.splits == null) {
container.splits = new ArrayList<ArrayList<EquationSet>>();
}
for (EquationEntry e : v.equations) {
if (!(e.expression instanceof Split)) {
Backend.err.get().println("Unexpected expression for $type");
throw new Backend.AbortRun();
}
ArrayList<EquationSet> split = ((Split) e.expression).parts;
if (!container.splits.contains(split)) {
container.splits.add(split);
for (EquationSet t : split) {
if (t.splitSources == null)
t.splitSources = new HashSet<EquationSet>();
t.splitSources.add(container);
}
}
}
}
}
Aggregations