1 #ifndef STAN_LANG_AST_SIGS_FUNCTION_SIGNATURES_DEF_HPP 2 #define STAN_LANG_AST_SIGS_FUNCTION_SIGNATURES_DEF_HPP 16 if (sigs_ == 0)
return;
29 const std::pair<std::string, function_signature_t>& name_sig) {
30 user_defined_set_.insert(name_sig);
34 const std::pair<std::string, function_signature_t>& name_sig) {
35 return user_defined_set_.find(name_sig) != user_defined_set_.end();
40 if (sigs_map_.find(name) == sigs_map_.end())
42 const std::vector<function_signature_t> sigs = sigs_map_[name];
43 for (
size_t i = 0; i < sigs.size(); ++i)
44 if (sig.second == sigs[i].second)
54 map<string, vector<function_signature_t> >::const_iterator it
55 = sigs_map_.find(fun);
56 if (it == sigs_map_.end())
58 const vector<function_signature_t> sigs = it->second;
59 for (
size_t i = 0; i < sigs.size(); ++i) {
60 if (sigs[i].second.size() == 0
61 || sigs[i].second[0].base_type_ !=
INT_T)
69 const std::vector<expr_type>& arg_types) {
75 std::vector<expr_type> arg_types;
76 add(name, result_type, arg_types);
82 std::vector<expr_type> arg_types;
83 arg_types.push_back(arg_type);
84 add(name, result_type, arg_types);
91 std::vector<expr_type> arg_types;
92 arg_types.push_back(arg_type1);
93 arg_types.push_back(arg_type2);
94 add(name, result_type, arg_types);
102 std::vector<expr_type> arg_types;
103 arg_types.push_back(arg_type1);
104 arg_types.push_back(arg_type2);
105 arg_types.push_back(arg_type3);
106 add(name, result_type, arg_types);
115 std::vector<expr_type> arg_types;
116 arg_types.push_back(arg_type1);
117 arg_types.push_back(arg_type2);
118 arg_types.push_back(arg_type3);
119 arg_types.push_back(arg_type4);
120 add(name, result_type, arg_types);
130 std::vector<expr_type> arg_types;
131 arg_types.push_back(arg_type1);
132 arg_types.push_back(arg_type2);
133 arg_types.push_back(arg_type3);
134 arg_types.push_back(arg_type4);
135 arg_types.push_back(arg_type5);
136 add(name, result_type, arg_types);
147 std::vector<expr_type> arg_types;
148 arg_types.push_back(arg_type1);
149 arg_types.push_back(arg_type2);
150 arg_types.push_back(arg_type3);
151 arg_types.push_back(arg_type4);
152 arg_types.push_back(arg_type5);
153 arg_types.push_back(arg_type6);
154 add(name, result_type, arg_types);
166 std::vector<expr_type> arg_types;
167 arg_types.push_back(arg_type1);
168 arg_types.push_back(arg_type2);
169 arg_types.push_back(arg_type3);
170 arg_types.push_back(arg_type4);
171 arg_types.push_back(arg_type5);
172 arg_types.push_back(arg_type6);
173 arg_types.push_back(arg_type7);
174 add(name, result_type, arg_types);
187 for (
size_t i = 0; i < 8; ++i) {
209 const std::vector<expr_type>& call_args,
210 const std::vector<expr_type>& sig_args) {
211 if (call_args.size() != sig_args.size()) {
215 for (
size_t i = 0; i < call_args.size(); ++i) {
216 if (call_args[i] == sig_args[i]) {
218 }
else if (call_args[i].is_primitive_int()
219 && sig_args[i].is_primitive_double()) {
229 const std::vector<expr_type>& args,
232 std::vector<function_signature_t> signatures = sigs_map_[name];
233 size_t min_promotions = std::numeric_limits<size_t>::max();
234 size_t num_matches = 0;
235 for (
size_t i = 0; i < signatures.size(); ++i) {
236 signature = signatures[i];
238 if (promotions < 0)
continue;
239 size_t promotions_ui =
static_cast<size_t>(promotions);
240 if (promotions_ui < min_promotions) {
241 min_promotions = promotions_ui;
243 }
else if (promotions_ui == min_promotions) {
254 || name ==
"subtract" 255 || name ==
"multiply" 258 || name ==
"mdivide_left" 259 || name ==
"mdivide_right" 260 || name ==
"elt_multiply" 261 || name ==
"elt_divide";
265 return name ==
"minus" 266 || name ==
"logical_negation";
270 return name ==
"transpose";
284 if (name ==
"add")
return "+";
285 if (name ==
"subtract")
return "-";
286 if (name ==
"multiply")
return "*";
287 if (name ==
"divide")
return "/";
288 if (name ==
"modulus")
return "%";
289 if (name ==
"mdivide_left")
return "\\";
290 if (name ==
"mdivide_right")
return "/";
291 if (name ==
"elt_multiply")
return ".*";
292 if (name ==
"elt_divide")
return "./";
295 if (name ==
"minus")
return "-";
296 if (name ==
"logical_negation")
return "!";
299 if (name ==
"transpose")
return "'";
306 const std::vector<expr_type>& arg_types,
307 bool sampling_error_style,
308 std::ostream& msgs) {
309 static size_t OP_SIZE = std::string(
"operator").size();
311 if (name.size() > OP_SIZE && name.substr(0, OP_SIZE) ==
"operator") {
312 std::string operator_name = name.substr(OP_SIZE);
313 if (arg_types.size() == 2) {
314 msgs << arg_types[0] <<
" " << operator_name <<
" " << arg_types[1]
317 }
else if (arg_types.size() == 1) {
318 if (operator_name ==
"'")
319 msgs << arg_types[0] << operator_name << std::endl;
321 msgs << operator_name << arg_types[0] << std::endl;
326 msgs <<
"Operators must have 1 or 2 arguments." << std::endl;
329 if (sampling_error_style && arg_types.size() > 0)
330 msgs << arg_types[0] <<
" ~ ";
332 size_t start = sampling_error_style ? 1 : 0;
333 for (
size_t j = start; j < arg_types.size(); ++j) {
334 if (j > start) msgs <<
", ";
335 msgs << arg_types[j];
337 msgs <<
")" << std::endl;
341 const std::vector<expr_type>& args,
342 std::ostream& error_msgs,
343 bool sampling_error_style) {
344 std::vector<function_signature_t> signatures = sigs_map_[name];
345 size_t match_index = 0;
346 size_t min_promotions = std::numeric_limits<size_t>::max();
347 size_t num_matches = 0;
349 std::string display_name;
352 }
else if (sampling_error_style &&
ends_with(
"_log", name)) {
353 display_name = name.substr(0, name.size() - 4);
354 }
else if (sampling_error_style
356 display_name = name.substr(0, name.size() - 5);
361 for (
size_t i = 0; i < signatures.size(); ++i) {
363 if (promotions < 0)
continue;
364 size_t promotions_ui =
static_cast<size_t>(promotions);
365 if (promotions_ui < min_promotions) {
366 min_promotions = promotions_ui;
369 }
else if (promotions_ui == min_promotions) {
374 if (num_matches == 1)
375 return signatures[match_index].first;
379 if (num_matches == 0) {
380 error_msgs <<
"No matches for: " 381 << std::endl << std::endl;
383 error_msgs <<
"Ambiguous: " 384 << num_matches <<
" matches with " 385 << min_promotions <<
" integer promotions for: " 390 if (signatures.size() == 0) {
391 error_msgs << std::endl
392 << (sampling_error_style ?
"Distribution " :
"Function ")
393 << display_name <<
" not found.";
394 if (sampling_error_style)
395 error_msgs <<
" Require function with _lpdf or _lpmf or _log suffix";
396 error_msgs << std::endl;
398 error_msgs << std::endl
399 <<
"Available argument signatures for " 400 << display_name <<
":" << std::endl << std::endl;
402 for (
size_t i = 0; i < signatures.size(); ++i) {
404 sampling_error_style, error_msgs);
406 error_msgs << std::endl;
411 function_signatures::function_signatures() {
412 #include <stan/lang/function_signatures.h> 420 for (
set<pair<string, function_signature_t> >::const_iterator
421 it = user_defined_set_.begin();
422 it != user_defined_set_.end();
424 if (it->first == key)
436 for (map<
string, vector<function_signature_t> >::const_iterator
437 it = sigs_map_.begin();
438 it != sigs_map_.end();
440 result.insert(it->first);
445 return sigs_map_.find(key) != sigs_map_.end();
expr_type get_result_type(const std::string &name, const std::vector< expr_type > &args, std::ostream &error_msgs, bool sampling_error_style=false)
Return the result expression type resulting from applying a function of the speicified name and argum...
void add(const std::string &name, const expr_type &result_type, const std::vector< expr_type > &arg_types)
Add a built-in function with the specified name, result, type and arguments.
const int ROW_VECTOR_T
Row vector type; scalar type is real.
bool is_operator(const std::string &name)
Probability, optimization and sampling library.
static function_signatures & instance()
Return the instance of this singleton.
void add(const std::string &name, const expr_type &result_type, const expr_type &arg_type1)
Add a built-in function with the specifed name, result type, and argument types.
bool is_unary_postfix_operator(const std::string &name)
This class is a singleton used to store the available functions in the Stan object language and their...
const int DOUBLE_T
Real scalar type.
int num_promotions(const std::vector< expr_type > &call_args, const std::vector< expr_type > &sig_args)
Return the number of integer to real promotions required to convert the specified call arguments to t...
Structure for function application.
int get_signature_matches(const std::string &name, const std::vector< expr_type > &args, function_signature_t &signature)
Return the number of declared function signatures match for the specified name, argument types...
Structure of the type of an expression, which consists of a base type and a number of dimensions...
void add_binary(const ::std::string &name)
Add a built-in function with the specified name, a real return type, and two real arguments...
bool has_user_defined_key(const std::string &name) const
Return true if the specified name is the name of a user-defined function.
bool is_unary_operator(const std::string &name)
void add_unary(const ::std::string &name)
Add a built-in function with the specified name, a real return type, and a single real argument...
static void reset_sigs()
Reset the signature singleton to contain no instances.
bool discrete_first_arg(const std::string &name) const
Return true if all of the function signatures for functions with the specified name have integer base...
void add_nullary(const ::std::string &name)
Add a built-in function with the specified name, a real return type, and no arguments.
bool ends_with(const std::string &suffix, const std::string &s)
Returns true if the specified suffix appears at the end of the specified string.
bool is_defined(const std::string &name, const function_signature_t &sig)
Return true if the specified function name is defined for the specified signature.
void add_quaternary(const ::std::string &name)
Add a built-in function with the specified name, a real return type, and four real arguments...
bool is_user_defined(const std::pair< std::string, function_signature_t > &name_sig)
Return true if the specified name and signature have been added as user-defined functions.
void print_signature(const std::string &name, const std::vector< expr_type > &arg_types, bool sampling_error_style, std::ostream &msgs)
std::pair< expr_type, std::vector< expr_type > > function_signature_t
The type of a function signature, mapping a vector of argument expression types to a result expressio...
bool is_binary_operator(const std::string &name)
const int INT_T
Integer type.
void add_ternary(const ::std::string &name)
Add a built-in function with the specified name, a real return type, and three real arguments...
std::set< std::string > key_set() const
Return the set of function names defined.
const int VECTOR_T
Column vector type; scalar type is real.
bool has_key(const std::string &key) const
Return true if specified key is the name of a declared function.
void set_user_defined(const std::pair< std::string, function_signature_t > &name_sig)
Set the specified name and signature to be a user-defined function.
void add_unary_vectorized(const ::std::string &name)
Add built-in functions for all the vectorized form of a unary function with the speicifed name and a ...
std::string fun_name_to_operator(const std::string &name)
const int MATRIX_T
Matrix type; scalar type is real.