Search in sources :

Example 31 with Operator

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

the class Device method getDefinition.

// / Writes an instance-specific use of an internal device.
public String getDefinition(XyceRenderer renderer) {
    StringBuilder result = new StringBuilder();
    // Nodes that this device connects to
    List<String> nodeNames = new ArrayList<String>();
    for (int i = 0; i < varnames.size(); i++) {
        Variable v = varnames.get(i);
        if (v == ground) {
            nodeNames.add("0");
        } else if (v != empty) {
            nodeNames.add(getInstanceVarname(v.reference, renderer.pi));
        }
    }
    // Its specific parameter values will be based on first written part.
    if (model == null) {
        model = new HashMap<String, String>();
        for (Entry<String, Variable> p : paramList.entrySet()) {
            // TODO: select() can return null. Should we guard against it?
            model.put(p.getKey(), renderer.change(p.getValue().select(renderer.pi).expression));
        }
        result.append(Xyceisms.defineModel(device.getDeviceTypeName(), device.getDeviceLevel(), modelName, model));
    }
    // Instance-specific parameters that override model
    Map<String, String> instanceParams = new HashMap<String, String>();
    for (Entry<String, Variable> p : paramList.entrySet()) {
        Variable v = p.getValue();
        if (v.global)
            continue;
        String name = p.getKey();
        // TODO: select() can return null. Should we guard against it?
        String value = renderer.change(v.select(renderer.pi).expression);
        // no need to override model parameter if value is exactly the same
        if (model.get(name).equals(value))
            continue;
        instanceParams.put(name, value);
    }
    result.append(Xyceisms.defineYDeviceWithModel(device.getDeviceTypeName(), eqSet.name, nodeNames, renderer.pi.hashCode(), modelName, instanceParams));
    // Define inputs
    for (Integer inputNode : inputs.keySet()) {
        // Write a B device definition to update the node associated with the input
        // For neurons, this assumes we want to add a current of the form I/C_m
        // where the user specifies I and C_m is known.
        // Not at all clear what it means to add current to synapse, which doesn't
        // have a capacitance of its own, but this will allow adding a user-defined
        // current I to a synapse node.
        Variable v = inputs.get(inputNode);
        AccessVariable av = new AccessVariable(v.reference);
        Operator inputEq;
        if (device.getDeviceTypeName().equals("neuron")) {
            Divide d = new Divide();
            d.operand0 = av;
            av = new AccessVariable(paramList.get(device.getCapacitanceVar()).reference);
            d.operand1 = av;
            inputEq = d;
        } else {
            inputEq = av;
        }
        String eqName = Xyceisms.referenceVariable(v.name, renderer.pi.hashCode());
        String instanceVarName = getInstanceVarname(v.reference, renderer.pi);
        result.append(Xyceisms.updateDiffEq(eqName, instanceVarName, renderer.change(inputEq)));
    }
    return result.toString();
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) Variable(gov.sandia.n2a.eqset.Variable) AccessVariable(gov.sandia.n2a.language.AccessVariable) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Divide(gov.sandia.n2a.language.operator.Divide)

Example 32 with Operator

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

the class EquationSet method findConnectionMatrix.

/**
 *        Detects if $p depends on a NonzeroIterable operator.
 *        Depends on results of: determineTypes() and clearVariables() -- To provide fake values.
 */
