OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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 parses and evaluates string expressions (objectives or
8// constraints) using a hand-written recursive-descent parser.
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 <iostream>
34#include <map>
35#include <set>
36#include <string>
37#include <string_view>
38#include <tuple>
39#include <variant>
40
41#include "Util/Types.h"
43
48
49
50typedef std::map<std::string, double> variableDictionary_t;
51typedef std::map<std::string, client::function::type> functionDictionary_t;
52
53class Expression;
54namespace Expressions {
55
58
59 // result of an evaluated expression
60 typedef std::tuple<double, bool> Result_t;
65
66 //FIXME: this actually should be a map of type (name, fusion::vector<...>)
68 typedef std::map<std::string, Expressions::Expr_t*> Named_t;
69
70 //XXX name of one single expression
71 typedef std::pair<std::string, Expressions::Expr_t*> SingleNamed_t;
72
74 enum class OperatorType_t {
75 NONE,
76 EQ, // ==
77 NOT_EQ, // !=
78 INEQ_LHS, // <
79 INEQ_LHS_EQ, // <=
80 INEQ_RHS, // >
81 INEQ_RHS_EQ // >=
82 };
83}
84
86
88
89public:
91 {}
92
93 Expression(std::string expr)
94 : expr_(expr)
95 {
97 functionDictionary_t global_funcs = GlobalFunctions::get();
98 known_expr_funcs_.insert(global_funcs.begin(), global_funcs.end());
99 parse();
100 }
101
102 Expression(std::string expr, functionDictionary_t known_expr_funcs)
103 : expr_(std::move(expr))
104 , known_expr_funcs_(known_expr_funcs)
105 {
107 functionDictionary_t global_funcs = GlobalFunctions::get();
108 known_expr_funcs_.insert(global_funcs.begin(), global_funcs.end());
109 parse();
110 }
111
112 virtual ~Expression()
113 {}
114
115 const std::set<std::string>& getReqVars() const { return vars_; }
116 const std::set<std::string>& getReqFuncs() const { return funcs_; }
117 const std::string& toString() const { return expr_; }
118
120
123
126
127 iterator_type iter = expr_.begin();
128 iterator_type end = expr_.end();
129 client::error_handler<iterator_type> error_handler(iter, end);
130 client::code_gen::StackEvaluator evaluator(error_handler);
131 evaluator.registerVariables(vars);
133
134 double result = 0.0;
135 bool valid = false;
136 if (evaluator(ast_)) {
137 result = evaluator.result();
138 valid = true;
139 }
140
141 return std::make_tuple(result, valid);
142 }
143
144private:
145 typedef std::string::const_iterator iterator_type;
147
148 std::set<std::string> vars_;
149 std::set<std::string> funcs_;
150
151 std::string expr_;
153
155
158 std::string_view op(expr_);
159
160 constexpr std::pair<std::string_view, Expressions::OperatorType_t> op_map[] = {
167 };
168
169 for (const auto& p : op_map) {
170 if (op.find(p.first) != std::string_view::npos) {
171 type_ = p.second;
172 break;
173 }
174 }
175 }
176
177 void parse() {
178 iterator_type iter = expr_.begin();
179 iterator_type end = expr_.end();
180
181 client::error_handler<iterator_type> error_handler(iter, end);
182 client::parser::expression<iterator_type> expression(error_handler);
183 client::code_gen::requirements requirements(error_handler);
184
185 bool success = expression.parse(iter, end, ast_);
186
187 if (!success || iter != end) {
188 std::cout << "Parsing failed!" << std::endl;
189 std::string here = (iter != end ? std::string(iter, end): expr_);
190 throw OptPilotException("Expression::parse()",
191 "Parsing failed here: " + here + "!");
192 }
193
194 // store the functions and variables required to evaluate this
195 // expression
196 if (requirements(ast_)) {
197 vars_ = requirements.variables();
198 funcs_ = requirements.functions();
199 }
200 }
201};
202
203#endif
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
std::map< std::string, client::function::type > functionDictionary_t
Definition Expression.h:51
std::map< std::string, double > variableDictionary_t
Definition Expression.h:50
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:68
Expression Expr_t
type of an expression
Definition Expression.h:57
OperatorType_t
distinguish different constraints
Definition Expression.h:74
std::tuple< double, bool > Result_t
Definition Expression.h:60
std::pair< std::string, Expressions::Expr_t * > SingleNamed_t
Definition Expression.h:71
std::set< std::string > vars_
Definition Expression.h:148
std::set< std::string > funcs_
Definition Expression.h:149
functionDictionary_t known_expr_funcs_
Definition Expression.h:152
virtual ~Expression()
Definition Expression.h:112
Expressions::OperatorType_t type_
Definition Expression.h:154
client::ast::expression ast_
Definition Expression.h:146
std::string::const_iterator iterator_type
Definition Expression.h:145
const std::set< std::string > & getReqFuncs() const
Definition Expression.h:116
void determineConstrOperator()
Definition Expression.h:156
Expressions::OperatorType_t getOpType() const
get operator type present (if expression is constraint)
Definition Expression.h:122
std::string expr_
Definition Expression.h:151
void parse()
Definition Expression.h:177
functionDictionary_t getRegFuncs() const
Definition Expression.h:119
const std::string & toString() const
Definition Expression.h:117
Expressions::Result_t evaluate(const variableDictionary_t &vars)
evaluate an expression given a value dictionary of free variables
Definition Expression.h:125
Expression(std::string expr)
Definition Expression.h:93
Expression(std::string expr, functionDictionary_t known_expr_funcs)
Definition Expression.h:102
const std::set< std::string > & getReqVars() const
Definition Expression.h:115
void registerVariables(std::map< std::string, double > variableDictionary)
Definition evaluator.hpp:56
void registerFunctions(std::map< std::string, client::function::type > functions)
Definition evaluator.hpp:51
bool parse(Iterator &first, Iterator last, ast::expression &attr)
std::set< std::string > variables()
std::set< std::string > functions()