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 = 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 }
void prepIfNeeded() const
Definition: Expression.h:274
std::set< DExpression * > operandExprs
Definition: ExprMultiExpr.h:40
EvaluationStrategy
Types of evaluation strategies that are available.
Definition: Expression.h:79
void eval(const char **result)
int dim() const
Definition: ExprType.h:160
GlobalVal(const std::string &varName, const SeExpr2::ExprType &et)
</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")
VariableHandle addExternalVariable(const std::string &variableName, ExprType seTy)
void addError(const std::string &error, const int startPos, const int endPos) const
Definition: Expression.h:205
void setVariable(VariableHandle handle, double *values, unsigned dim)
bool isFP() const
Direct is predicate checks.
Definition: ExprType.h:164
std::set< GlobalVal * > AllExternalVars
Definition: ExprMultiExpr.h:55
std::set< DExpression * > users
bool isString() const
Definition: ExprType.h:169
std::pair< ExprHandle, std::vector< DExpression * > > ExprEvalHandle
Definition: ExprMultiExpr.h:28
ExprHandle addExpression(const std::string &varName, ExprType seTy, const std::string &expr)
std::set< GlobalVal * >::iterator VariableHandle
Definition: ExprMultiExpr.h:23
std::set< DExpression * > exprToEval
Definition: ExprMultiExpr.h:50
std::set< DExpression * > exprEvaled
Definition: ExprMultiExpr.h:51
void setLoopVariable(VariableSetHandle handle, double *values, unsigned dim)
ExprType _desiredReturnType
Definition: Expression.h:266
const char * evalStr(ExprEvalHandle eeh)
void eval(double *result)
returns this variable&#39;s value by setting result
void eval(const char **result)
void eval(double *result)
returns this variable&#39;s value by setting result
main expression class
Definition: Expression.h:76
std::set< DExpression * >::iterator ExprHandle
Definition: ExprMultiExpr.h:27
ExprEvalHandle getExprEvalHandle(ExprHandle eh)
DExpression(const std::string &varName, Expressions &context, const std::string &e, const ExprType &type=ExprType().FP(3), EvaluationStrategy be=defaultEvaluationStrategy)
If a scalar is used in a vector context
Definition: userdoc.txt:456
const double * evalFP(VarBlock *varBlock=nullptr) const
Definition: Expression.cpp:299
< b ></b >< br >< b ></b ></td >< td > vector constructor< br > vector component access n must be
Definition: userdoc.txt:504
const char * evalStr(VarBlock *varBlock=nullptr) const
Definition: Expression.cpp:335
GlobalStr(const std::string &varName)
const std::string & name() const
std::set< GlobalVal * >::iterator VariableSetHandle
Definition: ExprMultiExpr.h:26
virtual ExprType type() const
returns (current) type
Definition: Expression.h:59
std::set< GlobalVal * > operandVars
Definition: ExprMultiExpr.h:41
VariableSetHandle getLoopVarSetHandle(VariableHandle vh)
you may not use this file except in compliance with the License and the following modification to it
Definition: license.txt:10
GlobalFP(const std::string &varName, int dim)
abstract class for implementing variable references
Definition: Expression.h:45
const std::vector< double > & evalFP(ExprEvalHandle eeh)
ExprVarRef * resolveVar(const std::string &name) const
std::set< DExpression * > AllExprs
Definition: ExprMultiExpr.h:54
std::vector< double > val