OGS 6.2.0-244-g47b8a9a9d
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)
explicit

Constructs an instance whose unbound arguments have the given names.

Definition at line 115 of file NamedFunctionCaller.cpp.

References _map_name_idx, and BaseLib::insertIfKeyUniqueElseError().

117  : _uninitialized(-1 - unbound_argument_names.size())
118 {
119  int idx = -1;
120  for (auto arg : unbound_argument_names) {
122  _map_name_idx, arg, idx,
123  "The name of the unbound argument is not unique.");
124  --idx;
125  }
126 }
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 128 of file NamedFunctionCaller.cpp.

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

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

129 {
130  DBUG("Adding named function `%s'", fct.getName().c_str());
131 
133  _map_name_idx, fct.getName(), _named_functions.size(),
134  "The name of the function is not unique.");
135 
136  _map_sink_source.emplace_back(fct.getArgumentNames().size(),
138  _named_functions.push_back(std::move(fct));
139 }
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 148 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().

149 {
150  while (!_deferred_plugs.empty())
151  {
152  auto const& plug = _deferred_plugs.back();
153  auto const& sink_fct = plug.sink_fct;
154  auto const& sink_arg = plug.sink_arg;
155  auto const& source = plug.source;
156 
157  auto const source_it = _map_name_idx.find(source);
158  if (source_it == _map_name_idx.end())
159  {
160  OGS_FATAL("A function with the name `%s' has not been found.",
161  source.c_str());
162  }
163  auto const source_idx = source_it->second;
164 
165  auto const sink_it = _map_name_idx.find(sink_fct);
166  if (sink_it == _map_name_idx.end())
167  {
168  OGS_FATAL("A function with the name `%s' has not been found.",
169  sink_fct.c_str());
170  }
171  auto const sink_fct_idx = sink_it->second;
172 
173  auto const& sink_args =
174  _named_functions[sink_it->second].getArgumentNames();
175  auto const sink_arg_it =
176  std::find(sink_args.begin(), sink_args.end(), sink_arg);
177  if (sink_arg_it == sink_args.end())
178  {
179  OGS_FATAL(
180  "An argument with the name `%s' has not been found for the "
181  "function `%s'.",
182  sink_arg.c_str(), sink_fct.c_str());
183  }
184  std::size_t const sink_arg_idx =
185  std::distance(sink_args.begin(), sink_arg_it);
186 
187  auto& sis_sos = _map_sink_source[sink_fct_idx];
188  if (sis_sos[sink_arg_idx] != _uninitialized)
189  {
190  OGS_FATAL("A dependency for `%s'.`%s' has already been introduced.",
191  sink_fct.c_str(), sink_arg.c_str());
192  }
193  sis_sos[sink_arg_idx] = source_idx;
195  {
196  OGS_FATAL(
197  "The call graph being plugged together must be an acyclic "
198  "graph. The added dependency for `%s'.`%s' introduces a cycle "
199  "into the graph.",
200  sink_fct.c_str(), sink_arg.c_str());
201  }
202 
203  _deferred_plugs.pop_back();
204  }
205 }
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 207 of file NamedFunctionCaller.cpp.

References _deferred_plugs, _map_sink_source, _named_functions, and _uninitialized.

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

210 {
211  assert(_deferred_plugs.empty() &&
212  "You must call applyPlugs() before this method!");
213 
214  auto const& sis_sos = _map_sink_source[function_idx];
215  assert(sis_sos.size() ==
216  _named_functions[function_idx].getArgumentNames().size());
217  std::vector<double> fct_args(sis_sos.size());
218 
219  for (std::size_t sink=0; sink<sis_sos.size(); ++sink)
220  {
221  auto const source = sis_sos[sink];
222 
223  if (source >= 0) {
224  fct_args[sink] = call(source, unbound_arguments);
225  } else {
226  assert(source != _uninitialized);
227  fct_args[sink] = unbound_arguments[-source-1];
228  }
229  }
230 
231  return _named_functions[function_idx].call(fct_args);
232 }
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 234 of file NamedFunctionCaller.cpp.

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

Referenced by getNamedFunctions().

236 {
237  auto const fct_it = _map_name_idx.find(function_name);
238  if (fct_it == _map_name_idx.end()) {
239  OGS_FATAL("A function with the name `%s' has not been found.",
240  function_name.c_str());
241  }
242 
243  std::string expr;
244  auto callback = [&](int fct_idx, TraversePosition pos)
245  {
246  switch (pos) {
248  {
249  if (fct_idx < 0) {
250  auto it = std::find_if(
251  _map_name_idx.begin(), _map_name_idx.end(),
252  [fct_idx](std::pair<std::string, int> const& e) {
253  return e.second == fct_idx;
254  });
255  if (it == _map_name_idx.end()) {
256  OGS_FATAL("The function index %i has not been found.", fct_idx);
257  }
258  expr += it->first;
259  } else {
260  expr += _named_functions[fct_idx].getName() + "(";
261  }
262  break;
263  }
265  expr += ", ";
266  break;
268  expr += ")";
269  }
270  };
271 
272  traverse(_map_sink_source, fct_it->second, callback);
273  DBUG("expression: %s", expr.c_str());
274  return expr;
275 }
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 288 of file NamedFunctionCaller.cpp.

References _uninitialized.

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

289 {
290  return -_uninitialized - 1;
291 }

◆ 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 278 of file NamedFunctionCaller.cpp.

References _map_name_idx, OGS_FATAL, and SpecificFunctionCaller.

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

279 {
280  auto const fct_it = _map_name_idx.find(function_name);
281  if (fct_it == _map_name_idx.end()) {
282  OGS_FATAL("A function with the name `%s' has not been found.",
283  function_name.c_str());
284  }
285  return SpecificFunctionCaller(fct_it->second, *this);
286 }
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 141 of file NamedFunctionCaller.cpp.

References _deferred_plugs.

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

144 {
145  _deferred_plugs.push_back({sink_fct, sink_arg, source_fct});
146 }
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: