#include #include #include #include #include #include #include #include #include using std::vector; using std::string; using std::set; using std::logic_error; static Index mkDim(Function const *func, vector const &parents) { /* Calculates dimension of logical node as a function of its parameters. */ vector parameters(parents.size()); long j = 0; for (vector::const_iterator p = parents.begin(); p != parents.end(); ++p) { parameters[j++] = &((*p)->data); } if (!func->checkParameterLength(parameters)) { throw logic_error(string("Incorrect number of parameters for function ") + func->name()); } if (!func->checkParameterDim(parameters)) { throw logic_error(string("Non-conforming parameters for function ") + func->name()); } return func->dim(parameters); } LogicalNode::LogicalNode(Function const *function, vector const ¶meters) : DeterministicNode(mkDim(function,parameters)), _func(function) { for (unsigned long j = 0; j < parameters.size(); ++j) { _parameters.push_back(¶meters[j]->data); addParent(parameters[j]); } if (_func->isDiscreteValued(_parameters)) { data.setDiscreteValued(true); } } LogicalNode::~LogicalNode() { } string LogicalNode::name(NodeNameTab const &name_table) const { string name = name_table.getName(this); if (!name.empty()) return name; /* * We have to do a little work here. We can't recover the * parameter names from the vector "_parameters", because it is * a vector of SArrays. Conversely, the set of parents is not * stored in the right order. By putting the two pieces of * data together, we can reconstruct the original vector of * parameters. */ vector parameters; vector::const_iterator p; for (p = _parameters.begin(); p != _parameters.end(); ++p) { set::const_iterator q; for (q = parents().begin(); q != parents().end(); ++q) { Node *parent = (*q); if (*p == &parent->data) { parameters.push_back(parent); break; } } } string const &fname = _func->name(); if (fname == "*" || fname == "/" || fname == "+" || fname == "-") { name.append("("); for (unsigned int i = 0; i < parameters.size(); ++i) { if (i > 0) { name.append(fname); } name.append(parameters[i]->name(name_table)); } name.append(")"); } else if (fname == "NEG") { name.append("(-"); name.append(parameters[0]->name(name_table)); name.append(")"); } else { name.append(fname); name.append("("); for (unsigned int i = 0; i < parameters.size(); ++i) { if (i > 0) name.append(","); name.append(parameters[i]->name(name_table)); } name.append(")"); } return name; } vector const &LogicalNode::parameters() const { return _parameters; } Function const* LogicalNode::function() const { return _func; } void LogicalNode::forwardSample() { if (!_func->checkParameterValue(_parameters)) { throw NodeError(this, "Invalid parameter values for LogicalNode"); } _func->evaluate(data, _parameters); } LogicalNode *asLogical(Node *node) { return dynamic_cast(node); } bool isLogical(Node const *node) { return dynamic_cast(node); }