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,
90 Expressions &context,
91 const std::string &e,
92 const ExprType &type,
93 EvaluationStrategy be)
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
132 void DExpression::eval() {
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
145 Expressions::~Expressions() {
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
170 VariableSetHandle Expressions::getLoopVarSetHandle(VariableHandle vh) {
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
228 ExprEvalHandle Expressions::getExprEvalHandle(ExprHandle eh) {
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
263 const char *Expressions::evalStr(ExprEvalHandle eeh) {
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")