OGS 6.2.1-97-g73d1aeda3
NumLib::NamedFunctionCaller Class Referencefinal

Detailed Description

Builds expression trees of named functions dynamically at runtime.

Definition at line 21 of file NamedFunctionCaller.h.

#include <NamedFunctionCaller.h>

Classes

struct  SinkSource
 

Public Member Functions

 NamedFunctionCaller (std::initializer_list< std::string > unbound_argument_names)
 Constructs an instance whose unbound arguments have the given names. More...
 
void addNamedFunction (NamedFunction &&fct)
 Adds the given named function. More...
 
std::vector< NamedFunction > const & getNamedFunctions () const
 Returns all named functions associated with the caller instance. More...
 
void plug (std::string const &sink_fct, std::string const &sink_arg, std::string const &source_fct)
 
void applyPlugs ()
 
SpecificFunctionCaller getSpecificFunctionCaller (std::string const &function_name)
 
std::string getCallExpression (std::string const &function_name) const
 
std::size_t getNumberOfUnboundArguments () const
 Returns the number of unbound arguments. More...
 

Private Member Functions

double call (std::size_t function_idx, std::vector< double > const &unbound_arguments) const
 

Private Attributes

std::map< std::string, int > _map_name_idx
 
std::vector< NamedFunction_named_functions
 Contains all named functions. More...
 
std::vector< std::vector< int > > _map_sink_source
 
const int _uninitialized
 
std::vector< SinkSource_deferred_plugs
 Saves plugs declared by plug(). More...
 

Friends

class SpecificFunctionCaller
 

Constructor & Destructor Documentation

◆ NamedFunctionCaller()

NumLib::NamedFunctionCaller::NamedFunctionCaller ( std::initializer_list< std::string >  unbound_argument_names)

Constructs an instance whose unbound arguments have the given names.

Definition at line 116 of file NamedFunctionCaller.cpp.

References _map_name_idx, and BaseLib::insertIfKeyUniqueElseError().

118  : _uninitialized(-1 - static_cast<int>(unbound_argument_names.size()))
119 {
120  assert(unbound_argument_names.size() <
121  static_cast<std::size_t>(std::numeric_limits<int>::max()));
122  int idx = -1;
123  for (auto arg : unbound_argument_names) {
125  _map_name_idx, arg, idx,
126  "The name of the unbound argument is not unique.");
127  --idx;
128  }
129 }
std::map< std::string, int > _map_name_idx
void insertIfKeyUniqueElseError(Map &map, Key const &key, Value &&value, std::string const &error_message)
Definition: Algorithm.h:104

Member Function Documentation

◆ addNamedFunction()

void NumLib::NamedFunctionCaller::addNamedFunction ( NamedFunction &&  fct)

Adds the given named function.

Definition at line 131 of file NamedFunctionCaller.cpp.

References _map_name_idx, _map_sink_source, _named_functions, _uninitialized, and BaseLib::insertIfKeyUniqueElseError().

Referenced by ProcessLib::TES::TESProcess::initializeSecondaryVariables().

132 {
133  DBUG("Adding named function `%s'", fct.getName().c_str());
134 
136  _map_name_idx, fct.getName(), _named_functions.size(),
137  "The name of the function is not unique.");
138 
139  _map_sink_source.emplace_back(fct.getArgumentNames().size(),
141  _named_functions.push_back(std::move(fct));
142 }
std::map< std::string, int > _map_name_idx
void insertIfKeyUniqueElseError(Map &map, Key const &key, Value &&value, std::string const &error_message)
Definition: Algorithm.h:104
std::vector< NamedFunction > _named_functions
Contains all named functions.
std::vector< std::vector< int > > _map_sink_source

◆ applyPlugs()

void NumLib::NamedFunctionCaller::applyPlugs ( )

Actually plug all the plugs previously declared.

Precondition
All functions involved must have been added.

Definition at line 151 of file NamedFunctionCaller.cpp.

References _deferred_plugs, _map_name_idx, _map_sink_source, _named_functions, _uninitialized, hasTopologicalOrdering(), OGS_FATAL, and plug().

Referenced by ProcessLib::Process::finishNamedFunctionsInitialization(), and getNamedFunctions().

