SeExpr
ExprMultiExpr.cpp
Go to the documentation of this file.
1 /*
2  Copyright Disney Enterprises, Inc. All rights reserved.
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License
6  and the following modification to it: Section 6 Trademarks.
7  deleted and replaced with:
8 
9  6. Trademarks. This License does not grant permission to use the
10  trade names, trademarks, service marks, or product names of the
11  Licensor and its affiliates, except as required for reproducing
12  the content of the NOTICE file.
13 
14  You may obtain a copy of the License at
15  http://www.apache.org/licenses/LICENSE-2.0
16 */
17 #include "ExprMultiExpr.h"
18 #include <algorithm>
19 #include <set>
20 
21 namespace SeExpr2 {
22 class GlobalVal : public ExprVarRef {
23  public:
24  GlobalVal(const std::string &varName, const SeExpr2::ExprType &et) : ExprVarRef(et), varName(varName) {}
25  std::set<DExpression *> users;
26  std::string varName;
27 };
28 
29 struct GlobalFP : public GlobalVal {
30  GlobalFP(const std::string &varName, int dim) : GlobalVal(varName, ExprType().FP(dim).Varying()) {
31  val.assign(dim, 0);
32  }
33 
34  std::vector<double> val;
35  void eval(double *result) {
36  for (int i = 0; i < type().dim(); i++) result[i] = val[i];
37  }
38  void eval(const char **result) { assert(false); }
39  bool isVec() { return type().dim() > 1; }
40 };
41 
42 struct GlobalStr : public GlobalVal {
43  GlobalStr(const std::string &varName) : GlobalVal(varName, ExprType().String().Varying()), val(0) {}
44 
45  const char *val;
46  void eval(double *result) { assert(false); }
47  void eval(const char **result) { *result = val; }
48  bool isVec() { return 0; }
49 };
50 }
51 
52 namespace {
53 
54 std::set<SeExpr2::DExpression *> getAffectedExpr(SeExpr2::GlobalVal *gv) {
55  std::set<SeExpr2::DExpression *> ret;
56 
57  std::set<SeExpr2::DExpression *> workList = gv->users;
58  while (workList.size()) {
59  SeExpr2::DExpression *de = *workList.begin();
60  workList.erase(de);
61  ret.insert(de);
62  workList.insert(de->val->users.begin(), de->val->users.end());
63  }
64 
65  return ret;
66 }
67 
68 std::set<SeExpr2::DExpression *> getTransitiveOperandExpr(SeExpr2::DExpression *expr) {
69  std::set<SeExpr2::DExpression *> ret;
70 
71  std::set<SeExpr2::DExpression *> workList;
72  workList.insert(expr);
73  while (workList.size()) {
74  SeExpr2::DExpression *de = *workList.begin();
75  workList.erase(de);
76  ret.insert(de);
77  workList.insert(de->operandExprs.begin(), de->operandExprs.end());
78  }
79 
80  return ret;
81 }
82 
83 std::set<SeExpr2::DExpression *> tmpOperandExprs;
84 std::set<SeExpr2::GlobalVal *> tmpOperandVars;
85 }
86 
87 namespace SeExpr2 {
88 
89 DExpression::DExpression(const std::string &varName,
91  const std::string &e,
92  const ExprType &type,
94  : Expression(e, type, be), context(context) {
95  if (type.isFP())
96  val = new GlobalFP(varName, type.dim());
97  else if (type.isString())
98  val = new GlobalStr(varName);
99  else
100  assert(false);
101 
102  operandExprs = context.AllExprs;
103  operandVars = context.AllExternalVars;
104  prepIfNeeded();
105  operandExprs = tmpOperandExprs;
106  operandVars = tmpOperandVars;
107 }
108 
109 const std::string &DExpression::name() const { return val->varName; }
110 
111 ExprVarRef *DExpression::resolveVar(const std::string &name) const {
112  // first time resolve var from all exprs & vars
113  // then resolve var from used exprs & vars
114  for (std::set<DExpression *>::iterator I = operandExprs.begin(), E = operandExprs.end(); I != E; ++I)
115  if ((*I)->name() == name) {
116  tmpOperandExprs.insert(*I);
117  (*I)->val->users.insert(const_cast<DExpression *>(this));
118  return (*I)->val;
119  }
120 
121  for (std::set<GlobalVal *>::iterator I = operandVars.begin(), E = operandVars.end(); I != E; ++I)
122  if ((*I)->varName == name) {
123  tmpOperandVars.insert(*I);
124  (*I)->users.insert(const_cast<DExpression *>(this));
125  return *I;
126  }
127 
128  addError(name + " fail resolveVar", 0, 0);
129  return 0;
130 }
131 
133  if (_desiredReturnType.isFP()) {
134  const double *ret = evalFP();
135  GlobalFP *fpVal = dynamic_cast<GlobalFP *>(val);
136  fpVal->val.assign(ret, ret + fpVal->val.size());
137  return;
138  }
139 
140  assert(_desiredReturnType.isString());
141  GlobalStr *strVal = dynamic_cast<GlobalStr *>(val);
142  strVal->val = evalStr();
143 }
144 
146  for (std::set<DExpression *>::iterator I = AllExprs.begin(), E = AllExprs.end(); I != E; ++I) delete *I;
147 
148  for (std::set<GlobalVal *>::iterator I = AllExternalVars.begin(), E = AllExternalVars.end(); I != E; ++I) delete *I;
149 }
150 
151 VariableHandle Expressions::addExternalVariable(const std::string &variableName, ExprType seTy) {
152  std::pair<std::set<GlobalVal *>::iterator, bool> ret;
153 
154  if (seTy.isFP())
155  ret = AllExternalVars.insert(new GlobalFP(variableName, seTy.dim()));
156  else if (seTy.isString())
157  ret = AllExternalVars.insert(new GlobalStr(variableName));
158  else
159  assert(false);
160 
161  return ret.first;
162 }
163 
164 ExprHandle Expressions::addExpression(const std::string &varName, ExprType seTy, const std::string &expr) {
165  std::pair<std::set<DExpression *>::iterator, bool> ret;
166  ret = AllExprs.insert(new DExpression(varName, *this, expr, seTy));
167  return ret.first;
168 }
169 
171  GlobalVal *thisvar = *vh;
172  unsigned initSize = static_cast<unsigned>(thisvar->users.size());
173  if (!initSize) return AllExternalVars.end();
174 
175  std::set<DExpression *> ret = getAffectedExpr(thisvar);
176  exprToEval.insert(ret.begin(), ret.end());
177  // std::cout << "exprToEval size is " << exprToEval.size() << std::endl;
178  return vh;
179 }
180 
181 void Expressions::setLoopVariable(VariableSetHandle handle, double *values, unsigned dim) {
182  if (handle == AllExternalVars.end()) return;
183 
184  GlobalFP *thisvar = dynamic_cast<GlobalFP *>(*handle);
185  assert(thisvar && "set value to variable with incompatible types.");
186 
187  assert(dim == thisvar->val.size());
188  for (unsigned i = 0; i < dim; ++i) thisvar->val[i] = values[i];
189 }
190 
191 void Expressions::setLoopVariable(VariableSetHandle handle, const char *values) {
192  if (handle == AllExternalVars.end()) return;
193 
194  GlobalStr *thisvar = dynamic_cast<GlobalStr *>(*handle);
195  assert(thisvar && "set value to variable with incompatible types.");
196  thisvar->val = values;
197 }
198 
199 void Expressions::setVariable(VariableHandle handle, double *values, unsigned dim) {
200  GlobalFP *thisvar = dynamic_cast<GlobalFP *>(*handle);
201  assert(thisvar && "set value to variable with incompatible types.");
202 
203  assert(dim == thisvar->val.size());
204  for (unsigned i = 0; i < dim; ++i) thisvar->val[i] = values[i];
205 
206  // eval loop invariant now.
207  std::set<DExpression *> ret = getAffectedExpr(thisvar);
208  for (std::set<DExpression *>::iterator I = ret.begin(), E = ret.end(); I != E; ++I) (*I)->eval();
209 }
210 
211 void Expressions::setVariable(VariableHandle handle, const char *values) {
212  GlobalStr *thisvar = dynamic_cast<GlobalStr *>(*handle);
213  assert(thisvar && "set value to variable with incompatible types.");
214  thisvar->val = values;
215 
216  // eval loop invariant now.
217  std::set<DExpression *> ret = getAffectedExpr(thisvar);
218  for (std::set<DExpression *>::iterator I = ret.begin(), E = ret.end(); I != E; ++I) (*I)->eval();
219 }
220 
221 bool Expressions::isValid() const {
222  bool ret = true;
223  for (std::set<DExpression *>::const_iterator I = AllExprs.begin(), E = AllExprs.end(); I != E; ++I)
224  ret &= (*I)->isValid();
225  return ret;
226 }
227 
229  // std::cout << "exprToEval size is " << exprToEval.size() << std::endl;
230 
231  DExpression *de = *eh;
232  std::set<DExpression *> all = getTransitiveOperandExpr(de);
233  // std::cout << "all size is " << all.size() << std::endl;
234 
235  std::vector<DExpression *>::iterator it;
236 
237  std::vector<DExpression *> ret1(all.size());
238  it = std::set_intersection(all.begin(), all.end(), exprToEval.begin(), exprToEval.end(), ret1.begin());
239  ret1.resize(it - ret1.begin());
240 
241  std::vector<DExpression *> ret2(ret1.size());
242  it = std::set_difference(ret1.begin(), ret1.end(), exprEvaled.begin(), exprEvaled.end(), ret2.begin());
243  ret2.resize(it - ret2.begin());
244 
245  exprEvaled.insert(ret2.begin(), ret2.end());
246 
247  // std::cout << "ret2 size is " << ret2.size() << std::endl;
248  return std::make_pair(eh, ret2);
249 }
250 
251 const std::vector<double> &Expressions::evalFP(ExprEvalHandle eeh) {
252  // std::cout << "eeh.second.size() is " << eeh.second.size() << std::endl;
253  for (std::vector<DExpression *>::iterator I = eeh.second.begin(), E = eeh.second.end(); I != E; ++I) (*I)->eval();
254 
255  GlobalFP *thisvar = dynamic_cast<GlobalFP *>((*eeh.first)->val);
256 
257  // std::cout << thisvar->val[0] << ","
258  // << thisvar->val[1] << ","
259  // << thisvar->val[2] << std::endl;
260  return thisvar->val;
261 }
262 
264  for (std::vector<DExpression *>::iterator I = eeh.second.begin(), E = eeh.second.end(); I != E; ++I) (*I)->eval();
265 
266  GlobalStr *thisvar = dynamic_cast<GlobalStr *>((*eeh.first)->val);
267  return thisvar->val;
268 }
269 }
SeExpr2::ExprType::isString
bool isString() const
Definition: ExprType.h:169
SeExpr2::Expressions::evalStr
const char * evalStr(ExprEvalHandle eeh)
Definition: ExprMultiExpr.cpp:263
SeExpr2::GlobalFP
Definition: ExprMultiExpr.cpp:29
SeExpr2::Expression::context
const Context & context() const
Definition: Expression.h:216
ExprMultiExpr.h
SeExpr2::Expressions
Definition: ExprMultiExpr.h:49
SeExpr2::DExpression::DExpression
DExpression(const std::string &varName, Expressions &context, const std::string &e, const ExprType &type=ExprType().FP(3), EvaluationStrategy be=defaultEvaluationStrategy)
Definition: ExprMultiExpr.cpp:89
SeExpr2::GlobalVal::GlobalVal
GlobalVal(const std::string &varName, const SeExpr2::ExprType &et)
Definition: ExprMultiExpr.cpp:24
SeExpr2::GlobalStr::eval
void eval(double *result)
returns this variable's value by setting result
Definition: ExprMultiExpr.cpp:46
SeExpr2::GlobalVal
Definition: ExprMultiExpr.cpp:22
SeExpr2::Expressions::getExprEvalHandle
ExprEvalHandle getExprEvalHandle(ExprHandle eh)
Definition: ExprMultiExpr.cpp:228
SeExpr2::Expression::evalStr
const char * evalStr(VarBlock *varBlock=nullptr) const
Definition: Expression.cpp:339
SeExpr2::GlobalStr::GlobalStr
GlobalStr(const std::string &varName)
Definition: ExprMultiExpr.cpp:43
SeExpr2::GlobalStr::isVec
bool isVec()
Definition: ExprMultiExpr.cpp:48
SeExpr2::GlobalVal::users
std::set< DExpression * > users
Definition: ExprMultiExpr.cpp:25
SeExpr2::ExprEvalHandle
std::pair< ExprHandle, std::vector< DExpression * > > ExprEvalHandle
Definition: ExprMultiExpr.h:28
SeExpr2::DExpression::operandVars
std::set< GlobalVal * > operandVars
Definition: ExprMultiExpr.h:41
SeExpr2::ExprType::dim
int dim() const
Definition: ExprType.h:160
SeExpr2::ExprType
Definition: ExprType.h:39
SeExpr2::Expression::_desiredReturnType
ExprType _desiredReturnType
Definition: Expression.h:266
SeExpr2::GlobalFP::eval
void eval(double *result)
returns this variable's value by setting result
Definition: ExprMultiExpr.cpp:35
SeExpr2::Expressions::~Expressions
~Expressions()
Definition: ExprMultiExpr.cpp:145
SeExpr2::GlobalStr
Definition: ExprMultiExpr.cpp:42
SeExpr2::Expression::prepIfNeeded
void prepIfNeeded() const
Definition: Expression.h:274
SeExpr2
Definition: Context.h:22
SeExpr2::Expressions::evalFP
const std::vector< double > & evalFP(ExprEvalHandle eeh)
Definition: ExprMultiExpr.cpp:251
SeExpr2::VariableHandle
std::set< GlobalVal * >::iterator VariableHandle
Definition: ExprMultiExpr.h:23
SeExpr2::DExpression::resolveVar
ExprVarRef * resolveVar(const std::string &name) const
Definition: ExprMultiExpr.cpp:111
SeExpr2::DExpression
Definition: ExprMultiExpr.h:30
SeExpr2::Expressions::getLoopVarSetHandle
VariableSetHandle getLoopVarSetHandle(VariableHandle vh)
Definition: ExprMultiExpr.cpp:170
SeExpr2::DExpression::operandExprs
std::set< DExpression * > operandExprs
Definition: ExprMultiExpr.h:40
it
you may not use this file except in compliance with the License and the following modification to it
Definition: license.txt:10
SeExpr2::GlobalFP::GlobalFP
GlobalFP(const std::string &varName, int dim)
Definition: ExprMultiExpr.cpp:30
SeExpr2::DExpression::name
const std::string & name() const
Definition: ExprMultiExpr.cpp:109
SeExpr2::Expressions::AllExprs
std::set< DExpression * > AllExprs
Definition: ExprMultiExpr.h:54
SeExpr2::GlobalFP::isVec
bool isVec()
Definition: ExprMultiExpr.cpp:39
SeExpr2::Expression
main expression class
Definition: Expression.h:76
SeExpr2::ExprType::isFP
bool isFP() const
Direct is predicate checks.
Definition: ExprType.h:164
SeExpr2::DExpression::val
GlobalVal * val
Definition: ExprMultiExpr.h:43
SeExpr2::Expressions::setVariable
void setVariable(VariableHandle handle, double *values, unsigned dim)
Definition: ExprMultiExpr.cpp:199
be
< b ></b >< br >< b ></b ></td >< td > vector constructor< br > vector component access n must be
Definition: userdoc.txt:484
SeExpr2::GlobalFP::val
std::vector< double > val
Definition: ExprMultiExpr.cpp:34
SeExpr2::GlobalStr::eval
void eval(const char **result)
Definition: ExprMultiExpr.cpp:47
SeExpr2::Expressions::addExternalVariable
VariableHandle addExternalVariable(const std::string &variableName, ExprType seTy)
Definition: ExprMultiExpr.cpp:151
SeExpr2::DExpression::eval
void eval()
Definition: ExprMultiExpr.cpp:132
SeExpr2::GlobalVal::varName
std::string varName
Definition: ExprMultiExpr.cpp:26
SeExpr2::ExprHandle
std::set< DExpression * >::iterator ExprHandle
Definition: ExprMultiExpr.h:27
SeExpr2::Expressions::AllExternalVars
std::set< GlobalVal * > AllExternalVars
Definition: ExprMultiExpr.h:55
SeExpr2::Expression::EvaluationStrategy
EvaluationStrategy
Types of evaluation strategies that are available.
Definition: Expression.h:79
SeExpr2::Expressions::exprEvaled
std::set< DExpression * > exprEvaled
Definition: ExprMultiExpr.h:51
SeExpr2::GlobalStr::val
const char * val
Definition: ExprMultiExpr.cpp:45
SeExpr2::Expressions::exprToEval
std::set< DExpression * > exprToEval
Definition: ExprMultiExpr.h:50
SeExpr2::Expressions::isValid
bool isValid() const
Definition: ExprMultiExpr.cpp:221
SeExpr2::Expressions::addExpression
ExprHandle addExpression(const std::string &varName, ExprType seTy, const std::string &expr)
Definition: ExprMultiExpr.cpp:164
SeExpr2::Expression::evalFP
const double * evalFP(VarBlock *varBlock=nullptr) const
Definition: Expression.cpp:304
SeExpr2::VariableSetHandle
std::set< GlobalVal * >::iterator VariableSetHandle
Definition: ExprMultiExpr.h:26
SeExpr2::Expressions::setLoopVariable
void setLoopVariable(VariableSetHandle handle, double *values, unsigned dim)
Definition: ExprMultiExpr.cpp:181
SeExpr2::Expression::addError
void addError(const std::string &error, const int startPos, const int endPos) const
Definition: Expression.h:205
SeExpr2::GlobalFP::eval
void eval(const char **result)
Definition: ExprMultiExpr.cpp:38
SeExpr2::ExprVarRef
abstract class for implementing variable references
Definition: Expression.h:45
SeExpr2::ExprVarRef::type
virtual ExprType type() const
returns (current) type
Definition: Expression.h:59
context
If a scalar is used in a vector context
Definition: userdoc.txt:436
expr
</pre >< h3 > Binding our variable reference</h3 > If we now tried to use the variable would still not be found by our expressions To make it bindable we need to override the resolveVar() function as follows</pre >< h3 > Variable setting</h3 > Next we need to make a way of setting the variable As the controlling code will use the expression it will repeatedly alternate between setting the independent variables that are used and calling evaluate(). What it has to do depends very much on the application. In this case we only need to set the independent variable x as</pre >< h2 > Evaluating expressions</h2 > Evaluating an expression is pretty easy But before we can do that we need to make an instance< pre > GrapherExpr expr("x+x^2")