public void findConnectionMatrix() {
    for (EquationSet s : parts) {
        s.findConnectionMatrix();
    }
    // Only do this on connections
    if (connectionBindings == null)
        return;
    // Only check binary connections
    if (connectionBindings.size() != 2)
        return;
    Variable p = find(new Variable("$p"));
    if (p == null)
        return;
    // Determine which equation fires during connect phase
    Instance instance = new Instance() {

        public Type get(Variable v) {
            if (v.name.equals("$connect"))
                return new Scalar(1);
            if (v.name.equals("$init"))
                return new Scalar(0);
            if (v.name.equals("$live"))
                return new Scalar(0);
            return v.type;
        }
    };
    Operator predicate = null;
    for (// Scan for first equation whose condition is nonzero
    EquationEntry e : // Scan for first equation whose condition is nonzero
    p.equations) {
        if (e.condition == null) {
            predicate = e.expression;
            break;
        }
        Type doit = e.condition.eval(instance);
        if (doit instanceof Scalar && ((Scalar) doit).value != 0) {
            predicate = e.expression;
            break;
        }
    }
    if (predicate == null)
        return;
    // Detect if equation or dependency contains a NonzeroIterable.
    class ContainsTransformer implements Transformer {

        public NonzeroIterable found;

        // Number of times a nonzero iterable was found
        public int count;

        public boolean substituted;

        public Operator transform(Operator op) {
            if (op instanceof NonzeroIterable) {
                found = (NonzeroIterable) op;
                count++;
                return op;
            }
            if (op instanceof AccessVariable) {
                // Check if this is a local reference to a single equation.
                AccessVariable av = (AccessVariable) op;
                Variable v = av.reference.variable;
                // We only examine local dependencies.
                if (v.container != p.container)
                    return op;
                if (v.equations.size() != 1)
                    return op;
                EquationEntry e = v.equations.first();
                if (e.condition != null)
                    return op;
                // Substitute the equation into the predicate.
                substituted = true;
                Operator result = e.expression.deepCopy();
                result.parent = op.parent;
                return result;
            }
            // continue descent
            return null;
        }
    }
    ContainsTransformer ct = new ContainsTransformer();
    Operator p2 = predicate.deepCopy();
    // to prevent infinite recursion
    int depthLimit = variables.size();
    do {
        ct.count = 0;
        ct.substituted = false;
        p2 = p2.transform(ct);
    } while (ct.substituted && depthLimit-- > 0);
    if (ct.count != 1)
        return;
    if (!ct.found.hasCorrectForm())
        return;
    // then only non-zero elements will produce connections.
    try {
        Type result = p2.eval(instance);
        // Any type other than Scalar is treated as "true", so p2 fails the test.
        if (!(result instanceof Scalar))
            return;
        // Any nonzero value is treated as "true".
        if (((Scalar) result).value != 0)
            return;
    } catch (EvaluationException e) {
        return;
    }
    // Construct
    // The NonzeroIterable we found above was a deep-copy, not the original.
    // We need to locate and work with the original in order to maintain object
    // identity in the finished model.
    predicate.visit(new Visitor() {

        public int depthLimit = variables.size();

        public boolean visit(Operator op) {
            if (op instanceof NonzeroIterable) {
                ConnectionMatrix cm = new ConnectionMatrix((NonzeroIterable) op);
                if (cm.rowMapping != null && cm.colMapping != null) {
                    connectionMatrix = cm;
                    // Somewhat of a hack. cm is a one-time process, so we shouldn't do polling.
                    p.metadata.clear("poll");
                }
                return false;
            }
            if (op instanceof AccessVariable) {
                AccessVariable av = (AccessVariable) op;
                Variable v = av.reference.variable;
                if (v.container != p.container)
                    return false;
                if (v.equations.size() != 1)
                    return false;
                EquationEntry e = v.equations.first();
                if (e.condition != null)
                    return false;
                depthLimit--;
                if (depthLimit >= 0)
                    e.expression.visit(this);
                depthLimit++;
            }
            return true;
        }
    });
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) Transformer(gov.sandia.n2a.language.Transformer) AccessVariable(gov.sandia.n2a.language.AccessVariable) Visitor(gov.sandia.n2a.language.Visitor) Instance(gov.sandia.n2a.language.type.Instance) EvaluationException(gov.sandia.n2a.language.EvaluationException) Scalar(gov.sandia.n2a.language.type.Scalar) Type(gov.sandia.n2a.language.Type)

Example 33 with Operator

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

the class EquationSet method flatten.

/**
 *        Convert this equation set into an equivalent object where each included part with $n==1
 *        (and satisfying a few other conditions) is merged into its containing part.
 *        Equations with combiners (=+, =*, and so on) are joined together into one long equation
 *        with the appropriate operator.
 *        Depends on results of: resolveLHS(), resolveRHS() -- Object identity of variables should already be established.
 *        @param backend Prefix for metadata keys specific to the engine selected to execute this model.
 *        Where such keys exist, the parts should not be flattened.
 */