152 {
153  while (!_deferred_plugs.empty())
154  {
155  auto const& plug = _deferred_plugs.back();
156  auto const& sink_fct = plug.sink_fct;
157  auto const& sink_arg = plug.sink_arg;
158  auto const& source = plug.source;
159 
160  auto const source_it = _map_name_idx.find(source);
161  if (source_it == _map_name_idx.end())
162  {
163  OGS_FATAL("A function with the name `%s' has not been found.",
164  source.c_str());
165  }
166  auto const source_idx = source_it->second;
167 
168  auto const sink_it = _map_name_idx.find(sink_fct);
169  if (sink_it == _map_name_idx.end())
170  {
171  OGS_FATAL("A function with the name `%s' has not been found.",
172  sink_fct.c_str());
173  }
174  auto const sink_fct_idx = sink_it->second;
175 
176  auto const& sink_args =
177  _named_functions[sink_it->second].getArgumentNames();
178  auto const sink_arg_it =
179  std::find(sink_args.begin(), sink_args.end(), sink_arg);
180  if (sink_arg_it == sink_args.end())
181  {
182  OGS_FATAL(
183  "An argument with the name `%s' has not been found for the "
184  "function `%s'.",
185  sink_arg.c_str(), sink_fct.c_str());
186  }
187  std::size_t const sink_arg_idx =
188  std::distance(sink_args.begin(), sink_arg_it);
189 
190  auto& sis_sos = _map_sink_source[sink_fct_idx];
191  if (sis_sos[sink_arg_idx] != _uninitialized)
192  {
193  OGS_FATAL("A dependency for `%s'.`%s' has already been introduced.",
194  sink_fct.c_str(), sink_arg.c_str());
195  }
196  sis_sos[sink_arg_idx] = source_idx;
198  {
199  OGS_FATAL(
200  "The call graph being plugged together must be an acyclic "
201  "graph. The added dependency for `%s'.`%s' introduces a cycle "
202  "into the graph.",
203  sink_fct.c_str(), sink_arg.c_str());
204  }
205 
206  _deferred_plugs.pop_back();
207  }
208 }
void plug(std::string const &sink_fct, std::string const &sink_arg, std::string const &source_fct)
bool hasTopologicalOrdering(std::vector< std::vector< int >> const &graph)
std::map< std::string, int > _map_name_idx
std::vector< SinkSource > _deferred_plugs
Saves plugs declared by plug().
std::vector< NamedFunction > _named_functions
Contains all named functions.
#define OGS_FATAL(fmt,...)
Definition: Error.h:63
std::vector< std::vector< int > > _map_sink_source

◆ call()

double NumLib::NamedFunctionCaller::call ( std::size_t  function_idx,
std::vector< double > const &  unbound_arguments 
) const
private

Calls the function with the given index with the given unbound arguments.

Definition at line 210 of file NamedFunctionCaller.cpp.

References _deferred_plugs, _map_sink_source, _named_functions, and _uninitialized.

Referenced by NumLib::SpecificFunctionCaller::call(), and getNamedFunctions().

213 {
214  assert(_deferred_plugs.empty() &&
215  "You must call applyPlugs() before this method!");
216 
217  auto const& sis_sos = _map_sink_source[function_idx];
218  assert(sis_sos.size() ==
219  _named_functions[function_idx].getArgumentNames().size());
220  std::vector<double> fct_args(sis_sos.size());
221 
222  for (std::size_t sink=0; sink<sis_sos.size(); ++sink)
223  {
224  auto const source = sis_sos[sink];
225 
226  if (source >= 0) {
227  fct_args[sink] = call(source, unbound_arguments);
228  } else {
229  assert(source != _uninitialized);
230  fct_args[sink] = unbound_arguments[-source-1];
231  }
232  }
233 
234  return _named_functions[function_idx].call(fct_args);
235 }
double call(std::size_t function_idx, std::vector< double > const &unbound_arguments) const
std::vector< SinkSource > _deferred_plugs
Saves plugs declared by plug().
std::vector< NamedFunction > _named_functions
Contains all named functions.
std::vector< std::vector< int > > _map_sink_source

◆ getCallExpression()

std::string NumLib::NamedFunctionCaller::getCallExpression ( std::string const &  function_name) const

Returns a string representing the expression graph of the given function.

Precondition
applyPlugs() must have been called before.

Definition at line 237 of file NamedFunctionCaller.cpp.

References _map_name_idx, _map_sink_source, _named_functions, BetweenChildren, EndNode, OGS_FATAL, StartNode, and traverse().

Referenced by getNamedFunctions().

239 {
240  auto const fct_it = _map_name_idx.find(function_name);
241  if (fct_it == _map_name_idx.end()) {
242  OGS_FATAL("A function with the name `%s' has not been found.",
243  function_name.c_str());
244  }
245 
246  std::string expr;
247  auto callback = [&](int fct_idx, TraversePosition pos)
248  {
249  switch (pos) {
251  {
252  if (fct_idx < 0) {
253  auto it = std::find_if(
254  _map_name_idx.begin(), _map_name_idx.end(),
255  [fct_idx](std::pair<std::string, int> const& e) {
256  return e.second == fct_idx;
257  });
258  if (it == _map_name_idx.end()) {
259  OGS_FATAL("The function index %i has not been found.", fct_idx);
260  }
261  expr += it->first;
262  } else {
263  expr += _named_functions[fct_idx].getName() + "(";
264  }
265  break;
266  }
268  expr += ", ";
269  break;
271  expr += ")";
272  }
273  };
274 
275  traverse(_map_sink_source, fct_it->second, callback);
276  DBUG("expression: %s", expr.c_str());
277  return expr;
278 }
void traverse(std::vector< std::vector< int >> const &map_sink_source, int sink_fct, Callback &&callback)
std::map< std::string, int > _map_name_idx
TraversePosition
std::vector< NamedFunction > _named_functions
Contains all named functions.
#define OGS_FATAL(fmt,...)
Definition: Error.h:63
std::vector< std::vector< int > > _map_sink_source

