OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
Expression.h
Go to the documentation of this file.
1 //
2 // Class Expression
3 // Expression to be evaluated in the framework.
4 //
5 // @see GlobalFunctions.h
6 //
7 // This class uses the Boost Spirit parser to parse and evaluate string
8 // expressions (objectives or constraints).
9 // Custom functions called in the expression should be registered by the
10 // driver. A collection of C math default functions is always included.
11 // For constraints the operator type can be queried.
12 //
13 // Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
14 // All rights reserved
15 //
16 // Implemented as part of the PhD thesis
17 // "Toward massively parallel multi-objective optimization with application to
18 // particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
19 //
20 // This file is part of OPAL.
21 //
22 // OPAL is free software: you can redistribute it and/or modify
23 // it under the terms of the GNU General Public License as published by
24 // the Free Software Foundation, either version 3 of the License, or
25 // (at your option) any later version.
26 //
27 // You should have received a copy of the GNU General Public License
28 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
29 //
30 #ifndef __EXPRESSION_H__
31 #define __EXPRESSION_H__
32 
33 #include <map>
34 #include <set>
35 #include <string>
36 
37 #include "Util/Types.h"
38 #include "Util/OptPilotException.h"
39 
45 
46 #include <boost/function.hpp>
47 #include <boost/lexical_cast.hpp>
48 #include <boost/variant/get.hpp>
49 #include <boost/variant/variant.hpp>
50 #include "boost/smart_ptr.hpp"
51 #include "boost/tuple/tuple.hpp"
52 #include "boost/algorithm/string.hpp"
53 
54 
55 typedef std::map<std::string, double> variableDictionary_t;
56 typedef std::map<std::string, client::function::type> functionDictionary_t;
57 
58 
59 class Expression;
60 namespace Expressions {
61 
63  typedef Expression Expr_t;
64 
65  // result of an evaluated expression
66  typedef boost::tuple<double, bool> Result_t;
69  IS_VALID
70  };
71 
72  //FIXME: this actually should be a map of type (name, fusion::vector<...>)
74  typedef std::map<std::string, Expressions::Expr_t*> Named_t;
75 
76  //XXX name of one single expression
77  typedef std::pair<std::string, Expressions::Expr_t*> SingleNamed_t;
78 
82  EQ, // ==
83  NOT_EQ, // !=
84  INEQ_LHS, // <
85  INEQ_LHS_EQ, // <=
86  INEQ_RHS, // >
87  INEQ_RHS_EQ // >=
88  };
89 
90 }
91 
93 
94 class Expression {
95 
96 public:
97 
99  {}
100 
101  Expression(std::string expr)
102  : expr_(expr)
103  {
105  functionDictionary_t global_funcs = GlobalFunctions::get();
106  known_expr_funcs_.insert(global_funcs.begin(), global_funcs.end());
107  parse();
108  }
109 
110  Expression(std::string expr, functionDictionary_t known_expr_funcs)
111  : expr_(expr)
112  , known_expr_funcs_(known_expr_funcs)
113  {
115  functionDictionary_t global_funcs = GlobalFunctions::get();
116  known_expr_funcs_.insert(global_funcs.begin(), global_funcs.end());
117  parse();
118  }
119 
120  virtual ~Expression()
121  {}
122 
123 
124  std::set<std::string> getReqVars() const { return vars_; }
125  std::set<std::string> getReqFuncs() const { return funcs_; }
126  std::string toString() const { return expr_; }
128 
131 
134 
135  iterator_type iter = expr_.begin();
136  iterator_type end = expr_.end();
137  client::error_handler<iterator_type> error_handler(iter, end);
138  client::code_gen::StackEvaluator evaluator(error_handler);
139  evaluator.registerVariables(vars);
141 
142  double result = 0.0;
143  bool valid = false;
144  if (evaluator(ast_)) {
145  result = evaluator.result();
146  valid = true;
147  }
148 
149  return boost::make_tuple(result, valid);
150  }
151 
152 
153 private:
154 
155  typedef std::string::const_iterator iterator_type;
157 
158  std::set<std::string> vars_;
159  std::set<std::string> funcs_;
160 
161  std::string expr_;
163 
165 
167 
168  std::string op = expr_;
169 
170  if(boost::find_first(op, "=="))
172  else if(boost::find_first(op, "!="))
174  else if(boost::find_first(op, "<="))
176  else if(boost::find_first(op, "<"))
178  else if(boost::find_first(op, ">="))
180  else if(boost::find_first(op,">"))
182  else
184  }
185 
186  void parse() {
187 
188  iterator_type iter = expr_.begin();
189  iterator_type end = expr_.end();
190 
191  client::error_handler<iterator_type> error_handler(iter, end);
192  client::parser::expression<iterator_type> expression(error_handler);
194  client::code_gen::requirements requirements(error_handler);
195 
196  bool success = phrase_parse(iter, end, expression, skipper, ast_);
197 
198  if (!success || iter != end) {
199  std::cout << "Parsing failed!" << std::endl;
200  std::string here = (iter != end ? std::string(iter, end): expr_);
201  throw new OptPilotException("Expression::parse()",
202  "Parsing failed here: " + here + "!");
203  }
204 
205  // store the functions and variables required to evaluate this
206  // expression
207  if (requirements(ast_)) {
208  vars_ = requirements.variables();
209  funcs_ = requirements.functions();
210  }
211  }
212 };
213 
214 #endif
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
std::map< std::string, client::function::type > functionDictionary_t
Definition: Expression.h:56
std::map< std::string, double > variableDictionary_t
Definition: Expression.h:55
Representation objects and parsers for attribute expressions.
Definition: Expressions.h:64
std::map< std::string, Expressions::Expr_t * > Named_t
type of an expressions with a name
Definition: Expression.h:74
Expression Expr_t
type of an expression
Definition: Expression.h:63
OperatorType_t
distinguish different constraints
Definition: Expression.h:80
boost::tuple< double, bool > Result_t
Definition: Expression.h:66
std::pair< std::string, Expressions::Expr_t * > SingleNamed_t
Definition: Expression.h:77
std::set< std::string > vars_
Definition: Expression.h:158
std::set< std::string > funcs_
Definition: Expression.h:159
functionDictionary_t known_expr_funcs_
Definition: Expression.h:162
virtual ~Expression()
Definition: Expression.h:120
std::set< std::string > getReqVars() const
Definition: Expression.h:124
std::string toString() const
Definition: Expression.h:126
Expressions::OperatorType_t type_
Definition: Expression.h:164
client::ast::expression ast_
Definition: Expression.h:156
std::string::const_iterator iterator_type
Definition: Expression.h:155
void determineConstrOperator()
Definition: Expression.h:166
Expressions::OperatorType_t getOpType() const
get operator type present (if expression is constraint)
Definition: Expression.h:130
std::string expr_
Definition: Expression.h:161
std::set< std::string > getReqFuncs() const
Definition: Expression.h:125
void parse()
Definition: Expression.h:186
functionDictionary_t getRegFuncs() const
Definition: Expression.h:127
Expression(std::string expr)
Definition: Expression.h:101
Expressions::Result_t evaluate(variableDictionary_t vars)
evaluate an expression given a value dictionary of free variables
Definition: Expression.h:133
Expression(std::string expr, functionDictionary_t known_expr_funcs)
Definition: Expression.h:110
void registerVariables(std::map< std::string, double > variableDictionary)
Definition: evaluator.hpp:61
void registerFunctions(std::map< std::string, client::function::type > functions)
Definition: evaluator.hpp:56
std::set< std::string > functions()
std::set< std::string > variables()