public void flatten(String backend) {
    TreeSet<EquationSet> temp = new TreeSet<EquationSet>(parts);
    for (final EquationSet s : temp) {
        s.flatten(backend);
        // Check if connection or endpoint. They must remain separate equation sets for code-generation purposes.
        if (s.connectionBindings != null)
            continue;
        if (s.connected)
            continue;
        // For similar reasons, if the part contains backend-related metadata, it should remain separate.
        if (s.metadata.child("backend", backend) != null)
            continue;
        // Check if $n==1
        if (!s.isSingleton(true))
            continue;
        // We don't want to overwrite our own $n, so remove it from the sub-part. This won't change its singleton status.
        s.variables.remove(new Variable("$n"));
        // Don't merge if there are any conflicting $variables.
        // Regular variables never conflict, because they get a unique prefix when flattened.
        // However, $variables cannot be prefixed. Their semantics are strongly bound to their
        // current equation set.
        boolean conflict = false;
        for (Variable v : s.variables) {
            if (!v.name.startsWith("$"))
                continue;
            // Not a conflict if LHS is an up-reference to this equation set. These equations will get merged.
            if (v.reference.variable.container == EquationSet.this)
                continue;
            Variable d = find(v);
            // Not a conflict unless v exists in this equation set.
            if (d == null)
                continue;
            // Not a conflict if v is a $variable added by processing.
            if (s.source.child(v.nameString()) == null)
                continue;
            conflict = true;
            break;
        }
        if (conflict)
            continue;
        // No conflicts. However, there may still be overlapping $variables. Only $variables unique
        // to s will be moved up. For those that do overlap, any references will be redirected to
        // the equivalent variable in this container.
        // Merge
        final String prefix = s.name;
        parts.remove(s);
        // Variables
        // In addition to simply moving the variables up to this container, we need to do incremental maintenance of:
        // * Display names, for debugging.
        // * Resolution paths.
        // Of those, resolution paths are the most difficult, because many different objects are affected:
        // * References to variables in s
        // - from this container or our parents
        // - from children of s
        // * References to variables in children of s
        // * References from s to other sets
        // * References from children of s
        // - to s
        // - to other sets
        // And it is necessary to handle both LHS and RHS references.
        // Pass 1 -- Change RHS references originating from variables within s so they function within this container instead.
        // Need to do this before variables get moved, because we depend on the identity of their current container.
        Visitor prefixer = new Visitor() {

            public boolean visit(Operator op) {
                if (!(op instanceof AccessVariable))
                    return true;
                AccessVariable av = (AccessVariable) op;
                if (// internal reference
                av.reference.variable.container == s) {
                    // cosmetic change
                    if (!av.name.startsWith("$"))
                        av.name = prefix + "." + av.name;
                } else // external reference
                {
                    // cosmetic change
                    if (av.name.startsWith("$up."))
                        av.name = av.name.substring(4);
                    List<Object> r = av.reference.resolution;
                    // If first step of resolution is parent, then remove it, because variable is about to become part of parent.
                    if (r.get(0) == EquationSet.this)
                        r.remove(0);
                }
                return false;
            }
        };
        for (Variable v : s.variables) {
            v.visit(prefixer);
        }
        // The expectation is that "from" will be forgotten.
        class Redirector implements Visitor {

            // original reference target, in child part
            Variable from;

            // new reference target, in parent part
            Variable to;

            // current variable being processed; the one that makes the reference
            Variable user;

            public boolean visit(Operator op) {
                if (!(op instanceof AccessVariable))
                    return true;
                AccessVariable av = (AccessVariable) op;
                if (av.reference.variable != from)
                    return false;
                if (from != to) {
                    user.removeDependencyOn(from);
                    user.addDependencyOn(to);
                }
                adjustReference(av.reference);
                return false;
            }

            public void adjustReference(VariableReference reference) {
                reference.variable = to;
                List<Object> r = reference.resolution;
                int last = r.size() - 1;
                if (// The resolution path has something in it.
                last >= 0) {
                    // The last entry should always be from.container. The only other case, of a connection binding, is eliminated by early tests in the flatten() function.
                    r.remove(last--);
                    // The problem is how to distinguish these cases ...
                    if (// Path was more than 1 step, so check if parent is now last entry.
                    last >= 0) {
                        // parent was not last entry, so need to add it
                        if (r.get(last) != to.container)
                            r.add(to.container);
                    } else // Path was 1-step, so check whether descending or ascending.
                    {
                        // The user's immediate equation set.
                        EquationSet p = user.container;
                        // The parent of the user's equation set. Conceptually, this is the value to check to see if we are ascending.
                        if (p != null)
                            p = p.container;
                        // If redirecting to the same variable, then "from" has already been moved up, so we need the grandparent instead.
                        if (from == to && p != null)
                            p = p.container;
                        // ascending, so add parent
                        if (p == from.container)
                            r.add(to.container);
                    }
                }
            }

            public void redirect(Variable from, Variable to) {
                this.from = from;
                this.to = to;
                // Copy list of users, so we can safely modify the original below.
                List<Object> usedBy;
                if (from.usedBy == null)
                    usedBy = new ArrayList<Object>();
                else
                    usedBy = new ArrayList<Object>(from.usedBy);
                // Check variables that "from" uses. Some of these may be external writers to "from", which don't necessarily show up in usedBy.
                if (from.uses != null) {
                    // copy, in case it gets modified
                    List<Variable> uses = new ArrayList<Variable>(from.uses.keySet());
                    for (Variable v : uses) {
                        // Null container indicates a connection binding, which won't write to "from" and is not a member of the part being flattened.
                        if (v.container == null)
                            continue;
                        // Skip variables that are not external writers of "from".
                        if (v.reference.variable != from)
                            continue;
                        user = v;
                        if (from != to) {
                            from.removeDependencyOn(user);
                            to.addDependencyOn(user);
                        }
                        adjustReference(v.reference);
                    }
                }
                // Check variables that use "from".
                for (Object o : usedBy) {
                    if (o instanceof Variable) {
                        user = (Variable) o;
                        // RHS references
                        user.visit(this);
                        if (// "user" has "from" as an external writer
                        from.reference.variable == user) {
                            if (from != to) {
                                user.removeDependencyOn(from);
                                user.addDependencyOn(to);
                            }
                        // Since "from" is going away, we don't bother adjusting its reference to "user".
                        }
                    } else if (o instanceof EquationSet) {
                        // This case should not occur. Currently, only addSpecials() creates such a
                        // dependency, and it is for a non-singleton.
                        from.removeUser(o);
                        if (o == from.container)
                            to.addUser(to.container);
                        else
                            to.addUser(o);
                    }
                }
            }
        }
        Redirector redirector = new Redirector();
        // Note that v may have the same name as a variable in this container. Prefixing will make the name unique.
        for (Variable v : s.variables) {
            // Adjust LHS references to work in this container.
            boolean couldNeedMerge = false;
            if (// internal reference, which for LHS is exactly same as self-reference
            v.reference.variable == v) {
                if (v.name.startsWith("$")) {
                    // Ignore automatically-added $variables that are not used.
                    if (!v.hasUsers() && s.source.child(v.nameString()) == null)
                        continue;
                    // Check if this is a conflicting $variable.
                    Variable d = find(v);
                    if (// Already exists in this container, so redirect any references in v's dependents to d.
                    d != null) {
                        // Only does something if v has users.
                        redirector.redirect(v, d);
                        // Don't process v further
                        continue;
                    }
                } else {
                    v.name = prefix + "." + v.name;
                }
            } else // external reference
            {
                if (v.name.startsWith("$up."))
                    v.name = v.name.substring(4);
                else if (v.name.startsWith(name + "."))
                    v.name = v.name.substring(name.length() + 1);
                List<Object> r = v.reference.resolution;
                if (r.get(0) == EquationSet.this) {
                    couldNeedMerge = true;
                    r.remove(0);
                }
            }
            if (// An external reference whose first resolution step is this container.
            couldNeedMerge) {
                Variable v2 = find(v);
                if (// There is a matching variable, so must merge. The match could be (and often is) the direct target of the reference.
                v2 != null) {
                    // This user must be redirected appropriately.
                    if (// direct up-reference
                    v2 == v.reference.variable) {
                        // But don't replace with dependency from v2 to itself.
                        v2.removeDependencyOn(v);
                    } else // Some other variable depends on v.
                    {
                        // v should only have one user.
                        redirector.redirect(v, v2);
                    }
                    v2.flattenExpressions(v);
                    continue;
                }
            // else fall through ...
            }
            // A distinct variable that needs to be moved up.
            // This is either an internal reference (always unique) or an external reference that does not overlap an existing variable.
            // Changes v.container, used by redirector.
            add(v);
            // Adjust resolution paths of v's users.
            redirector.redirect(v, v);
        }
        // These paths do not target s itself, but rather its parents or deeper children.
        class Resolver implements Visitor {

            // The container being eliminated (same as "s" in outer code).
            EquationSet child;

            // Holds "child". Remains after child is eliminated. (Same as EquationSet.this in outer code.)
            EquationSet parent;

            // The variable in "child" that should be the destination of the resolution path. If null, don't filter (process every reference).
            Variable target;

            public boolean visit(Operator op) {
                if (!(op instanceof AccessVariable))
                    return true;
                AccessVariable av = (AccessVariable) op;
                if (target != null && av.reference.variable != target)
                    return true;
                adjustResolution(av.reference.resolution);
                return false;
            }

            public void adjustResolution(List<Object> r) {
                // If the path has been maintained in simplest form, then it passes through child only once.
                // Our task is to find that point (if it exists) and elide child.
                int last = r.size() - 1;
                for (int i = 0; i <= last; i++) {
                    Object o = r.get(i);
                    if (o != child)
                        continue;
                    // Found child in path. Now update it.
                    // Always remove child
                    r.remove(i);
                    // The original path targeted child, so it should now target parent.
                    if (i == last)
                        r.add(parent);
                    break;
                }
            }

            public void resolve(EquationSet child, EquationSet parent) {
                this.child = child;
                this.parent = parent;
                // Instead, we immediately descend to child parts.
                for (EquationSet p : child.parts) resolveRecursive(p);
            }

            public void resolveRecursive(EquationSet current) {
                for (Variable v : current.variables) {
                    if (v.reference.variable != v)
                        adjustResolution(v.reference.resolution);
                    target = null;
                    v.visit(this);
                    if (v.usedBy == null)
                        continue;
                    target = v;
                    for (Object o : v.usedBy) {
                        if (o instanceof Variable) {
                            Variable user = (Variable) o;
                            if (user.reference.variable != user)
                                adjustResolution(user.reference.resolution);
                            user.visit(this);
                        }
                    // else if (o instanceof EquationSet)  // should not be a relevant case.
                    // A possibility is o==s. However, this should not occur if flatten() is run immediately after resolveRHS().
                    }
                }
                for (EquationSet p : current.parts) resolveRecursive(p);
            }
        }
        Resolver resolver = new Resolver();
        resolver.resolve(s, this);
        // Parts
        for (EquationSet sp : s.parts) {
            // s was the former container for sp, but s is going away
            sp.container = this;
            sp.name = prefix + "." + sp.name;
            parts.add(sp);
        }
        // Metadata
        if (s.metadata.size() > 0)
            metadata.set(s.metadata, prefix);
        // Dependent connections (paths that pass through s)
        if (s.dependentConnections != null) {
            if (dependentConnections == null)
                dependentConnections = new ArrayList<ConnectionBinding>();
            for (ConnectionBinding c : s.dependentConnections) {
                // By construction, this element must exist.
                int i = c.resolution.indexOf(s);
                // replace s with this
                c.resolution.set(i, this);
                if (i + 1 < c.resolution.size() && c.resolution.get(i + 1) == this)
                    c.resolution.remove(i + 1);
                if (i > 0 && c.resolution.get(i - 1) == this)
                    c.resolution.remove(i - 1);
                if (!dependentConnections.contains(c))
                    dependentConnections.add(c);
            }
        }
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) Visitor(gov.sandia.n2a.language.Visitor) AccessVariable(gov.sandia.n2a.language.AccessVariable) ArrayList(java.util.ArrayList) TreeSet(java.util.TreeSet) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList)

Example 34 with Operator

use of gov.sandia.n2a.language.Operator 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);
    }
}
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) Instance(gov.sandia.n2a.language.type.Instance) LinkedList(java.util.LinkedList) Scalar(gov.sandia.n2a.language.type.Scalar) TreeSet(java.util.TreeSet) Split(gov.sandia.n2a.language.Split)

Example 35 with Operator

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

the class Variable method isEmptyCombiner.

public boolean isEmptyCombiner() {
    if (equations.size() != 1 || assignment == Variable.REPLACE)
        return false;
    Operator e = equations.first().expression;
    if (!e.isScalar())
        return false;
    double value = e.getDouble();
    switch(assignment) {
        case Variable.ADD:
            return value == 0;
        case Variable.MULTIPLY:
        case Variable.DIVIDE:
            return value == 1;
        case Variable.MIN:
            return value == Double.POSITIVE_INFINITY;
        case Variable.MAX:
            return value == Double.NEGATIVE_INFINITY;
    }
    // This statement should never be reached.
    return false;
}
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