◆ getNamedFunctions()

std::vector<NamedFunction> const& NumLib::NamedFunctionCaller::getNamedFunctions ( ) const
inline

Returns all named functions associated with the caller instance.

Definition at line 32 of file NamedFunctionCaller.h.

References _named_functions, applyPlugs(), call(), getCallExpression(), getNumberOfUnboundArguments(), getSpecificFunctionCaller(), and plug().

Referenced by ProcessLib::Process::finishNamedFunctionsInitialization().

33  {
34  return _named_functions;
35  }
std::vector< NamedFunction > _named_functions
Contains all named functions.

◆ getNumberOfUnboundArguments()

std::size_t NumLib::NamedFunctionCaller::getNumberOfUnboundArguments ( ) const

Returns the number of unbound arguments.

Definition at line 291 of file NamedFunctionCaller.cpp.

References _uninitialized.

Referenced by getNamedFunctions(), and NumLib::SpecificFunctionCaller::getNumberOfUnboundArguments().

292 {
293  return -_uninitialized - 1;
294 }

◆ getSpecificFunctionCaller()

SpecificFunctionCaller NumLib::NamedFunctionCaller::getSpecificFunctionCaller ( std::string const &  function_name)

Creates a function caller that is able to call the function with the given name.

Definition at line 281 of file NamedFunctionCaller.cpp.

References _map_name_idx, OGS_FATAL, and SpecificFunctionCaller.

Referenced by ProcessLib::Process::finishNamedFunctionsInitialization(), and getNamedFunctions().

282 {
283  auto const fct_it = _map_name_idx.find(function_name);
284  if (fct_it == _map_name_idx.end()) {
285  OGS_FATAL("A function with the name `%s' has not been found.",
286  function_name.c_str());
287  }
288  return SpecificFunctionCaller(fct_it->second, *this);
289 }
std::map< std::string, int > _map_name_idx
#define OGS_FATAL(fmt,...)
Definition: Error.h:63

◆ plug()

void NumLib::NamedFunctionCaller::plug ( std::string const &  sink_fct,
std::string const &  sink_arg,
std::string const &  source_fct 
)

Declares that the argument with name sink_arg of the function sink_fct is being computed by the function source_fct.

The functions involved need not already be known to the NamedFunctionCaller.

Definition at line 144 of file NamedFunctionCaller.cpp.

References _deferred_plugs.

Referenced by applyPlugs(), ProcessLib::createSecondaryVariables(), getNamedFunctions(), and ProcessLib::TES::TESProcess::initializeSecondaryVariables().

147 {
148  _deferred_plugs.push_back({sink_fct, sink_arg, source_fct});
149 }
std::vector< SinkSource > _deferred_plugs
Saves plugs declared by plug().

Friends And Related Function Documentation

◆ SpecificFunctionCaller

friend class SpecificFunctionCaller
friend

Definition at line 97 of file NamedFunctionCaller.h.

Referenced by getSpecificFunctionCaller().

Member Data Documentation

◆ _deferred_plugs

std::vector<SinkSource> NumLib::NamedFunctionCaller::_deferred_plugs
private

Saves plugs declared by plug().

Definition at line 95 of file NamedFunctionCaller.h.

Referenced by applyPlugs(), call(), and plug().

◆ _map_name_idx

std::map<std::string, int> NumLib::NamedFunctionCaller::_map_name_idx
private

Maps function names to indices. Negative indices refer to unbound arguments.

Definition at line 72 of file NamedFunctionCaller.h.

Referenced by addNamedFunction(), applyPlugs(), getCallExpression(), getSpecificFunctionCaller(), and NamedFunctionCaller().

◆ _map_sink_source

std::vector<std::vector<int> > NumLib::NamedFunctionCaller::_map_sink_source
private

The expression graph. Contains for each named function (outer vector) a vector which maps each function argument to the source function index that computes this argument.

Definition at line 81 of file NamedFunctionCaller.h.

Referenced by addNamedFunction(), applyPlugs(), call(), and getCallExpression().

◆ _named_functions

std::vector<NamedFunction> NumLib::NamedFunctionCaller::_named_functions
private

Contains all named functions.

Definition at line 75 of file NamedFunctionCaller.h.

Referenced by addNamedFunction(), applyPlugs(), call(), getCallExpression(), and getNamedFunctions().

◆ _uninitialized

const int NumLib::NamedFunctionCaller::_uninitialized
private

Magic number used to mark function arguments in _map_sink_source whose source functions have not yet been set up.

Definition at line 85 of file NamedFunctionCaller.h.

Referenced by addNamedFunction(), applyPlugs(), call(), and getNumberOfUnboundArguments().


The documentation for this class was generated from the following files: