1 #ifndef STAN__GM__PARSER__TERM_GRAMMAR_DEF__HPP
2 #define STAN__GM__PARSER__TERM_GRAMMAR_DEF__HPP
16 #include <boost/spirit/include/qi.hpp>
18 #include <boost/spirit/include/phoenix_core.hpp>
19 #include <boost/spirit/include/phoenix_function.hpp>
20 #include <boost/spirit/include/phoenix_fusion.hpp>
21 #include <boost/spirit/include/phoenix_object.hpp>
22 #include <boost/spirit/include/phoenix_operator.hpp>
23 #include <boost/spirit/include/phoenix_stl.hpp>
25 #include <boost/lexical_cast.hpp>
26 #include <boost/fusion/include/adapt_struct.hpp>
27 #include <boost/fusion/include/std_pair.hpp>
28 #include <boost/config/warning_disable.hpp>
29 #include <boost/spirit/include/qi.hpp>
30 #include <boost/spirit/include/qi_numeric.hpp>
31 #include <boost/spirit/include/classic_position_iterator.hpp>
32 #include <boost/spirit/include/phoenix_core.hpp>
33 #include <boost/spirit/include/phoenix_function.hpp>
34 #include <boost/spirit/include/phoenix_fusion.hpp>
35 #include <boost/spirit/include/phoenix_object.hpp>
36 #include <boost/spirit/include/phoenix_operator.hpp>
37 #include <boost/spirit/include/phoenix_stl.hpp>
38 #include <boost/spirit/include/support_multi_pass.hpp>
39 #include <boost/tuple/tuple.hpp>
40 #include <boost/variant/apply_visitor.hpp>
41 #include <boost/variant/recursive_variant.hpp>
50 (std::vector<std::vector<stan::gm::expression> >,
54 (std::string, system_function_name_)
64 (std::vector<stan::gm::expression>, args_) );
82 template <
typename T1,
typename T2,
typename T3,
typename T4>
88 std::ostream& error_msgs)
const {
93 std::vector<expr_type> sys_arg_types;
102 error_msgs <<
"first argument to integrate_ode must be a function with signature"
103 <<
" (real, real[], real[], real[], int[]) : real[] ";
109 error_msgs <<
"second argument to integrate_ode must be type real[]"
110 <<
" for intial system state"
117 error_msgs <<
"third argument to integrate_ode must be type real or int"
118 <<
" for initial time"
125 error_msgs <<
"fourth argument to integrate_ode must be type real[]"
126 <<
" for requested solution times"
133 error_msgs <<
"fifth argument to integrate_ode must be type real[]"
141 error_msgs <<
"sixth argument to integrate_ode must be type real[]"
149 error_msgs <<
"seventh argument to integrate_ode must be type int[]"
150 <<
" for integer data;"
159 error_msgs <<
"third argument to integrate_ode (initial times)"
160 <<
" must be data only and not reference parameters";
164 error_msgs <<
"fourth argument to integrate_ode (solution times)"
165 <<
" must be data only and not reference parameters";
169 error_msgs <<
"fifth argument to integrate_ode (real data)"
170 <<
" must be data only and not reference parameters";
178 template <
typename T1,
typename T2>
182 std::ostream& error_msgs)
const {
183 std::vector<expr_type> arg_types;
184 for (
size_t i = 0; i < fun.
args_.size(); ++i)
185 arg_types.push_back(fun.
args_[i].expression_type());
196 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
203 std::ostream& error_msgs)
const {
204 std::vector<expr_type> arg_types;
205 for (
size_t i = 0; i < fun.
args_.size(); ++i)
206 arg_types.push_back(fun.
args_[i].expression_type());
215 error_msgs <<
"random number generators only allowed in"
216 <<
" generated quantities block or"
217 <<
" user-defined functions with names ending in _rng"
218 <<
"; found function=" << fun.
name_
221 error_msgs << std::endl;
234 error_msgs <<
"lp suffixed functions only allowed in"
235 <<
" transformed parameter, function argument, or model"
239 error_msgs << std::endl;
245 if (fun.
name_ ==
"abs"
246 && fun.
args_.size() > 0
247 && fun.
args_[0].expression_type().is_primitive_double()) {
248 error_msgs <<
"Warning: Function abs(real) is deprecated."
250 <<
" It will be removed in a future release."
252 <<
" Use fabs(real) instead."
253 << std::endl << std::endl;
256 if (fun.
name_ ==
"lkj_cov_log") {
257 error_msgs <<
"Warning: the lkj_cov_log() function"
258 <<
" is deprecated. It will be removed in Stan 3."
260 <<
"Code LKJ covariance in terms of an lkj_corr()"
261 <<
" distribution on a correlation matrix"
262 <<
" and independent lognormals on the scales."
263 << std::endl << std::endl;
273 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
280 std::ostream& error_msgs)
const {
284 error_msgs <<
"arguments to ^ must be primitive (real or int)"
285 <<
"; cannot exponentiate "
291 error_msgs << std::endl;
295 std::vector<expression> args;
296 args.push_back(expr1);
297 args.push_back(expr2);
307 template <
typename T1,
typename T2,
typename T3>
312 std::ostream& error_msgs)
const {
319 std::vector<expression> args;
320 args.push_back(expr1);
321 args.push_back(expr2);
323 fun f(
"multiply",args);
333 template <
typename T1,
typename T2,
typename T3>
338 std::ostream& error_msgs)
const {
346 std::vector<expression> args;
347 args.push_back(expr1);
348 args.push_back(expr2);
353 error_msgs <<
"Warning: integer division implicitly rounds to integer."
354 <<
" Found int division: ";
358 error_msgs << std::endl
359 <<
" Positive values rounded down, negative values rounded up or down"
360 <<
" in platform-dependent way."
363 fun f(
"divide",args);
371 fun f(
"mdivide_right",args);
376 fun f(
"divide",args);
385 template <
typename T1,
typename T2,
typename T3,
typename T4>
391 std::ostream& error_msgs)
const {
394 error_msgs <<
"both operands of % must be int"
395 <<
"; cannot modulo "
399 error_msgs << std::endl;
403 std::vector<expression> args;
404 args.push_back(expr1);
405 args.push_back(expr2);
407 fun f(
"modulus",args);
415 template <
typename T1,
typename T2,
typename T3>
420 std::ostream& error_msgs)
const {
421 std::vector<expression> args;
422 args.push_back(expr1);
423 args.push_back(expr2);
428 fun f(
"mdivide_left",args);
433 fun f(
"divide_left",args);
442 template <
typename T1,
typename T2,
typename T3>
447 std::ostream& error_msgs)
const {
454 std::vector<expression> args;
455 args.push_back(expr1);
456 args.push_back(expr2);
458 fun f(
"elt_multiply",args);
466 template <
typename T1,
typename T2,
typename T3>
471 std::ostream& error_msgs)
const {
478 std::vector<expression> args;
479 args.push_back(expr1);
480 args.push_back(expr2);
482 fun f(
"elt_divide",args);
495 template <
typename T1,
typename T2,
typename T3,
typename T4>
501 std::ostream& error_msgs)
const {
506 std::vector<expression> args;
507 args.push_back(expr);
517 template <
typename T1,
typename T2,
typename T3>
522 std::ostream& error_msgs)
const {
524 error_msgs <<
"logical negation operator ! only applies to int or real types; ";
527 std::vector<expression> args;
528 args.push_back(expr);
530 fun f(
"logical_negation",args);
538 template <
typename T1,
typename T2>
542 std::ostream& error_msgs)
const {
547 std::vector<expression> args;
548 args.push_back(expr);
550 fun f(
"transpose",args);
558 template <
typename T1,
typename T2,
typename T3,
typename T4>
561 std::vector<std::vector<stan::gm::expression> >& dimss,
563 std::ostream& error_msgs)
const {
567 error_msgs <<
"indexes inappropriate for expression." << std::endl;
577 template <
typename T1,
typename T2,
typename T3,
typename T4>
581 std::ostream& error_msgs,
583 std::string name = var_expr.
name_;
586 error_msgs <<
"variable \"" << name <<
'"' <<
" does not exist."
590 if (name == std::string(
"lp__")) {
591 error_msgs << std::endl
594 <<
" Direct use of variable lp__ is deprecated and will be removed in a future release."
596 <<
" Please use increment_log_prob(u) in place of of lp__ <- lp__ + u."
607 template <
typename T1,
typename T2>
611 std::stringstream& error_msgs)
const {
613 error_msgs <<
"expression denoting integer required; found type="
624 template <
typename Iterator>
626 std::stringstream& error_msgs,
630 error_msgs_(error_msgs),
633 using boost::spirit::qi::_1;
634 using boost::spirit::qi::char_;
635 using boost::spirit::qi::double_;
636 using boost::spirit::qi::eps;
637 using boost::spirit::qi::int_;
638 using boost::spirit::qi::lexeme;
639 using boost::spirit::qi::lit;
640 using boost::spirit::qi::_pass;
641 using boost::spirit::qi::_val;
642 using boost::spirit::qi::labels::_r1;
707 %= lit(
"integrate_ode")
756 fun_r.name(
"function and argument expressions");
764 %= lexeme[char_(
"a-zA-Z")
765 >> *char_(
"a-zA-Z0-9_.")];
768 args_r.name(
"function argument expressions");
770 %= (lit(
'(') >> lit(
')'))
777 dims_r.name(
"array dimensions");
boost::phoenix::function< validate_integrate_ode > validate_integrate_ode_f
void generate_expression(const expression &e, std::ostream &o)
boost::spirit::qi::rule< Iterator, variable(), whitespace_grammar< Iterator > > variable_r
boost::spirit::qi::rule< Iterator, expression(var_origin), whitespace_grammar< Iterator > > term_r
variable operator()(variable &var_expr, variable_map &vm, std::ostream &error_msgs, bool &pass) const
const int parameter_origin
static function_signatures & instance()
fun operator()(fun &fun, std::ostream &error_msgs) const
void operator()(expression &expression, std::vector< std::vector< stan::gm::expression > > &dimss, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< multiplication_expr > multiplication_f
bool is_primitive_int() const
void operator()(expression &expr1, const expression &expr2, const var_origin &var_origin, bool &pass, std::ostream &error_msgs) const
boost::spirit::qi::rule< Iterator, int_literal(), whitespace_grammar< Iterator > > int_literal_r
bool is_primitive_double() const
stan::gm::expression_grammar< Iterator > & expression_g
void print_var_origin(std::ostream &o, const var_origin &vo)
BOOST_FUSION_ADAPT_STRUCT(stan::gm::index_op,(stan::gm::expression, expr_)(std::vector< std::vector< stan::gm::expression > >, dimss_))
boost::spirit::qi::rule< Iterator, expression(var_origin), whitespace_grammar< Iterator > > exponentiated_factor_r
boost::phoenix::function< negate_expr > negate_expr_f
bool operator()(const expression &expr, std::stringstream &error_msgs) const
boost::spirit::qi::rule< Iterator, double_literal(), whitespace_grammar< Iterator > > double_literal_r
void operator()(expression &fun_result, fun &fun, const var_origin &var_origin, bool &pass, std::ostream &error_msgs) const
void operator()(const integrate_ode &ode_fun, const variable_map &var_map, bool &pass, std::ostream &error_msgs) const
const int function_argument_origin_rng
bool has_rng_suffix(const std::string &s)
std::vector< expression > args_
boost::spirit::qi::rule< Iterator, integrate_ode(var_origin), whitespace_grammar< Iterator > > integrate_ode_r
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
boost::phoenix::function< validate_int_expr3 > validate_int_expr3_f
size_t get_num_dims(const std::string &name) const
base_expr_type type() const
term_grammar(variable_map &var_map, std::stringstream &error_msgs, expression_grammar< Iterator > &eg)
boost::spirit::qi::rule< Iterator, fun(var_origin), whitespace_grammar< Iterator > > fun_r
boost::phoenix::function< logical_negate_expr > logical_negate_expr_f
boost::spirit::qi::rule< Iterator, std::vector< expression >var_origin), whitespace_grammar< Iterator > > args_r
boost::phoenix::function< set_fun_type_named > set_fun_type_named_f
boost::phoenix::function< modulus_expr > modulus_f
void operator()(expression &expr1, const expression &expr2, bool &pass, std::ostream &error_msgs) const
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
boost::phoenix::function< exponentiation_expr > exponentiation_f
bool has_var(const expression &e, const variable_map &var_map)
std::stringstream & error_msgs_
boost::phoenix::function< add_expression_dimss > add_expression_dimss_f
boost::phoenix::function< elt_division_expr > elt_division_f
boost::phoenix::function< division_expr > division_f
void operator()(expression &expr_result, const expression &expr, bool &pass, std::ostream &error_msgs) const
bool has_lp_suffix(const std::string &s)
boost::phoenix::function< elt_multiplication_expr > elt_multiplication_f
boost::spirit::qi::rule< Iterator, std::string(), whitespace_grammar< Iterator > > identifier_r
std::string system_function_name_
boost::phoenix::function< set_fun_type > set_fun_type_f
base_expr_type get_base_type(const std::string &name) const
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< bool >, expression(var_origin), whitespace_grammar< Iterator > > factor_r
double e()
Return the base of the natural logarithm.
bool is_ill_formed() const
const int function_argument_origin_lp
boost::spirit::qi::rule< Iterator, expression(var_origin), whitespace_grammar< Iterator > > negated_factor_r
const int transformed_parameter_origin
boost::spirit::qi::rule< Iterator, expression(var_origin), whitespace_grammar< Iterator > > indexed_factor_r
boost::phoenix::function< transpose_expr > transpose_f
boost::phoenix::function< set_var_type > set_var_type_f
expr_type get_result_type(const std::string &name, const std::vector< expr_type > &args, std::ostream &error_msgs)
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
void operator()(expression &expr_result, const expression &expr, std::ostream &error_msgs) const
expression operator()(const expression &expr, std::ostream &error_msgs) const
bool exists(const std::string &name) const
boost::phoenix::function< left_division_expr > left_division_f
expr_type expression_type() const
void set_type(const base_expr_type &base_type, size_t num_dims)
bool is_primitive() const
boost::spirit::qi::rule< Iterator, std::vector< expression >var_origin), whitespace_grammar< Iterator > > dims_r
std::pair< expr_type, std::vector< expr_type > > function_signature_t