Stan  2.13.1
probability, sampling & optimization
semantic_actions_def.cpp
Go to the documentation of this file.
1 #ifndef STAN_LANG_GRAMMARS_SEMANTIC_ACTIONS_DEF_CPP
2 #define STAN_LANG_GRAMMARS_SEMANTIC_ACTIONS_DEF_CPP
3 
4 #include <stan/lang/ast.hpp>
7 #include <boost/format.hpp>
8 #include <boost/spirit/include/qi.hpp>
9 #include <boost/variant/apply_visitor.hpp>
10 #include <boost/variant/recursive_variant.hpp>
11 #include <cstddef>
12 #include <limits>
13 #include <climits>
14 #include <iomanip>
15 #include <iostream>
16 #include <map>
17 #include <set>
18 #include <stdexcept>
19 #include <string>
20 #include <utility>
21 #include <vector>
22 
23 namespace stan {
24 
25  namespace lang {
26 
33  void qualify(fun& f) {
34  f.original_name_ = f.name_;
35  f.name_ = "stan::math::" + f.name_;
36  }
37 
45  void qualify_builtins(fun& f) {
46  if (f.args_.size() > 0) return;
47  if (f.name_ == "e" || f.name_ == "pi" || f.name_ == "log2"
48  || f.name_ == "log10" || f.name_ == "sqrt2"
49  || f.name_ == "not_a_number" || f.name_ == "positive_infinity"
50  || f.name_ == "negative_infinity" || f.name_ == "machine_precision")
51  qualify(f);
52  }
53 
64  if (f.args_.size() == 1
65  && (f.name_ == "acosh"|| f.name_ == "asinh" || f.name_ == "atanh"
66  || f.name_ == "exp2" || f.name_ == "expm1" || f.name_ == "log1p"
67  || f.name_ == "log2" || f.name_ == "cbrt" || f.name_ == "erf"
68  || f.name_ == "erfc" || f.name_ == "tgamma" || f.name_ == "lgamma"
69  || f.name_ == "round" || f.name_ == "trunc"))
70  qualify(f);
71  else if (f.args_.size() == 2
72  && (f.name_ == "fdim" || f.name_ == "fmax" || f.name_ == "fmin"
73  || f.name_ == "hypot"))
74  qualify(f);
75  else if (f.args_.size() == 3 && f.name_ == "fma")
76  qualify(f);
77  }
78 
79  bool has_prob_suffix(const std::string& s) {
80  return ends_with("_lpdf", s) || ends_with("_lpmf", s)
81  || ends_with("_lcdf", s) || ends_with("_lccdf", s);
82  }
83 
84  void replace_suffix(const std::string& old_suffix,
85  const std::string& new_suffix, fun& f) {
86  if (!ends_with(old_suffix, f.name_)) return;
87  f.original_name_ = f.name_;
88  f.name_ = f.name_.substr(0, f.name_.size() - old_suffix.size())
89  + new_suffix;
90  }
91 
92  bool deprecate_fun(const std::string& old_name, const std::string& new_name,
93  fun& f, std::ostream& msgs) {
94  if (f.name_ != old_name) return false;
95  f.original_name_ = f.name_;
96  f.name_ = new_name;
97  msgs << "Warning: Function name '" << old_name << "' is deprecated"
98  << " and will be removed in a later release; please replace"
99  << " with '" << new_name << "'" << std::endl;
100  return true;
101  }
102 
103  bool deprecate_suffix(const std::string& deprecated_suffix,
104  const std::string& replacement, fun& f,
105  std::ostream& msgs) {
106  if (!ends_with(deprecated_suffix, f.name_)) return false;
107  msgs << "Warning: Deprecated function '" << f.name_ << "';"
108  << " please replace suffix '" << deprecated_suffix
109  << "' with " << replacement << std::endl;
110  return true;
111  }
112 
114  bool& pass,
115  std::stringstream& error_msgs)
116  const {
118  && !expr.expression_type().is_primitive_int()) {
119  error_msgs << "expression denoting real required; found type="
120  << expr.expression_type() << std::endl;
121  pass = false;
122  return;
123  }
124  pass = true;
125  }
126  boost::phoenix::function<validate_double_expr> validate_double_expr_f;
127 
128  void set_fun_type(fun& fun, std::ostream& error_msgs) {
129  std::vector<expr_type> arg_types;
130  for (size_t i = 0; i < fun.args_.size(); ++i)
131  arg_types.push_back(fun.args_[i].expression_type());
133  .get_result_type(fun.name_, arg_types, error_msgs);
134  }
135 
136  int num_dimss(std::vector<std::vector<stan::lang::expression> >& dimss) {
137  int sum = 0;
138  for (size_t i = 0; i < dimss.size(); ++i)
139  sum += dimss[i].size();
140  return sum;
141  }
142 
143  template <typename L, typename R>
144  void assign_lhs::operator()(L& lhs, const R& rhs) const {
145  lhs = rhs;
146  }
147  boost::phoenix::function<assign_lhs> assign_lhs_f;
148 
149  template void assign_lhs::operator()(expression&, const expression&) const;
150  template void assign_lhs::operator()(expression&, const double_literal&)
151  const;
152  template void assign_lhs::operator()(expression&, const int_literal&) const;
153  template void assign_lhs::operator()(expression&, const integrate_ode&)
154  const;
155  template void assign_lhs::operator()(expression&,
156  const integrate_ode_control&)
157  const;
158  template void assign_lhs::operator()(int&, const int&) const;
159  template void assign_lhs::operator()(size_t&, const size_t&) const;
160  template void assign_lhs::operator()(statement&, const statement&) const;
161  template void assign_lhs::operator()(std::vector<var_decl>&,
162  const std::vector<var_decl>&) const;
163  template void assign_lhs::operator()(std::vector<idx>&,
164  const std::vector<idx>&) const;
165  template void assign_lhs::operator()(
166  std::vector<std::vector<expression> >&,
167  const std::vector<std::vector<expression> >&) const;
168  template void assign_lhs::operator()(fun&, const fun&) const;
169  template void assign_lhs::operator()(variable&, const variable&) const;
170 
171  void validate_expr_type3::operator()(const expression& expr, bool& pass,
172  std::ostream& error_msgs) const {
173  pass = !expr.expression_type().is_ill_formed();
174  if (!pass)
175  error_msgs << "expression is ill formed" << std::endl;
176  }
177  boost::phoenix::function<validate_expr_type3> validate_expr_type3_f;
178 
179  void is_prob_fun::operator()(const std::string& s,
180  bool& pass) const {
181  pass = has_prob_suffix(s);
182  }
183  boost::phoenix::function<is_prob_fun> is_prob_fun_f;
184 
186  std::ostream& error_msgs) const {
187  if (expr1.expression_type().is_primitive()
188  && expr2.expression_type().is_primitive()) {
189  expr1 += expr2;
190  return;
191  }
192  std::vector<expression> args;
193  args.push_back(expr1);
194  args.push_back(expr2);
195  fun f("add", args);
196  set_fun_type(f, error_msgs);
197  expr1 = expression(f);
198  }
199  boost::phoenix::function<addition_expr3> addition3_f;
200 
202  const expression& expr2,
203  std::ostream& error_msgs) const {
204  if (expr1.expression_type().is_primitive()
205  && expr2.expression_type().is_primitive()) {
206  expr1 -= expr2;
207  return;
208  }
209  std::vector<expression> args;
210  args.push_back(expr1);
211  args.push_back(expr2);
212  fun f("subtract", args);
213  set_fun_type(f, error_msgs);
214  expr1 = expression(f);
215  }
216  boost::phoenix::function<subtraction_expr3> subtraction3_f;
217 
218  void increment_size_t::operator()(size_t& lhs) const {
219  ++lhs;
220  }
221  boost::phoenix::function<increment_size_t> increment_size_t_f;
222 
223 
225  const var_origin& var_origin,
226  bool& pass,
227  const variable_map& var_map,
228  std::ostream& error_msgs) const {
229  expr_type cond_type = conditional_op.cond_.expression_type();
230  if (!cond_type.is_primitive_int()) {
231  error_msgs << "condition in ternary expression must be"
232  << " primitive int or real;"
233  << " found type=" << cond_type
234  << std::endl;
235  pass = false;
236  return;
237  }
238 
239  expr_type true_val_type = conditional_op.true_val_.expression_type();
240  base_expr_type true_val_base_type = true_val_type.base_type_;
241  expr_type false_val_type = conditional_op.false_val_.expression_type();
242  base_expr_type false_val_base_type = false_val_type.base_type_;
243  bool types_compatible
244  = (true_val_type == false_val_type)
245  || (true_val_type.is_primitive() && false_val_type.is_primitive()
246  && (true_val_base_type == false_val_base_type
247  || (true_val_base_type == DOUBLE_T
248  && false_val_base_type == INT_T)
249  || (true_val_base_type == INT_T
250  && false_val_base_type == DOUBLE_T)));
251 
252  if (!types_compatible) {
253  error_msgs << "base type mismatch in ternary expression,"
254  << " expression when true is: ";
255  write_base_expr_type(error_msgs, true_val_base_type);
256  error_msgs << "; expression when false is: ";
257  write_base_expr_type(error_msgs, false_val_base_type);
258  error_msgs << std::endl;
259  pass = false;
260  return;
261  }
262 
263  if (true_val_type.is_primitive())
264  conditional_op.type_
265  = (true_val_base_type == false_val_base_type)
266  ? true_val_base_type
267  : DOUBLE_T;
268  else
269  conditional_op.type_ = true_val_type;
270 
271  conditional_op.has_var_ = has_var(conditional_op, var_map);
272  conditional_op.var_origin_ = var_origin;
273  pass = true;
274  }
275  boost::phoenix::function<validate_conditional_op>
277 
279  const std::string& op,
280  const std::string& fun_name,
281  std::ostream& error_msgs) const {
282  if (!expr1.expression_type().is_primitive()
283  || !expr2.expression_type().is_primitive()) {
284  error_msgs << "binary infix operator " << op
285  << " with functional interpretation " << fun_name
286  << " requires arguments or primitive type (int or real)"
287  << ", found left type=" << expr1.expression_type()
288  << ", right arg type=" << expr2.expression_type()
289  << "; "
290  << std::endl;
291  }
292  std::vector<expression> args;
293  args.push_back(expr1);
294  args.push_back(expr2);
295  fun f(fun_name, args);
296  set_fun_type(f, error_msgs);
297  expr1 = expression(f);
298  }
299  boost::phoenix::function<binary_op_expr> binary_op_f;
300 
302  bool& pass,
303  std::ostream& error_msgs) const {
304  pass = !arg_type.is_void();
305  if (!pass)
306  error_msgs << "Functions cannot contain void argument types; "
307  << "found void argument."
308  << std::endl;
309  }
310  boost::phoenix::function<validate_non_void_arg_function>
312 
313  void set_void_function:: operator()(const expr_type& return_type,
314  var_origin& origin, bool& pass,
315  std::ostream& error_msgs) const {
316  if (return_type.is_void() && return_type.num_dims() > 0) {
317  error_msgs << "Void return type may not have dimensions declared."
318  << std::endl;
319  pass = false;
320  return;
321  }
322  origin = return_type.is_void()
325  pass = true;
326  }
327  boost::phoenix::function<set_void_function> set_void_function_f;
328 
329  void set_allows_sampling_origin::operator()(const std::string& identifier,
330  bool& allow_sampling,
331  int& origin) const {
332  bool is_void_function_origin
333  = (origin == void_function_argument_origin);
334  if (ends_with("_lp", identifier)) {
335  allow_sampling = true;
336  origin = is_void_function_origin
339  } else if (ends_with("_rng", identifier)) {
340  allow_sampling = false;
341  origin = is_void_function_origin
344  } else {
345  allow_sampling = false;
346  origin = is_void_function_origin
349  }
350  }
351  boost::phoenix::function<set_allows_sampling_origin>
353 
355  std::set<std::pair<std::string,
356  function_signature_t> >& declared,
357  std::set<std::pair<std::string,
358  function_signature_t> >& defined,
359  std::ostream& error_msgs,
360  bool allow_undefined) const {
361  using std::set;
362  using std::string;
363  using std::pair;
364  typedef set<pair<string, function_signature_t> >::iterator iterator_t;
365  if (!allow_undefined) {
366  for (iterator_t it = declared.begin(); it != declared.end(); ++it) {
367  if (defined.find(*it) == defined.end()) {
368  error_msgs <<"Function declared, but not defined."
369  << " Function name=" << (*it).first
370  << std::endl;
371  pass = false;
372  return;
373  }
374  }
375  }
376  pass = true;
377  }
378  boost::phoenix::function<validate_declarations> validate_declarations_f;
379 
380 
381  bool fun_exists(const std::set<std::pair<std::string,
382  function_signature_t> >& existing,
383  const std::pair<std::string,
384  function_signature_t>& name_sig,
385  bool name_only = true) {
386  for (std::set<std::pair<std::string,
387  function_signature_t> >::const_iterator it
388  = existing.begin();
389  it != existing.end();
390  ++it)
391  if (name_sig.first == (*it).first
392  && (name_only
393  || name_sig.second.second == (*it).second.second))
394  return true; // name and arg sequences match
395  return false;
396  }
397 
398  void validate_prob_fun::operator()(std::string& fname, bool& pass,
399  std::ostream& error_msgs) const {
400  if (has_prob_fun_suffix(fname)) {
401  std::string dist_name = strip_prob_fun_suffix(fname);
402  if (!fun_name_exists(fname) // catch redefines later avoid fwd
403  && (fun_name_exists(dist_name + "_lpdf")
404  || fun_name_exists(dist_name + "_lpmf")
405  || fun_name_exists(dist_name + "_log"))) {
406  error_msgs << "Parse Error. Probability function already defined"
407  << " for " << dist_name << std::endl;
408  pass = false;
409  return;
410  }
411  }
412  if (has_cdf_suffix(fname)) {
413  std::string dist_name = strip_cdf_suffix(fname);
414  if (fun_name_exists(dist_name + "_cdf_log")
415  || fun_name_exists(dist_name + "_lcdf")) {
416  error_msgs << " Parse Error. CDF already defined for "
417  << dist_name << std::endl;
418  pass = false;
419  return;
420  }
421  }
422  if (has_ccdf_suffix(fname)) {
423  std::string dist_name = strip_ccdf_suffix(fname);
424  if (fun_name_exists(dist_name + "_ccdf_log")
425  || fun_name_exists(dist_name + "_lccdf")) {
426  error_msgs << " Parse Error. CCDF already defined for "
427  << dist_name << std::endl;
428  pass = false;
429  return;
430  }
431  }
432  }
433  boost::phoenix::function<validate_prob_fun> validate_prob_fun_f;
434 
436  bool& pass,
437  std::set<std::pair<std::string, function_signature_t> >&
438  functions_declared,
439  std::set<std::pair<std::string, function_signature_t> >&
440  functions_defined,
441  std::ostream& error_msgs) const {
442  // build up representations
443  expr_type result_type(decl.return_type_.base_type_,
444  decl.return_type_.num_dims_);
445  std::vector<expr_type> arg_types;
446  for (size_t i = 0; i < decl.arg_decls_.size(); ++i)
447  arg_types.push_back(expr_type(decl.arg_decls_[i].arg_type_.base_type_,
448  decl.arg_decls_[i].arg_type_.num_dims_));
449 
450  function_signature_t sig(result_type, arg_types);
451  std::pair<std::string, function_signature_t> name_sig(decl.name_, sig);
452  // check that not already declared if just declaration
453  if (decl.body_.is_no_op_statement()
454  && fun_exists(functions_declared, name_sig)) {
455  error_msgs << "Parse Error. Function already declared, name="
456  << decl.name_;
457  pass = false;
458  return;
459  }
460 
461  // check not already user defined
462  if (fun_exists(functions_defined, name_sig)) {
463  error_msgs << "Parse Error. Function already defined, name="
464  << decl.name_;
465  pass = false;
466  return;
467  }
468 
469  // check not already system defined
470  if (!fun_exists(functions_declared, name_sig)
472  error_msgs << "Parse Error. Function system defined, name="
473  << decl.name_;
474  pass = false;
475  return;
476  }
477 
478 
479  if (ends_with("_lpdf", decl.name_) && arg_types[0].base_type_ == INT_T) {
480  error_msgs << "Parse Error. Probability density functions require"
481  << " real variates (first argument)."
482  << " Found type = " << arg_types[0] << std::endl;
483  pass = false;
484  return;
485  }
486  if (ends_with("_lpmf", decl.name_) && arg_types[0].base_type_ != INT_T) {
487  error_msgs << "Parse Error. Probability mass functions require"
488  << " integer variates (first argument)."
489  << " Found type = " << arg_types[0] << std::endl;
490  pass = false;
491  return;
492  }
493 
494  // add declaration in local sets and in parser function sigs
495  if (functions_declared.find(name_sig) == functions_declared.end()) {
496  functions_declared.insert(name_sig);
498  .add(decl.name_, result_type, arg_types);
500  }
501 
502  // add as definition if there's a body
503  if (!decl.body_.is_no_op_statement())
504  functions_defined.insert(name_sig);
505  pass = true;
506  }
507  boost::phoenix::function<add_function_signature> add_function_signature_f;
508 
509 
511  bool& pass,
512  std::ostream& error_msgs)
513  const {
514  if (!has_prob_fun_suffix(decl.name_))
515  return;
516  if (decl.arg_decls_.size() == 0) {
517  error_msgs << "Parse Error. Probability functions require"
518  << " at least one argument." << std::endl;
519  pass = false;
520  return;
521  }
522  expr_type variate_type = decl.arg_decls_[0].arg_type_;
523  if (ends_with("_lpdf", decl.name_) && variate_type.base_type_ == INT_T) {
524  error_msgs << "Parse Error. Probability density functions require"
525  << " real variates (first argument)."
526  << " Found type = " << variate_type << std::endl;
527  pass = false;
528  return;
529  }
530  if (ends_with("_lpmf", decl.name_) && variate_type.base_type_ != INT_T) {
531  error_msgs << "Parse Error. Probability mass functions require"
532  << " integer variates (first argument)."
533  << " Found type = " << variate_type << std::endl;
534  pass = false;
535  return;
536  }
537  }
538  boost::phoenix::function<validate_pmf_pdf_variate>
540 
542  bool& pass,
543  std::ostream& error_msgs) const {
544  pass = decl.body_.is_no_op_statement()
546  error_msgs);
547  if (!pass) {
548  error_msgs << "Improper return in body of function." << std::endl;
549  return;
550  }
551 
552  if ((ends_with("_log", decl.name_)
553  || ends_with("_lpdf", decl.name_)
554  || ends_with("_lpmf", decl.name_)
555  || ends_with("_lcdf", decl.name_)
556  || ends_with("_lccdf", decl.name_))
557  && !decl.return_type_.is_primitive_double()) {
558  pass = false;
559  error_msgs << "Require real return type for probability functions"
560  << " ending in _log, _lpdf, _lpmf, _lcdf, or _lccdf."
561  << std::endl;
562  }
563  }
564  boost::phoenix::function<validate_return_type> validate_return_type_f;
565 
567  vm.add("lp__", DOUBLE_T, local_origin);
568  vm.add("params_r__", VECTOR_T, local_origin);
569  }
570  boost::phoenix::function<scope_lp> scope_lp_f;
571 
573  variable_map& vm) const {
574  vm.remove("lp__");
575  vm.remove("params_r__");
576  for (size_t i = 0; i < decl.arg_decls_.size(); ++i)
577  vm.remove(decl.arg_decls_[i].name_);
578  }
579  boost::phoenix::function<unscope_variables> unscope_variables_f;
580 
581  void add_fun_var::operator()(arg_decl& decl, bool& pass, variable_map& vm,
582  std::ostream& error_msgs) const {
583  if (vm.exists(decl.name_)) {
584  // variable already exists
585  pass = false;
586  error_msgs << "duplicate declaration of variable, name="
587  << decl.name_
588  << "; attempt to redeclare as function argument"
589  << "; original declaration as ";
590  print_var_origin(error_msgs, vm.get_origin(decl.name_));
591  error_msgs << std::endl;
592  return;
593  }
594  pass = true;
595  vm.add(decl.name_, decl.base_variable_declaration(),
597  }
598  boost::phoenix::function<add_fun_var> add_fun_var_f;
599 
600  // TODO(carpenter): seems redundant; see if it can be removed
602  val = omni_idx();
603  }
604  boost::phoenix::function<set_omni_idx> set_omni_idx_f;
605 
607  const {
608  pass = e.expression_type().is_primitive_int();
609  }
610  boost::phoenix::function<validate_int_expr_silent>
612 
614  bool& pass,
615  std::ostream& error_msgs)
616  const {
617  if (e.expression_type().type() != INT_T) {
618  error_msgs << "ERROR: Indexes must be expressions of integer type."
619  << " found type = ";
620  write_base_expr_type(error_msgs, e.expression_type().type());
621  error_msgs << '.' << std::endl;
622  }
623  pass = e.expression_type().is_primitive_int();
624  }
625  boost::phoenix::function<validate_int_expression_warn>
627 
628 
630  std::ostream& error_msgs) const {
631  if (e.expression_type().type() != INT_T) {
632  error_msgs << "ERROR: Container index must be integer; found type=";
633  write_base_expr_type(error_msgs, e.expression_type().type());
634  error_msgs << std::endl;
635  pass = false;
636  return;
637  }
638  if (e.expression_type().num_dims_ > 1) {
639  // tests > 1 so that message is coherent because the single
640  // integer array tests don't print
641  error_msgs << "index must be integer or 1D integer array;"
642  << " found number of dimensions="
644  << std::endl;
645  pass = false;
646  return;
647  }
648  if (e.expression_type().num_dims_ == 0) {
649  // need integer array expression here, but nothing else to report
650  pass = false;
651  return;
652  }
653  pass = true;
654  }
655  boost::phoenix::function<validate_ints_expression>
657 
658 
660  vm.add("lp__",
661  base_var_decl("lp__", std::vector<expression>(), DOUBLE_T),
662  local_origin); // lp acts as a local where defined
663  vm.add("params_r__",
664  base_var_decl("params_r__", std::vector<expression>(), VECTOR_T),
665  local_origin); // lp acts as a local where defined
666  }
667  boost::phoenix::function<add_lp_var> add_lp_var_f;
668 
670  vm.remove("lp__");
671  vm.remove("params_r__");
672  }
673  boost::phoenix::function<remove_lp_var> remove_lp_var_f;
674 
676  pos_iterator_t _where, variable_map& vm,
677  std::stringstream& error_msgs) const {
678  using boost::spirit::get_line;
679  using boost::format;
680  using std::setw;
681 
682  size_t idx_errline = get_line(_where);
683 
684  error_msgs << std::endl;
685 
686  if (idx_errline > 0) {
687  error_msgs << "ERROR at line " << idx_errline
688  << std::endl << std::endl;
689 
690  std::basic_stringstream<char> sprogram;
691  sprogram << boost::make_iterator_range(_begin, _end);
692 
693  // show error in context 2 lines before, 1 lines after
694  size_t idx_errcol = 0;
695  idx_errcol = get_column(_begin, _where) - 1;
696 
697  std::string lineno = "";
698  format fmt_lineno("% 3d: ");
699 
700  std::string line_2before = "";
701  std::string line_before = "";
702  std::string line_err = "";
703  std::string line_after = "";
704 
705  size_t idx_line = 0;
706  size_t idx_before = idx_errline - 1;
707  if (idx_before > 0) {
708  // read lines up to error line, save 2 most recently read
709  while (idx_before > idx_line) {
710  line_2before = line_before;
711  std::getline(sprogram, line_before);
712  idx_line++;
713  }
714  if (line_2before.length() > 0) {
715  lineno = str(fmt_lineno % (idx_before - 1) );
716  error_msgs << lineno << line_2before << std::endl;
717  }
718  lineno = str(fmt_lineno % idx_before);
719  error_msgs << lineno << line_before << std::endl;
720  }
721 
722  std::getline(sprogram, line_err);
723  lineno = str(fmt_lineno % idx_errline);
724  error_msgs << lineno << line_err << std::endl
725  << setw(idx_errcol + lineno.length()) << "^" << std::endl;
726 
727  if (!sprogram.eof()) {
728  std::getline(sprogram, line_after);
729  lineno = str(fmt_lineno % (idx_errline+1));
730  error_msgs << lineno << line_after << std::endl;
731  }
732  }
733  error_msgs << std::endl;
734  }
735  boost::phoenix::function<program_error> program_error_f;
736 
738  const expression& e,
739  bool& pass,
740  std::stringstream& error_msgs)
741  const {
742  if (!e.expression_type().is_primitive()) {
743  error_msgs << "conditions in if-else statement must be"
744  << " primitive int or real;"
745  << " found type=" << e.expression_type()
746  << std::endl;
747  pass = false;
748  return;
749  }
750  cs.conditions_.push_back(e);
751  pass = true;
752  return;
753  }
754  boost::phoenix::function<add_conditional_condition>
756 
758  const statement& s) const {
759  cs.bodies_.push_back(s);
760  }
761  boost::phoenix::function<add_conditional_body> add_conditional_body_f;
762 
763  void deprecate_old_assignment_op::operator()(std::ostream& error_msgs)
764  const {
765  error_msgs << "Warning (non-fatal): assignment operator <- deprecated"
766  << " in the Stan language;"
767  << " use = instead."
768  << std::endl;
769  }
770  boost::phoenix::function<deprecate_old_assignment_op>
772 
774  std::ostream& error_msgs) const {
775  if (origin != function_argument_origin
776  && origin != function_argument_origin_lp
777  && origin != function_argument_origin_rng) {
778  error_msgs << "Returns only allowed from function bodies."
779  << std::endl;
780  pass = false;
781  return;
782  }
783  pass = true;
784  }
785  boost::phoenix::function<validate_return_allowed> validate_return_allowed_f;
786 
788  bool& pass,
789  std::ostream& error_msgs)
790  const {
791  if (origin != void_function_argument_origin
793  && origin != void_function_argument_origin_rng) {
794  error_msgs << "Void returns only allowed from function"
795  << " bodies of void return type."
796  << std::endl;
797  pass = false;
798  return;
799  }
800  pass = true;
801  }
802  boost::phoenix::function<validate_void_return_allowed>
804 
805  void identifier_to_var::operator()(const std::string& name,
806  const var_origin& origin_allowed,
807  variable& v, bool& pass,
808  const variable_map& vm,
809  std::ostream& error_msgs) const {
810  // validate existence
811  if (!vm.exists(name)) {
812  pass = false;
813  return;
814  }
815  // validate origin
816  var_origin lhs_origin = vm.get_origin(name);
817  if (lhs_origin != local_origin
818  && lhs_origin != origin_allowed) {
819  pass = false;
820  return;
821  }
822  // enforce constancy of function args
823  if (lhs_origin == function_argument_origin
824  || lhs_origin == function_argument_origin_lp
825  || lhs_origin == function_argument_origin_rng
826  || lhs_origin == void_function_argument_origin
827  || lhs_origin == void_function_argument_origin_lp
828  || lhs_origin == void_function_argument_origin_rng) {
829  pass = false;
830  return;
831  }
832  v = variable(name);
833  v.set_type(vm.get_base_type(name), vm.get_num_dims(name));
834  pass = true;
835  }
836  boost::phoenix::function<identifier_to_var> identifier_to_var_f;
837 
838  void validate_assgn::operator()(const assgn& a, bool& pass,
839  std::ostream& error_msgs) const {
840  // resolve type of lhs[idxs] and make sure it matches rhs
841  std::string name = a.lhs_var_.name_;
842  expression lhs_expr = expression(a.lhs_var_);
843  expr_type lhs_type = indexed_type(lhs_expr, a.idxs_);
844  if (lhs_type.is_ill_formed()) {
845  error_msgs << "Left-hand side indexing incompatible with variable."
846  << std::endl;
847  pass = false;
848  return;
849  }
850 
851  expr_type rhs_type = a.rhs_.expression_type();
852  base_expr_type lhs_base_type = lhs_type.base_type_;
853  base_expr_type rhs_base_type = rhs_type.base_type_;
854  // allow int -> double promotion, even in arrays
855  bool types_compatible
856  = lhs_base_type == rhs_base_type
857  || (lhs_base_type == DOUBLE_T && rhs_base_type == INT_T);
858  if (!types_compatible) {
859  error_msgs << "base type mismatch in assignment"
860  << "; variable name="
861  << name
862  << ", type=";
863  write_base_expr_type(error_msgs, lhs_base_type);
864  error_msgs << "; right-hand side type=";
865  write_base_expr_type(error_msgs, rhs_base_type);
866  error_msgs << std::endl;
867  pass = false;
868  return;
869  }
870 
871  if (lhs_type.num_dims_ != rhs_type.num_dims_) {
872  error_msgs << "dimension mismatch in assignment"
873  << "; variable name="
874  << name
875  << ", num dimensions given="
876  << lhs_type.num_dims_
877  << "; right-hand side dimensions="
878  << rhs_type.num_dims_
879  << std::endl;
880  pass = false;
881  return;
882  }
883 
884  if (a.lhs_var_occurs_on_rhs()) {
885  // this only requires a warning --- a deep copy will be made
886  error_msgs << "WARNING: left-hand side variable"
887  << " (name=" << name << ")"
888  << " occurs on right-hand side of assignment, causing"
889  << " inefficient deep copy to avoid aliasing."
890  << std::endl;
891  }
892 
893  pass = true;
894  }
895  boost::phoenix::function<validate_assgn> validate_assgn_f;
896 
898  const var_origin& origin_allowed,
899  bool& pass, variable_map& vm,
900  std::ostream& error_msgs) const {
901  // validate existence
902  std::string name = a.var_dims_.name_;
903  if (!vm.exists(name)) {
904  error_msgs << "unknown variable in assignment"
905  << "; lhs variable=" << a.var_dims_.name_
906  << std::endl;
907 
908  pass = false;
909  return;
910  }
911 
912  // validate origin
913  var_origin lhs_origin = vm.get_origin(name);
914  if (lhs_origin != local_origin
915  && lhs_origin != origin_allowed) {
916  error_msgs << "attempt to assign variable in wrong block."
917  << " left-hand-side variable origin=";
918  print_var_origin(error_msgs, lhs_origin);
919  error_msgs << std::endl;
920  pass = false;
921  return;
922  }
923 
924  // enforce constancy of function args
925  if (lhs_origin == function_argument_origin
926  || lhs_origin == function_argument_origin_lp
927  || lhs_origin == function_argument_origin_rng
928  || lhs_origin == void_function_argument_origin
929  || lhs_origin == void_function_argument_origin_lp
930  || lhs_origin == void_function_argument_origin_rng) {
931  error_msgs << "Illegal to assign to function argument variables."
932  << std::endl
933  << "Use local variables instead."
934  << std::endl;
935  pass = false;
936  return;
937  }
938 
939  // validate types
940  a.var_type_ = vm.get(name);
941  size_t lhs_var_num_dims = a.var_type_.dims_.size();
942  size_t num_index_dims = a.var_dims_.dims_.size();
943 
945  lhs_var_num_dims,
946  num_index_dims);
947 
948  if (lhs_type.is_ill_formed()) {
949  error_msgs << "too many indexes for variable "
950  << "; variable name = " << name
951  << "; num dimensions given = " << num_index_dims
952  << "; variable array dimensions = " << lhs_var_num_dims
953  << std::endl;
954  pass = false;
955  return;
956  }
957 
958  base_expr_type lhs_base_type = lhs_type.base_type_;
959  base_expr_type rhs_base_type = a.expr_.expression_type().base_type_;
960  // allow int -> double promotion
961  bool types_compatible
962  = lhs_base_type == rhs_base_type
963  || (lhs_base_type == DOUBLE_T && rhs_base_type == INT_T);
964  if (!types_compatible) {
965  error_msgs << "base type mismatch in assignment"
966  << "; variable name = "
967  << a.var_dims_.name_
968  << ", type = ";
969  write_base_expr_type(error_msgs, lhs_base_type);
970  error_msgs << "; right-hand side type=";
971  write_base_expr_type(error_msgs, rhs_base_type);
972  error_msgs << std::endl;
973  pass = false;
974  return;
975  }
976 
977  if (lhs_type.num_dims_ != a.expr_.expression_type().num_dims_) {
978  error_msgs << "dimension mismatch in assignment"
979  << "; variable name = "
980  << a.var_dims_.name_
981  << ", num dimensions given = "
982  << lhs_type.num_dims_
983  << "; right-hand side dimensions = "
985  << std::endl;
986  pass = false;
987  return;
988  }
989 
990  pass = true;
991  }
992  boost::phoenix::function<validate_assignment> validate_assignment_f;
993 
994  bool is_defined(const std::string& function_name,
995  const std::vector<expr_type>& arg_types) {
996  expr_type ret_type(DOUBLE_T, 0);
997  function_signature_t sig(ret_type, arg_types);
998  return function_signatures::instance().is_defined(function_name, sig);
999  }
1000 
1001  bool is_double_return(const std::string& function_name,
1002  const std::vector<expr_type>& arg_types,
1003  std::ostream& error_msgs) {
1005  .get_result_type(function_name, arg_types, error_msgs, true)
1007  }
1008 
1009  bool is_univariate(const expr_type& et) {
1010  return et.num_dims_ == 0
1011  && (et.base_type_ == INT_T
1012  || et.base_type_ == DOUBLE_T);
1013  }
1014 
1016  const variable_map& var_map, bool& pass,
1017  std::ostream& error_msgs) const {
1018  static const bool user_facing = true;
1019  std::vector<expr_type> arg_types;
1020  arg_types.push_back(s.expr_.expression_type());
1021  for (size_t i = 0; i < s.dist_.args_.size(); ++i)
1022  arg_types.push_back(s.dist_.args_[i].expression_type());
1023  std::string function_name(s.dist_.family_);
1024  std::string internal_function_name = get_prob_fun(function_name);
1026  .discrete_first_arg(internal_function_name);
1027 
1028  if (internal_function_name.size() == 0) {
1029  pass = false;
1030  error_msgs << "Error: couldn't find distribution named "
1031  << function_name << std::endl;
1032  return;
1033  }
1034 
1035  if ((internal_function_name.find("multiply_log") != std::string::npos)
1036  || (internal_function_name.find("binomial_coefficient_log")
1037  != std::string::npos)) {
1038  error_msgs << "Only distribution names can be used with"
1039  << " sampling (~) notation; found non-distribution"
1040  << " function: " << function_name
1041  << std::endl;
1042  pass = false;
1043  return;
1044  }
1045 
1046  if (internal_function_name.find("cdf_log") != std::string::npos) {
1047  error_msgs << "CDF and CCDF functions may not be used with"
1048  << " sampling notation."
1049  << " Use increment_log_prob("
1050  << internal_function_name << "(...)) instead."
1051  << std::endl;
1052  pass = false;
1053  return;
1054  }
1055 
1056  if (internal_function_name == "lkj_cov_log") {
1057  error_msgs << "Warning: the lkj_cov_log() sampling distribution"
1058  << " is deprecated. It will be removed in Stan 3."
1059  << std::endl
1060  << "Code LKJ covariance in terms of an lkj_corr()"
1061  << " distribution on a correlation matrix"
1062  << " and independent lognormals on the scales."
1063  << std::endl << std::endl;
1064  }
1065 
1066  if (!is_double_return(internal_function_name, arg_types, error_msgs)) {
1067  error_msgs << "require real scalar return type for"
1068  << " probability function." << std::endl;
1069  pass = false;
1070  return;
1071  }
1072  // test for LHS not being purely a variable
1073  if (has_non_param_var(s.expr_, var_map)) {
1074  error_msgs << "Warning (non-fatal):"
1075  << std::endl
1076  << "Left-hand side of sampling statement (~) may contain a"
1077  << " non-linear transform of a parameter or local variable."
1078  << std::endl
1079  << "If it does, you need to include a target += statement"
1080  << " with the log absolute determinant of the Jacobian of"
1081  << " the transform."
1082  << std::endl
1083  << "Left-hand-side of sampling statement:"
1084  << std::endl
1085  << " ";
1086  generate_expression(s.expr_, user_facing, error_msgs);
1087  error_msgs << " ~ " << function_name << "(...)"
1088  << std::endl;
1089  }
1090  // validate that variable and params are univariate if truncated
1091  if (s.truncation_.has_low() || s.truncation_.has_high()) {
1092  if (!is_univariate(s.expr_.expression_type())) {
1093  error_msgs << "Outcomes in truncated distributions"
1094  << " must be univariate."
1095  << std::endl
1096  << " Found outcome expression: ";
1097  generate_expression(s.expr_, user_facing, error_msgs);
1098  error_msgs << std::endl
1099  << " with non-univariate type: "
1100  << s.expr_.expression_type()
1101  << std::endl;
1102  pass = false;
1103  return;
1104  }
1105  for (size_t i = 0; i < s.dist_.args_.size(); ++i)
1106  if (!is_univariate(s.dist_.args_[i].expression_type())) {
1107  error_msgs << "Parameters in truncated distributions"
1108  << " must be univariate."
1109  << std::endl
1110  << " Found parameter expression: ";
1111  generate_expression(s.dist_.args_[i], user_facing, error_msgs);
1112  error_msgs << std::endl
1113  << " with non-univariate type: "
1114  << s.dist_.args_[i].expression_type()
1115  << std::endl;
1116  pass = false;
1117  return;
1118  }
1119  }
1120  if (s.truncation_.has_low()
1122  error_msgs << "Lower bounds in truncated distributions"
1123  << " must be univariate."
1124  << std::endl
1125  << " Found lower bound expression: ";
1126  generate_expression(s.truncation_.low_, user_facing, error_msgs);
1127  error_msgs << std::endl
1128  << " with non-univariate type: "
1130  << std::endl;
1131  pass = false;
1132  return;
1133  }
1134  if (s.truncation_.has_high()
1136  error_msgs << "Upper bounds in truncated distributions"
1137  << " must be univariate."
1138  << std::endl
1139  << " Found upper bound expression: ";
1140  generate_expression(s.truncation_.high_, user_facing, error_msgs);
1141  error_msgs << std::endl
1142  << " with non-univariate type: "
1144  << std::endl;
1145  pass = false;
1146  return;
1147  }
1148 
1149  // make sure CDFs or CCDFs exist with conforming signature
1150  // T[L, ]
1151  if (s.truncation_.has_low() && !s.truncation_.has_high()) {
1152  std::vector<expr_type> arg_types_trunc(arg_types);
1153  arg_types_trunc[0] = s.truncation_.low_.expression_type();
1154  std::string function_name_ccdf = get_ccdf(s.dist_.family_);
1155  if (function_name_ccdf == s.dist_.family_
1156  || !is_double_return(function_name_ccdf, arg_types_trunc,
1157  error_msgs)) {
1158  error_msgs << "lower truncation not defined for specified"
1159  << " arguments to "
1160  << s.dist_.family_ << std::endl;
1161  pass = false;
1162  return;
1163  }
1164  if (!is_double_return(function_name_ccdf, arg_types, error_msgs)) {
1165  error_msgs << "lower bound in truncation type does not match"
1166  << " sampled variate in distribution's type"
1167  << std::endl;
1168  pass = false;
1169  return;
1170  }
1171  }
1172  // T[, H]
1173  if (!s.truncation_.has_low() && s.truncation_.has_high()) {
1174  std::vector<expr_type> arg_types_trunc(arg_types);
1175  arg_types_trunc[0] = s.truncation_.high_.expression_type();
1176  std::string function_name_cdf = get_cdf(s.dist_.family_);
1177  if (function_name_cdf == s.dist_.family_
1178  || !is_double_return(function_name_cdf, arg_types_trunc,
1179  error_msgs)) {
1180  error_msgs << "upper truncation not defined for"
1181  << " specified arguments to "
1182  << s.dist_.family_ << std::endl;
1183 
1184  pass = false;
1185  return;
1186  }
1187  if (!is_double_return(function_name_cdf, arg_types, error_msgs)) {
1188  error_msgs << "upper bound in truncation type does not match"
1189  << " sampled variate in distribution's type"
1190  << std::endl;
1191  pass = false;
1192  return;
1193  }
1194  }
1195  // T[L, H]
1196  if (s.truncation_.has_low() && s.truncation_.has_high()) {
1197  std::vector<expr_type> arg_types_trunc(arg_types);
1198  arg_types_trunc[0] = s.truncation_.low_.expression_type();
1199  std::string function_name_cdf = get_cdf(s.dist_.family_);
1200  if (function_name_cdf == s.dist_.family_
1201  || !is_double_return(function_name_cdf, arg_types_trunc,
1202  error_msgs)) {
1203  error_msgs << "lower truncation not defined for specified"
1204  << " arguments to "
1205  << s.dist_.family_ << std::endl;
1206  pass = false;
1207  return;
1208  }
1209  if (!is_double_return(function_name_cdf, arg_types, error_msgs)) {
1210  error_msgs << "lower bound in truncation type does not match"
1211  << " sampled variate in distribution's type"
1212  << std::endl;
1213  pass = false;
1214  return;
1215  }
1216  }
1217 
1218  pass = true;
1219  }
1220  boost::phoenix::function<validate_sample> validate_sample_f;
1221 
1223  const stan::lang::expression& expr,
1224  std::stringstream& error_msgs) const {
1225  static const bool user_facing = true;
1226  if (expr.expression_type() != VOID_T) {
1227  error_msgs << "Illegal statement beginning with non-void"
1228  << " expression parsed as"
1229  << std::endl << " ";
1230  generate_expression(expr.expr_, user_facing, error_msgs);
1231  error_msgs << std::endl
1232  << "Not a legal assignment, sampling, or function"
1233  << " statement. Note that"
1234  << std::endl
1235  << " * Assignment statements only allow variables"
1236  << " (with optional indexes) on the left;"
1237  << std::endl
1238  << " if you see an outer function logical_lt (<)"
1239  << " with negated (-) second argument,"
1240  << std::endl
1241  << " it indicates an assignment statement A <- B"
1242  << " with illegal left"
1243  << std::endl
1244  << " side A parsed as expression (A < (-B))."
1245  << std::endl
1246  << " * Sampling statements allow arbitrary"
1247  << " value-denoting expressions on the left."
1248  << std::endl
1249  << " * Functions used as statements must be"
1250  << " declared to have void returns"
1251  << std::endl << std::endl;
1252  pass = false;
1253  return;
1254  }
1255  pass = true;
1256  }
1257  boost::phoenix::function<expression_as_statement> expression_as_statement_f;
1258 
1259  void unscope_locals::operator()(const std::vector<var_decl>& var_decls,
1260  variable_map& vm) const {
1261  for (size_t i = 0; i < var_decls.size(); ++i)
1262  vm.remove(var_decls[i].name());
1263  }
1264  boost::phoenix::function<unscope_locals> unscope_locals_f;
1265 
1267  const expression& e, bool& pass,
1268  std::stringstream& error_msgs) const {
1269  pass = e.expression_type().is_primitive();
1270  if (!pass) {
1271  error_msgs << "conditions in while statement must be primitive"
1272  << " int or real;"
1273  << " found type=" << e.expression_type() << std::endl;
1274  return;
1275  }
1276  ws.condition_ = e;
1277  }
1278  boost::phoenix::function<add_while_condition> add_while_condition_f;
1279 
1281  const {
1282  ws.body_ = s;
1283  }
1284  boost::phoenix::function<add_while_body> add_while_body_f;
1285 
1286  void add_loop_identifier::operator()(const std::string& name,
1287  std::string& name_local,
1288  bool& pass, variable_map& vm,
1289  std::stringstream& error_msgs) const {
1290  name_local = name;
1291  pass = !vm.exists(name);
1292  if (!pass)
1293  error_msgs << "ERROR: loop variable already declared."
1294  << " variable name=\"" << name << "\"" << std::endl;
1295  else
1296  vm.add(name, base_var_decl(name, std::vector<expression>(), INT_T),
1297  local_origin); // loop var acts like local
1298  }
1299  boost::phoenix::function<add_loop_identifier> add_loop_identifier_f;
1300 
1301  void remove_loop_identifier::operator()(const std::string& name,
1302  variable_map& vm) const {
1303  vm.remove(name);
1304  }
1305  boost::phoenix::function<remove_loop_identifier> remove_loop_identifier_f;
1306 
1308  bool& pass,
1309  std::stringstream& error_msgs)
1310  const {
1311  if (!expr.expression_type().is_primitive_int()) {
1312  error_msgs << "expression denoting integer required; found type="
1313  << expr.expression_type() << std::endl;
1314  pass = false;
1315  return;
1316  }
1317  pass = true;
1318  }
1319  boost::phoenix::function<validate_int_expr> validate_int_expr_f;
1320 
1322  std::stringstream& error_msgs) const {
1323  error_msgs << "Warning (non-fatal): increment_log_prob(...);"
1324  << " is deprecated and will be removed in the future."
1325  << std::endl
1326  << " Use target += ...; instead."
1327  << std::endl;
1328  }
1329  boost::phoenix::function<deprecate_increment_log_prob>
1331 
1332  void validate_allow_sample::operator()(const bool& allow_sample,
1333  bool& pass,
1334  std::stringstream& error_msgs)
1335  const {
1336  pass = allow_sample;
1337  if (!pass)
1338  error_msgs << "Sampling statements (~) and increment_log_prob() are"
1339  << std::endl
1340  << "only allowed in the model block."
1341  << std::endl;
1342  }
1343  boost::phoenix::function<validate_allow_sample> validate_allow_sample_f;
1344 
1346  bool& pass,
1347  std::ostream& error_msgs)
1348  const {
1349  pass = !e.expression_type().is_void();
1350  if (!pass)
1351  error_msgs << "attempt to increment log prob with void expression"
1352  << std::endl;
1353  }
1354  boost::phoenix::function<validate_non_void_expression>
1356 
1357 
1359  const pos_iterator_t& begin,
1360  const pos_iterator_t& end) const {
1361  stmt.begin_line_ = get_line(begin);
1362  stmt.end_line_ = get_line(end);
1363  }
1364  boost::phoenix::function<add_line_number> add_line_number_f;
1365 
1367  s = return_statement();
1368  }
1369  boost::phoenix::function<set_void_return> set_void_return_f;
1370 
1372  s = no_op_statement();
1373  }
1374  boost::phoenix::function<set_no_op> set_no_op_f;
1375 
1376 
1377  void deprecated_integrate_ode::operator()(std::ostream& error_msgs)
1378  const {
1379  error_msgs << "Warning: the integrate_ode() function is deprecated"
1380  << " in the Stan language; use integrate_ode_rk45() [non-stiff]"
1381  << " or integrate_ode_bdf() [stiff] instead."
1382  << std::endl;
1383  }
1384  boost::phoenix::function<deprecated_integrate_ode>
1386 
1387  template <class T>
1389  const variable_map& var_map,
1390  bool& pass,
1391  std::ostream& error_msgs) {
1392  pass = true;
1393  // test function argument type
1394  expr_type sys_result_type(DOUBLE_T, 1);
1395  std::vector<expr_type> sys_arg_types;
1396  sys_arg_types.push_back(expr_type(DOUBLE_T, 0));
1397  sys_arg_types.push_back(expr_type(DOUBLE_T, 1));
1398  sys_arg_types.push_back(expr_type(DOUBLE_T, 1));
1399  sys_arg_types.push_back(expr_type(DOUBLE_T, 1));
1400  sys_arg_types.push_back(expr_type(INT_T, 1));
1401  function_signature_t system_signature(sys_result_type, sys_arg_types);
1403  .is_defined(ode_fun.system_function_name_, system_signature)) {
1404  error_msgs << "first argument to "
1405  << ode_fun.integration_function_name_
1406  << " must be the name of a function with signature"
1407  << " (real, real[], real[], real[], int[]) : real[] ";
1408  pass = false;
1409  }
1410 
1411  // test regular argument types
1412  if (ode_fun.y0_.expression_type() != expr_type(DOUBLE_T, 1)) {
1413  error_msgs << "second argument to "
1414  << ode_fun.integration_function_name_
1415  << " must have type real[] for intial system state;"
1416  << " found type="
1417  << ode_fun.y0_.expression_type()
1418  << ". ";
1419  pass = false;
1420  }
1421  if (!ode_fun.t0_.expression_type().is_primitive()) {
1422  error_msgs << "third argument to "
1423  << ode_fun.integration_function_name_
1424  << " must have type real or int for initial time;"
1425  << " found type="
1426  << ode_fun.t0_.expression_type()
1427  << ". ";
1428  pass = false;
1429  }
1430  if (ode_fun.ts_.expression_type() != expr_type(DOUBLE_T, 1)) {
1431  error_msgs << "fourth argument to "
1432  << ode_fun.integration_function_name_
1433  << " must have type real[]"
1434  << " for requested solution times; found type="
1435  << ode_fun.ts_.expression_type()
1436  << ". ";
1437  pass = false;
1438  }
1439  if (ode_fun.theta_.expression_type() != expr_type(DOUBLE_T, 1)) {
1440  error_msgs << "fifth argument to "
1441  << ode_fun.integration_function_name_
1442  << " must have type real[] for parameters; found type="
1443  << ode_fun.theta_.expression_type()
1444  << ". ";
1445  pass = false;
1446  }
1447  if (ode_fun.x_.expression_type() != expr_type(DOUBLE_T, 1)) {
1448  error_msgs << "sixth argument to "
1449  << ode_fun.integration_function_name_
1450  << " must have type real[] for real data; found type="
1451  << ode_fun.x_.expression_type()
1452  << ". ";
1453  pass = false;
1454  }
1455  if (ode_fun.x_int_.expression_type() != expr_type(INT_T, 1)) {
1456  error_msgs << "seventh argument to "
1457  << ode_fun.integration_function_name_
1458  << " must have type int[] for integer data; found type="
1459  << ode_fun.x_int_.expression_type()
1460  << ". ";
1461  pass = false;
1462  }
1463 
1464  // test data-only variables do not have parameters (int locals OK)
1465  if (has_var(ode_fun.t0_, var_map)) {
1466  error_msgs << "third argument to "
1467  << ode_fun.integration_function_name_
1468  << " (initial times)"
1469  << " must be data only and not reference parameters";
1470  pass = false;
1471  }
1472  if (has_var(ode_fun.ts_, var_map)) {
1473  error_msgs << "fourth argument to "
1474  << ode_fun.integration_function_name_
1475  << " (solution times)"
1476  << " must be data only and not reference parameters";
1477  pass = false;
1478  }
1479  if (has_var(ode_fun.x_, var_map)) {
1480  error_msgs << "sixth argument to "
1481  << ode_fun.integration_function_name_
1482  << " (real data)"
1483  << " must be data only and not reference parameters";
1484  pass = false;
1485  }
1486  }
1487 
1489  const variable_map& var_map,
1490  bool& pass,
1491  std::ostream& error_msgs) const {
1492  validate_integrate_ode_non_control_args(ode_fun, var_map, pass,
1493  error_msgs);
1494  }
1495  boost::phoenix::function<validate_integrate_ode> validate_integrate_ode_f;
1496 
1498  const integrate_ode_control& ode_fun,
1499  const variable_map& var_map, bool& pass,
1500  std::ostream& error_msgs) const {
1501  validate_integrate_ode_non_control_args(ode_fun, var_map, pass,
1502  error_msgs);
1503  if (!ode_fun.rel_tol_.expression_type().is_primitive()) {
1504  error_msgs << "eighth argument to "
1505  << ode_fun.integration_function_name_
1506  << " (relative tolerance) must have type real or int;"
1507  << " found type="
1508  << ode_fun.rel_tol_.expression_type()
1509  << ". ";
1510  pass = false;
1511  }
1512  if (!ode_fun.abs_tol_.expression_type().is_primitive()) {
1513  error_msgs << "ninth argument to "
1514  << ode_fun.integration_function_name_
1515  << " (absolute tolerance) must have type real or int;"
1516  << " found type="
1517  << ode_fun.abs_tol_.expression_type()
1518  << ". ";
1519  pass = false;
1520  }
1521  if (!ode_fun.max_num_steps_.expression_type().is_primitive()) {
1522  error_msgs << "tenth argument to "
1523  << ode_fun.integration_function_name_
1524  << " (max steps) must have type real or int;"
1525  << " found type="
1526  << ode_fun.max_num_steps_.expression_type()
1527  << ". ";
1528  pass = false;
1529  }
1530 
1531  // test data-only variables do not have parameters (int locals OK)
1532  if (has_var(ode_fun.rel_tol_, var_map)) {
1533  error_msgs << "eight argument to "
1534  << ode_fun.integration_function_name_
1535  << " (relative tolerance) must be data only"
1536  << " and not depend on parameters";
1537  pass = false;
1538  }
1539  if (has_var(ode_fun.abs_tol_, var_map)) {
1540  error_msgs << "ninth argument to "
1541  << ode_fun.integration_function_name_
1542  << " (absolute tolerance ) must be data only"
1543  << " and not depend parameters";
1544  pass = false;
1545  }
1546  if (has_var(ode_fun.max_num_steps_, var_map)) {
1547  error_msgs << "tenth argument to "
1548  << ode_fun.integration_function_name_
1549  << " (max steps) must be data only"
1550  << " and not depend on parameters";
1551  pass = false;
1552  }
1553  }
1554  boost::phoenix::function<validate_integrate_ode_control>
1556 
1558  const var_origin& var_origin,
1559  bool& pass,
1560  std::ostream& error_msgs) const {
1561  if (fun.name_ == "get_lp")
1562  error_msgs << "Warning (non-fatal): get_lp() function deprecated."
1563  << std::endl
1564  << " It will be removed in a future release."
1565  << std::endl
1566  << " Use target() instead."
1567  << std::endl;
1568  if (fun.name_ == "target")
1569  fun.name_ = "get_lp"; // for code gen and context validation
1570 
1571  std::vector<expr_type> arg_types;
1572  for (size_t i = 0; i < fun.args_.size(); ++i)
1573  arg_types.push_back(fun.args_[i].expression_type());
1574 
1576  .get_result_type(fun.name_, arg_types, error_msgs);
1577  if (fun.type_ == ILL_FORMED_T) {
1578  pass = false;
1579  return;
1580  }
1581 
1582  // disjunction so only first match triggered
1583  deprecate_fun("binomial_coefficient_log", "lchoose", fun, error_msgs)
1584  || deprecate_fun("multiply_log", "lmultiply", fun, error_msgs)
1585  || deprecate_suffix("_cdf_log", "'_lcdf'", fun, error_msgs)
1586  || deprecate_suffix("_ccdf_log", "'_lccdf'", fun, error_msgs)
1587  || deprecate_suffix("_log",
1588  "'_lpdf' for density functions or '_lpmf' for mass functions",
1589  fun, error_msgs);
1590 
1591  // add stan::math:: qualifier for built-in nullary and math.h
1592  qualify_builtins(fun);
1594 
1595  // use old function names for built-in prob funs
1596  if (!function_signatures::instance().has_user_defined_key(fun.name_)) {
1597  replace_suffix("_lpdf", "_log", fun);
1598  replace_suffix("_lpmf", "_log", fun);
1599  replace_suffix("_lcdf", "_cdf_log", fun);
1600  replace_suffix("_lccdf", "_ccdf_log", fun);
1601  }
1602  // know these are not user-defined`x
1603  replace_suffix("lmultiply", "multiply_log", fun);
1604  replace_suffix("lchoose", "binomial_coefficient_log", fun);
1605 
1606  if (has_rng_suffix(fun.name_)) {
1607  if (!(var_origin == derived_origin
1608  || var_origin == transformed_data_origin
1609  || var_origin == function_argument_origin_rng)) {
1610  error_msgs << "ERROR: random number generators only allowed in"
1611  << " transformed data block, generated quantities block"
1612  << " or user-defined functions with names ending in _rng"
1613  << "; found function=" << fun.name_ << " in block=";
1614  print_var_origin(error_msgs, var_origin);
1615  error_msgs << std::endl;
1616  pass = false;
1617  return;
1618  }
1619  }
1620 
1621  if (has_lp_suffix(fun.name_) || fun.name_ == "target") {
1622  // modified function_argument_origin to add _lp because
1623  // that's only viable context
1624  if (!(var_origin == transformed_parameter_origin
1625  || var_origin == function_argument_origin_lp
1626  || var_origin == void_function_argument_origin_lp
1627  || var_origin == local_origin)) {
1628  error_msgs << "Function target() or functions suffixed with _lp only"
1629  << " allowed in transformed parameter block, model block"
1630  << std::endl
1631  << "or the body of a function with suffix _lp."
1632  << std::endl
1633  << "Found function = "
1634  << (fun.name_ == "get_lp" ? "target or get_lp" : fun.name_)
1635  << " in block = ";
1636  print_var_origin(error_msgs, var_origin);
1637  error_msgs << std::endl;
1638  pass = false;
1639  return;
1640  }
1641  }
1642 
1643  if (fun.name_ == "max" || fun.name_ == "min") {
1644  if (fun.args_.size() == 2) {
1645  if (fun.args_[0].expression_type().is_primitive_int()
1646  && fun.args_[1].expression_type().is_primitive_int()) {
1647  fun.name_ = "std::" + fun.name_;
1648  }
1649  }
1650  }
1651 
1652  if (fun.name_ == "abs"
1653  && fun.args_.size() > 0
1654  && fun.args_[0].expression_type().is_primitive_double()) {
1655  error_msgs << "Warning: Function abs(real) is deprecated"
1656  << " in the Stan language."
1657  << std::endl
1658  << " It will be removed in a future release."
1659  << std::endl
1660  << " Use fabs(real) instead."
1661  << std::endl << std::endl;
1662  }
1663 
1664  if (fun.name_ == "lkj_cov_log") {
1665  error_msgs << "Warning: the lkj_cov_log() function"
1666  << " is deprecated. It will be removed in Stan 3."
1667  << std::endl
1668  << "Code LKJ covariance in terms of an lkj_corr()"
1669  << " distribution on a correlation matrix"
1670  << " and independent lognormals on the scales."
1671  << std::endl << std::endl;
1672  }
1673 
1674  if (fun.name_ == "if_else") {
1675  error_msgs << "Warning (non-fatal): the if_else() function"
1676  << " is deprecated. "
1677  << "Use the conditional operator '?:' instead."
1678  << std::endl;
1679  }
1680 
1681  fun_result = fun;
1682  pass = true;
1683  }
1684  boost::phoenix::function<set_fun_type_named> set_fun_type_named_f;
1685 
1687  const expression& expr2,
1688  const var_origin& var_origin,
1689  bool& pass,
1690  std::ostream& error_msgs) const {
1691  if (!expr1.expression_type().is_primitive()
1692  || !expr2.expression_type().is_primitive()) {
1693  error_msgs << "arguments to ^ must be primitive (real or int)"
1694  << "; cannot exponentiate "
1695  << expr1.expression_type()
1696  << " by "
1697  << expr2.expression_type()
1698  << " in block=";
1699  print_var_origin(error_msgs, var_origin);
1700  error_msgs << std::endl;
1701  pass = false;
1702  return;
1703  }
1704  std::vector<expression> args;
1705  args.push_back(expr1);
1706  args.push_back(expr2);
1707  fun f("pow", args);
1708  set_fun_type(f, error_msgs);
1709  expr1 = expression(f);
1710  }
1711  boost::phoenix::function<exponentiation_expr> exponentiation_f;
1712 
1714  const expression& expr2,
1715  std::ostream& error_msgs) const {
1716  if (expr1.expression_type().is_primitive()
1717  && expr2.expression_type().is_primitive()) {
1718  expr1 *= expr2;;
1719  return;
1720  }
1721  std::vector<expression> args;
1722  args.push_back(expr1);
1723  args.push_back(expr2);
1724  fun f("multiply", args);
1725  set_fun_type(f, error_msgs);
1726  expr1 = expression(f);
1727  }
1728  boost::phoenix::function<multiplication_expr> multiplication_f;
1729 
1731  const expression& expr2,
1732  std::ostream& error_msgs) const {
1733  static const bool user_facing = true;
1734  if (expr1.expression_type().is_primitive()
1735  && expr2.expression_type().is_primitive()
1736  && (expr1.expression_type().is_primitive_double()
1737  || expr2.expression_type().is_primitive_double())) {
1738  expr1 /= expr2;
1739  return;
1740  }
1741  std::vector<expression> args;
1742  args.push_back(expr1);
1743  args.push_back(expr2);
1744  if (expr1.expression_type().is_primitive_int()
1745  && expr2.expression_type().is_primitive_int()) {
1746  // result might be assigned to real - generate warning
1747  error_msgs << "Warning: integer division"
1748  << " implicitly rounds to integer."
1749  << " Found int division: ";
1750  generate_expression(expr1.expr_, user_facing, error_msgs);
1751  error_msgs << " / ";
1752  generate_expression(expr2.expr_, user_facing, error_msgs);
1753  error_msgs << std::endl
1754  << " Positive values rounded down,"
1755  << " negative values rounded up or down"
1756  << " in platform-dependent way."
1757  << std::endl;
1758 
1759  fun f("divide", args);
1760  set_fun_type(f, error_msgs);
1761  expr1 = expression(f);
1762  return;
1763  }
1764  if ((expr1.expression_type().type() == MATRIX_T
1765  || expr1.expression_type().type() == ROW_VECTOR_T)
1766  && expr2.expression_type().type() == MATRIX_T) {
1767  fun f("mdivide_right", args);
1768  set_fun_type(f, error_msgs);
1769  expr1 = expression(f);
1770  return;
1771  }
1772  fun f("divide", args);
1773  set_fun_type(f, error_msgs);
1774  expr1 = expression(f);
1775  return;
1776  }
1777  boost::phoenix::function<division_expr> division_f;
1778 
1780  bool& pass, std::ostream& error_msgs) const {
1781  if (!expr1.expression_type().is_primitive_int()
1782  && !expr2.expression_type().is_primitive_int()) {
1783  error_msgs << "both operands of % must be int"
1784  << "; cannot modulo "
1785  << expr1.expression_type()
1786  << " by "
1787  << expr2.expression_type();
1788  error_msgs << std::endl;
1789  pass = false;
1790  return;
1791  }
1792  std::vector<expression> args;
1793  args.push_back(expr1);
1794  args.push_back(expr2);
1795  fun f("modulus", args);
1796  set_fun_type(f, error_msgs);
1797  expr1 = expression(f);
1798  }
1799  boost::phoenix::function<modulus_expr> modulus_f;
1800 
1802  const expression& expr2,
1803  std::ostream& error_msgs) const {
1804  std::vector<expression> args;
1805  args.push_back(expr1);
1806  args.push_back(expr2);
1807  if (expr1.expression_type().type() == MATRIX_T
1808  && (expr2.expression_type().type() == VECTOR_T
1809  || expr2.expression_type().type() == MATRIX_T)) {
1810  fun f("mdivide_left", args);
1811  set_fun_type(f, error_msgs);
1812  expr1 = expression(f);
1813  pass = true;
1814  return;
1815  }
1816  fun f("mdivide_left", args); // set for alt args err msg
1817  set_fun_type(f, error_msgs);
1818  expr1 = expression(f);
1819  pass = false;
1820  }
1821  boost::phoenix::function<left_division_expr> left_division_f;
1822 
1824  const expression& expr2,
1825  std::ostream& error_msgs) const {
1826  if (expr1.expression_type().is_primitive()
1827  && expr2.expression_type().is_primitive()) {
1828  expr1 *= expr2;
1829  return;
1830  }
1831  std::vector<expression> args;
1832  args.push_back(expr1);
1833  args.push_back(expr2);
1834  fun f("elt_multiply", args);
1835  set_fun_type(f, error_msgs);
1836  expr1 = expression(f);
1837  }
1838  boost::phoenix::function<elt_multiplication_expr> elt_multiplication_f;
1839 
1841  const expression& expr2,
1842  std::ostream& error_msgs) const {
1843  if (expr1.expression_type().is_primitive()
1844  && expr2.expression_type().is_primitive()) {
1845  expr1 /= expr2;
1846  return;
1847  }
1848  std::vector<expression> args;
1849  args.push_back(expr1);
1850  args.push_back(expr2);
1851  fun f("elt_divide", args);
1852  set_fun_type(f, error_msgs);
1853  expr1 = expression(f);
1854  }
1855  boost::phoenix::function<elt_division_expr> elt_division_f;
1856 
1858  const expression& expr, bool& pass,
1859  std::ostream& error_msgs) const {
1860  if (expr.expression_type().is_primitive()) {
1861  expr_result = expression(unary_op('-', expr));
1862  return;
1863  }
1864  std::vector<expression> args;
1865  args.push_back(expr);
1866  fun f("minus", args);
1867  set_fun_type(f, error_msgs);
1868  expr_result = expression(f);
1869  }
1870  boost::phoenix::function<negate_expr> negate_expr_f;
1871 
1873  const expression& expr,
1874  std::ostream& error_msgs) const {
1875  if (!expr.expression_type().is_primitive()) {
1876  error_msgs << "logical negation operator !"
1877  << " only applies to int or real types; ";
1878  expr_result = expression();
1879  }
1880  std::vector<expression> args;
1881  args.push_back(expr);
1882  fun f("logical_negation", args);
1883  set_fun_type(f, error_msgs);
1884  expr_result = expression(f);
1885  }
1886  boost::phoenix::function<logical_negate_expr> logical_negate_expr_f;
1887 
1888  void transpose_expr::operator()(expression& expr, bool& pass,
1889  std::ostream& error_msgs) const {
1890  if (expr.expression_type().is_primitive())
1891  return;
1892  std::vector<expression> args;
1893  args.push_back(expr);
1894  fun f("transpose", args);
1895  set_fun_type(f, error_msgs);
1896  expr = expression(f);
1897  pass = !expr.expression_type().is_ill_formed();
1898  }
1899  boost::phoenix::function<transpose_expr> transpose_f;
1900 
1901  void add_idxs::operator()(expression& e, std::vector<idx>& idxs,
1902  bool& pass, std::ostream& error_msgs) const {
1903  e = index_op_sliced(e, idxs);
1904  pass = !e.expression_type().is_ill_formed();
1905  if (!pass)
1906  error_msgs << "Indexed expression must have at least as many"
1907  << " dimensions as number of indexes supplied:"
1908  << std::endl
1909  << " indexed expression dims="
1910  << e.total_dims()
1911  << "; num indexes=" << idxs.size()
1912  << std::endl;
1913  }
1914  boost::phoenix::function<add_idxs> add_idxs_f;
1915 
1917  std::vector<std::vector<stan::lang::expression> >& dimss,
1918  bool& pass, std::ostream& error_msgs) const {
1919  index_op iop(expression, dimss);
1920  int expr_dims = expression.total_dims();
1921  int index_dims = num_dimss(dimss);
1922  if (expr_dims < index_dims) {
1923  error_msgs << "Indexed expression must have at least as many"
1924  << " dimensions as number of indexes supplied: "
1925  << std::endl
1926  << " indexed expression dimensionality = " << expr_dims
1927  << "; indexes supplied = " << dimss.size()
1928  << std::endl;
1929  pass = false;
1930  return;
1931  }
1932  iop.infer_type();
1933  if (iop.type_.is_ill_formed()) {
1934  error_msgs << "Indexed expression must have at least as many"
1935  << " dimensions as number of indexes supplied."
1936  << std::endl;
1937  pass = false;
1938  return;
1939  }
1940  pass = true;
1941  expression = iop;
1942  }
1943  boost::phoenix::function<add_expression_dimss> add_expression_dimss_f;
1944 
1946  expression& val, variable_map& vm,
1947  std::ostream& error_msgs, bool& pass) const {
1948  std::string name = var_expr.name_;
1949  if (name == std::string("lp__")) {
1950  error_msgs << std::endl
1951  << "ERROR (fatal): Use of lp__ is no longer supported."
1952  << std::endl
1953  << " Use target += ... statement to increment log density."
1954  << std::endl
1955  << " Use target() function to get log density."
1956  << std::endl;
1957  pass = false;
1958  return;
1959  } else if (name == std::string("params_r__")) {
1960  error_msgs << std::endl << "WARNING:" << std::endl
1961  << " Direct access to params_r__ yields an inconsistent"
1962  << " statistical model in isolation and no guarantee is"
1963  << " made that this model will yield valid inferences."
1964  << std::endl
1965  << " Moreover, access to params_r__ is unsupported"
1966  << " and the variable may be removed without notice."
1967  << std::endl;
1968  }
1969  pass = vm.exists(name);
1970  if (pass) {
1971  var_expr.set_type(vm.get_base_type(name), vm.get_num_dims(name));
1972  } else {
1973  error_msgs << "variable \"" << name << '"' << " does not exist."
1974  << std::endl;
1975  return;
1976  }
1977  val = expression(var_expr);
1978  }
1979  boost::phoenix::function<set_var_type> set_var_type_f;
1980 
1981  void require_vbar::operator()(bool& pass, std::ostream& error_msgs) const {
1982  pass = false;
1983  error_msgs << "Probabilty functions with suffixes _lpdf, _lpmf,"
1984  << " _lcdf, and _lccdf," << std::endl
1985  << "require a vertical bar (|) between the first two"
1986  << " arguments." << std::endl;
1987  }
1988  boost::phoenix::function<require_vbar> require_vbar_f;
1989 
1990 
1991 
1993  std::stringstream& error_msgs)
1994  : error_msgs_(error_msgs) { }
1995 
1997  error_msgs_ << "nil declarations not allowed";
1998  return false; // fail if arises
1999  }
2001  if (x.range_.has_low() || x.range_.has_high()) {
2002  error_msgs_ << "require unconstrained."
2003  << " found range constraint." << std::endl;
2004  return false;
2005  }
2006  return true;
2007  }
2009  const {
2010  if (x.range_.has_low() || x.range_.has_high()) {
2011  error_msgs_ << "require unconstrained."
2012  << " found range constraint." << std::endl;
2013  return false;
2014  }
2015  return true;
2016  }
2018  const {
2019  if (x.range_.has_low() || x.range_.has_high()) {
2020  error_msgs_ << "require unconstrained."
2021  << " found range constraint." << std::endl;
2022  return false;
2023  }
2024  return true;
2025  }
2027  const {
2028  if (x.range_.has_low() || x.range_.has_high()) {
2029  error_msgs_ << "require unconstrained."
2030  << " found range constraint." << std::endl;
2031  return false;
2032  }
2033  return true;
2034  }
2036  const {
2037  if (x.range_.has_low() || x.range_.has_high()) {
2038  error_msgs_ << "require unconstrained."
2039  << " found range constraint." << std::endl;
2040  return false;
2041  }
2042  return true;
2043  }
2045  const unit_vector_var_decl& /*x*/) const {
2046  error_msgs_ << "require unconstrained variable declaration."
2047  << " found unit_vector." << std::endl;
2048  return false;
2049  }
2051  const {
2052  error_msgs_ << "require unconstrained variable declaration."
2053  << " found simplex." << std::endl;
2054  return false;
2055  }
2057  const {
2058  error_msgs_ << "require unconstrained variable declaration."
2059  << " found ordered." << std::endl;
2060  return false;
2061  }
2063  const positive_ordered_var_decl& /*x*/) const {
2064  error_msgs_ << "require unconstrained variable declaration."
2065  << " found positive_ordered." << std::endl;
2066  return false;
2067  }
2069  const cholesky_factor_var_decl& /*x*/) const {
2070  error_msgs_ << "require unconstrained variable declaration."
2071  << " found cholesky_factor." << std::endl;
2072  return false;
2073  }
2075  const cholesky_corr_var_decl& /*x*/) const {
2076  error_msgs_ << "require unconstrained variable declaration."
2077  << " found cholesky_factor_corr." << std::endl;
2078  return false;
2079  }
2081  const cov_matrix_var_decl& /*x*/) const {
2082  error_msgs_ << "require unconstrained variable declaration."
2083  << " found cov_matrix." << std::endl;
2084  return false;
2085  }
2087  const corr_matrix_var_decl& /*x*/) const {
2088  error_msgs_ << "require unconstrained variable declaration."
2089  << " found corr_matrix." << std::endl;
2090  return false;
2091  }
2092 
2093 
2094  data_only_expression::data_only_expression(std::stringstream& error_msgs,
2095  variable_map& var_map)
2096  : error_msgs_(error_msgs),
2097  var_map_(var_map) {
2098  }
2099  bool data_only_expression::operator()(const nil& /*e*/) const {
2100  return true;
2101  }
2103  return true;
2104  }
2106  return true;
2107  }
2109  for (size_t i = 0; i < x.args_.size(); ++i)
2110  if (!boost::apply_visitor(*this, x.args_[i].expr_))
2111  return false;
2112  return true;
2113  }
2115  var_origin origin = var_map_.get_origin(x.name_);
2116  bool is_data = (origin == data_origin)
2117  || (origin == transformed_data_origin)
2118  || (origin == local_origin);
2119  if (!is_data) {
2120  error_msgs_ << "non-data variables not allowed"
2121  << " in dimension declarations."
2122  << std::endl
2123  << " found variable=" << x.name_
2124  << "; declared in block=";
2125  print_var_origin(error_msgs_, origin);
2126  error_msgs_ << std::endl;
2127  }
2128  return is_data;
2129  }
2131  return boost::apply_visitor(*this, x.y0_.expr_)
2132  && boost::apply_visitor(*this, x.theta_.expr_);
2133  }
2135  const {
2136  return boost::apply_visitor(*this, x.y0_.expr_)
2137  && boost::apply_visitor(*this, x.theta_.expr_);
2138  }
2139  bool data_only_expression::operator()(const fun& x) const {
2140  for (size_t i = 0; i < x.args_.size(); ++i)
2141  if (!boost::apply_visitor(*this, x.args_[i].expr_))
2142  return false;
2143  return true;
2144  }
2146  if (!boost::apply_visitor(*this, x.expr_.expr_))
2147  return false;
2148  for (size_t i = 0; i < x.dimss_.size(); ++i)
2149  for (size_t j = 0; j < x.dimss_[i].size(); ++j)
2150  if (!boost::apply_visitor(*this, x.dimss_[i][j].expr_))
2151  return false;
2152  return true;
2153  }
2155  return boost::apply_visitor(*this, x.expr_.expr_);
2156  }
2158  return boost::apply_visitor(*this, x.cond_.expr_)
2159  && boost::apply_visitor(*this, x.true_val_.expr_)
2160  && boost::apply_visitor(*this, x.false_val_.expr_);
2161  }
2163  return boost::apply_visitor(*this, x.left.expr_)
2164  && boost::apply_visitor(*this, x.right.expr_);
2165  }
2167  return boost::apply_visitor(*this, x.subject.expr_);
2168  }
2169 
2170  void validate_decl_constraints::operator()(const bool& allow_constraints,
2171  const bool& declaration_ok,
2172  const var_decl& var_decl,
2173  bool& pass,
2174  std::stringstream& error_msgs)
2175  const {
2176  if (!declaration_ok) {
2177  error_msgs << "Problem with declaration." << std::endl;
2178  pass = false;
2179  return; // short-circuits test of constraints
2180  }
2181  if (allow_constraints) {
2182  pass = true;
2183  return;
2184  }
2185  validate_no_constraints_vis vis(error_msgs);
2186  pass = boost::apply_visitor(vis, var_decl.decl_);
2187  }
2188  boost::phoenix::function<validate_decl_constraints>
2190 
2192  const var_decl& var_decl,
2193  bool& pass,
2194  std::stringstream& error_msgs)
2195  const {
2196  if (!var_decl.has_def()) return;
2197 
2198  // validate that assigment is allowed in this block
2199  if (origin == data_origin
2200  || origin == parameter_origin) {
2201  error_msgs << "variable definition not possible in this block"
2202  << std::endl;
2203  pass = false;
2204  }
2205 
2206  // validate type
2207  expr_type decl_type(var_decl.base_decl().base_type_,
2208  var_decl.dims().size());
2209  expr_type def_type = var_decl.def().expression_type();
2210 
2211  bool types_compatible
2212  = (decl_type.is_primitive()
2213  && def_type.is_primitive()
2214  && (decl_type.type() == def_type.type()
2215  || (decl_type.type() == DOUBLE_T
2216  && def_type.type() == INT_T)))
2217  || (decl_type.type() == def_type.type());
2218  if (!types_compatible) {
2219  error_msgs << "variable definition base type mismatch,"
2220  << " variable declared as base type: ";
2221  write_base_expr_type(error_msgs, decl_type.type());
2222  error_msgs << "variable definition has base: ";
2223  write_base_expr_type(error_msgs, def_type.type());
2224  pass = false;
2225  }
2226  // validate dims
2227  if (decl_type.num_dims() != def_type.num_dims()) {
2228  error_msgs << "variable definition dimensions mismatch,"
2229  << " definition specifies "
2230  << decl_type.num_dims()
2231  << ", declaration specifies "
2232  << def_type.num_dims();
2233  pass = false;
2234  }
2235  return;
2236  }
2237  boost::phoenix::function<validate_definition>
2239 
2240 
2241  void validate_identifier::reserve(const std::string& w) {
2242  reserved_word_set_.insert(w);
2243  }
2244  bool validate_identifier::contains(const std::set<std::string>& s,
2245  const std::string& x) const {
2246  return s.find(x) != s.end();
2247  }
2248  bool validate_identifier::identifier_exists(const std::string& identifier)
2249  const {
2250  return contains(reserved_word_set_, identifier)
2251  || (contains(function_signatures::instance().key_set(), identifier)
2252  && !contains(const_fun_name_set_, identifier));
2253  }
2254 
2256  // constant functions which may be used as identifiers
2257  const_fun_name_set_.insert("pi");
2258  const_fun_name_set_.insert("e");
2259  const_fun_name_set_.insert("sqrt2");
2260  const_fun_name_set_.insert("log2");
2261  const_fun_name_set_.insert("log10");
2262  const_fun_name_set_.insert("not_a_number");
2263  const_fun_name_set_.insert("positive_infinity");
2264  const_fun_name_set_.insert("negative_infinity");
2265  const_fun_name_set_.insert("epsilon");
2266  const_fun_name_set_.insert("negative_epsilon");
2267  const_fun_name_set_.insert("machine_precision");
2268 
2269  // illegal identifiers
2270  reserve("for");
2271  reserve("in");
2272  reserve("while");
2273  reserve("repeat");
2274  reserve("until");
2275  reserve("if");
2276  reserve("then");
2277  reserve("else");
2278  reserve("true");
2279  reserve("false");
2280 
2281  reserve("int");
2282  reserve("real");
2283  reserve("vector");
2284  reserve("unit_vector");
2285  reserve("simplex");
2286  reserve("ordered");
2287  reserve("positive_ordered");
2288  reserve("row_vector");
2289  reserve("matrix");
2290  reserve("cholesky_factor_cov");
2291  reserve("cholesky_factor_corr");
2292  reserve("cov_matrix");
2293  reserve("corr_matrix");
2294 
2295  reserve("target");
2296 
2297  reserve("model");
2298  reserve("data");
2299  reserve("parameters");
2300  reserve("quantities");
2301  reserve("transformed");
2302  reserve("generated");
2303 
2304  reserve("var");
2305  reserve("fvar");
2306  reserve("STAN_MAJOR");
2307  reserve("STAN_MINOR");
2308  reserve("STAN_PATCH");
2309  reserve("STAN_MATH_MAJOR");
2310  reserve("STAN_MATH_MINOR");
2311  reserve("STAN_MATH_PATCH");
2312 
2313  reserve("alignas");
2314  reserve("alignof");
2315  reserve("and");
2316  reserve("and_eq");
2317  reserve("asm");
2318  reserve("auto");
2319  reserve("bitand");
2320  reserve("bitor");
2321  reserve("bool");
2322  reserve("break");
2323  reserve("case");
2324  reserve("catch");
2325  reserve("char");
2326  reserve("char16_t");
2327  reserve("char32_t");
2328  reserve("class");
2329  reserve("compl");
2330  reserve("const");
2331  reserve("constexpr");
2332  reserve("const_cast");
2333  reserve("continue");
2334  reserve("decltype");
2335  reserve("default");
2336  reserve("delete");
2337  reserve("do");
2338  reserve("double");
2339  reserve("dynamic_cast");
2340  reserve("else");
2341  reserve("enum");
2342  reserve("explicit");
2343  reserve("export");
2344  reserve("extern");
2345  reserve("false");
2346  reserve("float");
2347  reserve("for");
2348  reserve("friend");
2349  reserve("goto");
2350  reserve("if");
2351  reserve("inline");
2352  reserve("int");
2353  reserve("long");
2354  reserve("mutable");
2355  reserve("namespace");
2356  reserve("new");
2357  reserve("noexcept");
2358  reserve("not");
2359  reserve("not_eq");
2360  reserve("nullptr");
2361  reserve("operator");
2362  reserve("or");
2363  reserve("or_eq");
2364  reserve("private");
2365  reserve("protected");
2366  reserve("public");
2367  reserve("register");
2368  reserve("reinterpret_cast");
2369  reserve("return");
2370  reserve("short");
2371  reserve("signed");
2372  reserve("sizeof");
2373  reserve("static");
2374  reserve("static_assert");
2375  reserve("static_cast");
2376  reserve("struct");
2377  reserve("switch");
2378  reserve("template");
2379  reserve("this");
2380  reserve("thread_local");
2381  reserve("throw");
2382  reserve("true");
2383  reserve("try");
2384  reserve("typedef");
2385  reserve("typeid");
2386  reserve("typename");
2387  reserve("union");
2388  reserve("unsigned");
2389  reserve("using");
2390  reserve("virtual");
2391  reserve("void");
2392  reserve("volatile");
2393  reserve("wchar_t");
2394  reserve("while");
2395  reserve("xor");
2396  reserve("xor_eq");
2397 
2398  // function names declared in signatures
2400  using std::set;
2401  using std::string;
2403 
2404  set<string> fun_names = sigs.key_set();
2405  for (set<string>::iterator it = fun_names.begin();
2406  it != fun_names.end();
2407  ++it)
2408  if (!contains(const_fun_name_set_, *it))
2409  reserve(*it);
2410  }
2411 
2412  void validate_identifier::operator()(const std::string& identifier,
2413  bool& pass,
2414  std::stringstream& error_msgs) const {
2415  int len = identifier.size();
2416  if (len >= 2
2417  && identifier[len-1] == '_'
2418  && identifier[len-2] == '_') {
2419  error_msgs << "variable identifier (name) may"
2420  << " not end in double underscore (__)"
2421  << std::endl
2422  << " found identifer=" << identifier << std::endl;
2423  pass = false;
2424  return;
2425  }
2426  size_t period_position = identifier.find('.');
2427  if (period_position != std::string::npos) {
2428  error_msgs << "variable identifier may not contain a period (.)"
2429  << std::endl
2430  << " found period at position (indexed from 0)="
2431  << period_position
2432  << std::endl
2433  << " found identifier=" << identifier
2434  << std::endl;
2435  pass = false;
2436  return;
2437  }
2438  if (identifier_exists(identifier)) {
2439  error_msgs << "variable identifier (name) may not be reserved word"
2440  << std::endl
2441  << " found identifier=" << identifier
2442  << std::endl;
2443  pass = false;
2444  return;
2445  }
2446  pass = true;
2447  }
2448  boost::phoenix::function<validate_identifier> validate_identifier_f;
2449 
2450  // copies single dimension from M to N if only M declared
2453  if (is_nil(var_decl.N_))
2454  var_decl.N_ = var_decl.M_;
2455  }
2456  boost::phoenix::function<copy_square_cholesky_dimension_if_necessary>
2458 
2460  std::stringstream& /*error_msgs*/) const {
2461  r = range();
2462  }
2463  boost::phoenix::function<empty_range> empty_range_f;
2464 
2466  const expression& expr,
2467  bool& pass,
2468  std::stringstream& error_msgs) const {
2469  range.low_ = expr;
2470  validate_int_expr validator;
2471  validator(expr, pass, error_msgs);
2472  }
2473  boost::phoenix::function<set_int_range_lower> set_int_range_lower_f;
2474 
2476  const expression& expr,
2477  bool& pass,
2478  std::stringstream& error_msgs) const {
2479  range.high_ = expr;
2480  validate_int_expr validator;
2481  validator(expr, pass, error_msgs);
2482  }
2483  boost::phoenix::function<set_int_range_upper> set_int_range_upper_f;
2484 
2486  int var_origin, bool& pass,
2487  variable_map& var_map,
2488  std::stringstream& error_msgs)
2489  const {
2490  if (!expr.expression_type().is_primitive_int()) {
2491  error_msgs << "dimension declaration requires expression"
2492  << " denoting integer; found type="
2493  << expr.expression_type()
2494  << std::endl;
2495  pass = false;
2496  return;
2497  }
2498 
2499  if (var_origin != local_origin) {
2500  data_only_expression vis(error_msgs, var_map);
2501  bool only_data_dimensions = boost::apply_visitor(vis, expr.expr_);
2502  pass = only_data_dimensions;
2503  return;
2504  }
2505 
2506  // don't need to check data vs. parameter in dimensions for
2507  // local variable declarations
2508  pass = true;
2509  }
2510  boost::phoenix::function<validate_int_data_expr> validate_int_data_expr_f;
2511 
2513  const expression& expr,
2514  bool& pass,
2515  std::stringstream& error_msgs)
2516  const {
2517  range.low_ = expr;
2518  validate_double_expr validator;
2519  validator(expr, pass, error_msgs);
2520  }
2521  boost::phoenix::function<set_double_range_lower> set_double_range_lower_f;
2522 
2524  const expression& expr,
2525  bool& pass,
2526  std::stringstream& error_msgs)
2527  const {
2528  range.high_ = expr;
2529  validate_double_expr validator;
2530  validator(expr, pass, error_msgs);
2531  }
2532  boost::phoenix::function<set_double_range_upper> set_double_range_upper_f;
2533 
2534  template <typename T>
2535  void add_var::operator()(var_decl& var_decl_result, const T& var_decl,
2536  variable_map& vm, bool& pass, const var_origin& vo,
2537  std::ostream& error_msgs) const {
2538  if (vm.exists(var_decl.name_)) {
2539  pass = false;
2540  error_msgs << "duplicate declaration of variable, name="
2541  << var_decl.name_;
2542 
2543  error_msgs << "; attempt to redeclare as ";
2544  print_var_origin(error_msgs, vo);
2545 
2546  error_msgs << "; original declaration as ";
2547  print_var_origin(error_msgs, vm.get_origin(var_decl.name_));
2548 
2549  error_msgs << std::endl;
2550  var_decl_result = var_decl;
2551  return;
2552  }
2553  if ((vo == parameter_origin || vo == transformed_parameter_origin)
2554  && var_decl.base_type_ == INT_T) {
2555  pass = false;
2556  error_msgs << "integer parameters or transformed parameters"
2557  << " are not allowed; "
2558  << " found declared type int, parameter name="
2559  << var_decl.name_
2560  << std::endl;
2561  var_decl_result = var_decl;
2562  return;
2563  }
2564  pass = true;
2565  vm.add(var_decl.name_, var_decl, vo);
2566  var_decl_result = var_decl;
2567  }
2568  boost::phoenix::function<add_var> add_var_f;
2569 
2570  template void add_var::operator()(var_decl&, const int_var_decl&,
2571  variable_map&, bool&, const var_origin&,
2572  std::ostream&) const;
2573  template void add_var::operator()(var_decl&, const double_var_decl&,
2574  variable_map&, bool&, const var_origin&,
2575  std::ostream&) const;
2576  template void add_var::operator()(var_decl&, const vector_var_decl&,
2577  variable_map&, bool&, const var_origin&,
2578  std::ostream&) const;
2579  template void add_var::operator()(var_decl&, const row_vector_var_decl&,
2580  variable_map&, bool&, const var_origin&,
2581  std::ostream&) const;
2582  template void add_var::operator()(var_decl&, const matrix_var_decl&,
2583  variable_map&, bool&, const var_origin&,
2584  std::ostream&) const;
2585  template void add_var::operator()(var_decl&, const simplex_var_decl&,
2586  variable_map&, bool&, const var_origin&,
2587  std::ostream&) const;
2588  template void add_var::operator()(var_decl&, const unit_vector_var_decl&,
2589  variable_map&, bool&, const var_origin&,
2590  std::ostream&) const;
2591  template void add_var::operator()(var_decl&, const ordered_var_decl&,
2592  variable_map&, bool&, const var_origin&,
2593  std::ostream&) const;
2594  template void add_var::operator()(var_decl&,
2596  variable_map&, bool&, const var_origin&,
2597  std::ostream&) const;
2598  template void add_var::operator()(var_decl&,
2599  const cholesky_factor_var_decl&,
2600  variable_map&, bool&, const var_origin&,
2601  std::ostream&) const;
2602  template void add_var::operator()(var_decl&, const cholesky_corr_var_decl&,
2603  variable_map&, bool&, const var_origin&,
2604  std::ostream&) const;
2605  template void add_var::operator()(var_decl&, const cov_matrix_var_decl&,
2606  variable_map&, bool&, const var_origin&,
2607  std::ostream&) const;
2608  template void add_var::operator()(var_decl&, const corr_matrix_var_decl&,
2609  variable_map&, bool&, const var_origin&,
2610  std::ostream&) const;
2611 
2612  void validate_in_loop::operator()(bool in_loop, bool& pass,
2613  std::ostream& error_msgs) const {
2614  pass = in_loop;
2615  if (!pass)
2616  error_msgs << "ERROR: break and continue statements are only allowed"
2617  << " in the body of a for-loop or while-loop."
2618  << std::endl;
2619  }
2620  boost::phoenix::function<validate_in_loop> validate_in_loop_f;
2621 
2622  }
2623 }
2624 
2625 #endif
void operator()(while_statement &ws, const statement &s) const
expr_type get_result_type(const std::string &name, const std::vector< expr_type > &args, std::ostream &error_msgs, bool sampling_error_style=false)
Definition: ast_def.cpp:453
void operator()(conditional_statement &cs, const expression &e, bool &pass, std::stringstream &error_msgs) const
expression high_
Definition: ast.hpp:485
boost::phoenix::function< validate_return_allowed > validate_return_allowed_f
variable_dims var_dims_
Definition: ast.hpp:1078
boost::phoenix::function< require_vbar > require_vbar_f
void operator()(var_decl &var_decl_result, const T &var_decl, variable_map &vm, bool &pass, const var_origin &vo, std::ostream &error_msgs) const
bool is_primitive_int() const
Definition: ast_def.cpp:99
bool fun_exists(const std::set< std::pair< std::string, function_signature_t > > &existing, const std::pair< std::string, function_signature_t > &name_sig, bool name_only=true)
std::string strip_ccdf_suffix(const std::string &dist_fun)
Definition: ast_def.cpp:2294
boost::phoenix::function< set_void_function > set_void_function_f
void operator()(function_decl_def &decl, bool &pass, std::ostream &error_msgs) const
bool is_ill_formed() const
Definition: ast_def.cpp:107
std::string family_
Definition: ast.hpp:227
void operator()(conditional_statement &cs, const statement &s) const
void add(const std::string &name, const expr_type &result_type, const std::vector< expr_type > &arg_types)
Definition: ast_def.cpp:201
boost::phoenix::function< add_while_body > add_while_body_f
void operator()(variable &var_expr, expression &val, variable_map &vm, std::ostream &error_msgs, bool &pass) const
expr_type type_
Definition: ast.hpp:443
expression_t expr_
Definition: ast.hpp:293
const int function_argument_origin
Definition: ast.hpp:85
boost::phoenix::function< set_int_range_upper > set_int_range_upper_f
bool is_no_op_statement() const
Definition: ast_def.cpp:1905
const int ROW_VECTOR_T
Definition: ast.hpp:73
void operator()(return_statement &s) const
void operator()(variable_map &vm) const
expr_type type_
Definition: ast.hpp:423
void operator()(range &range, const expression &expr, bool &pass, std::stringstream &error_msgs) const
boost::phoenix::function< validate_assgn > validate_assgn_f
boost::phoenix::function< set_var_type > set_var_type_f
bool has_def() const
Definition: ast_def.cpp:1824
bool has_lp_suffix(const std::string &s)
Definition: ast_def.cpp:2163
void set_fun_type(fun &fun, std::ostream &error_msgs)
std::string name_
Definition: ast.hpp:365
const int derived_origin
Definition: ast.hpp:83
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
void operator()(const std::string &identifier, bool &pass, std::stringstream &error_msgs) const
distribution dist_
Definition: ast.hpp:1067
std::vector< expression > dims_
Definition: ast.hpp:570
void operator()(variable_map &vm) const
boost::phoenix::function< set_int_range_lower > set_int_range_lower_f
std::string original_name_
Definition: ast.hpp:421
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
boost::phoenix::function< binary_op_expr > binary_op_f
std::string strip_cdf_suffix(const std::string &dist_fun)
Definition: ast_def.cpp:2281
boost::phoenix::function< validate_expr_type3 > validate_expr_type3_f
void operator()(const bool &allow_constraints, const bool &declaration_ok, const var_decl &var_decl, bool &pass, std::stringstream &error_msgs) const
range truncation_
Definition: ast.hpp:1068
void operator()(range &range, const expression &expr, bool &pass, std::stringstream &error_msgs) const
boost::phoenix::function< deprecated_integrate_ode > deprecated_integrate_ode_f
void operator()(const expression &expr, bool &pass, std::ostream &error_msgs) const
int num_dimss(std::vector< std::vector< stan::lang::expression > > &dimss)
bool has_low() const
Definition: ast_def.cpp:1215
const int parameter_origin
Definition: ast.hpp:81
void operator()(var_origin origin, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< set_fun_type_named > set_fun_type_named_f
int total_dims() const
Definition: ast_def.cpp:780
bool has_cdf_suffix(const std::string &name)
Definition: ast_def.cpp:2277
boost::phoenix::function< set_no_op > set_no_op_f
boost::phoenix::function< validate_conditional_op > validate_conditional_op_f
const int function_argument_origin_rng
Definition: ast.hpp:87
void qualify_builtins(fun &f)
Add qualifier "stan::math::" to nullary functions defined in the Stan language.
Probability, optimization and sampling library.
bool deprecate_fun(const std::string &old_name, const std::string &new_name, fun &f, std::ostream &msgs)
void operator()(range &range, const expression &expr, bool &pass, std::stringstream &error_msgs) const
std::string get_prob_fun(const std::string &dist_name)
Definition: ast_def.cpp:2250
void operator()(const function_decl_def &decl, bool &pass, std::set< std::pair< std::string, function_signature_t > > &functions_declared, std::set< std::pair< std::string, function_signature_t > > &functions_defined, std::ostream &error_msgs) const
static function_signatures & instance()
Definition: ast_def.cpp:150
size_t num_dims() const
Definition: ast_def.cpp:116
boost::phoenix::function< deprecate_increment_log_prob > deprecate_increment_log_prob_f
void operator()(expression &expr, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< program_error > program_error_f
std::vector< expression > args_
Definition: ast.hpp:422
validate_no_constraints_vis(std::stringstream &error_msgs)
void operator()(const std::string &s, bool &pass) const
void add(const std::string &name, const base_var_decl &base_decl, const var_origin &vo)
Definition: ast_def.cpp:1359
void operator()(std::ostream &error_msgs) const
bool has_prob_fun_suffix(const std::string &name)
Definition: ast_def.cpp:2261
std::string get_cdf(const std::string &dist_name)
Definition: ast_def.cpp:2232
bool is_double_return(const std::string &function_name, const std::vector< expr_type > &arg_types, std::ostream &error_msgs)
std::vector< statement > bodies_
Definition: ast.hpp:967
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
const int DOUBLE_T
Definition: ast.hpp:71
bool has_rng_suffix(const std::string &s)
Definition: ast_def.cpp:2154
void operator()(pos_iterator_t _begin, pos_iterator_t _end, pos_iterator_t _where, variable_map &vm, std::stringstream &error_msgs) const
bool is_primitive_double() const
Definition: ast_def.cpp:103
int base_expr_type
Definition: ast.hpp:65
const int transformed_parameter_origin
Definition: ast.hpp:82
bool has_prob_suffix(const std::string &s)
expression expr_
Definition: ast.hpp:441
void operator()(expression &expr_result, const expression &expr, std::ostream &error_msgs) const
void operator()(sample &s, const variable_map &var_map, bool &pass, std::ostream &error_msgs) const
void operator()(expression &expr1, bool &pass, const expression &expr2, std::ostream &error_msgs) const
boost::spirit::line_pos_iterator< input_iterator_t > pos_iterator_t
boost::phoenix::function< validate_ints_expression > validate_ints_expression_f
boost::phoenix::function< add_conditional_condition > add_conditional_condition_f
boost::phoenix::function< empty_range > empty_range_f
void operator()(const std::string &name, variable_map &vm) const
boost::phoenix::function< subtraction_expr3 > subtraction3_f
boost::phoenix::function< addition_expr3 > addition3_f
void operator()(const std::string &name, const var_origin &origin_allowed, variable &v, bool &pass, const variable_map &vm, std::ostream &error_msgs) const
void operator()(const expression &expr, bool &pass, std::stringstream &error_msgs) const
void validate_integrate_ode_non_control_args(const T &ode_fun, const variable_map &var_map, bool &pass, std::ostream &error_msgs)
bool has_high() const
Definition: ast_def.cpp:1218
void replace_suffix(const std::string &old_suffix, const std::string &new_suffix, fun &f)
void operator()(const expr_type &arg_type, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< add_var > add_var_f
expr_type expression_type() const
Definition: ast_def.cpp:760
base_var_decl var_type_
Definition: ast.hpp:1080
void operator()(const expression &expr, int var_origin, bool &pass, variable_map &var_map, std::stringstream &error_msgs) const
boost::phoenix::function< remove_lp_var > remove_lp_var_f
void operator()(statement &stmt, const pos_iterator_t &begin, const pos_iterator_t &end) const
void operator()(std::stringstream &error_msgs) const
void set_type(const base_expr_type &base_type, size_t num_dims)
Definition: ast_def.cpp:1069
boost::phoenix::function< exponentiation_expr > exponentiation_f
boost::phoenix::function< add_loop_identifier > add_loop_identifier_f
expression true_val_
Definition: ast.hpp:453
std::string name_
Definition: ast.hpp:420
std::string get_ccdf(const std::string &dist_name)
Definition: ast_def.cpp:2241
boost::phoenix::function< set_double_range_lower > set_double_range_lower_f
boost::phoenix::function< validate_void_return_allowed > validate_void_return_allowed_f
void operator()(const expression &e, bool &pass, std::ostream &error_msgs) const
const int function_argument_origin_lp
Definition: ast.hpp:86
void operator()(bool &pass, const stan::lang::expression &expr, std::stringstream &error_msgs) const
boost::phoenix::function< validate_non_void_arg_function > validate_non_void_arg_f
bool identifier_exists(const std::string &identifier) const
void operator()(var_origin origin, bool &pass, std::ostream &error_msgs) const
void print_var_origin(std::ostream &o, const var_origin &vo)
Definition: ast_def.cpp:1289
void operator()(expression &e, std::vector< idx > &idxs, bool &pass, std::ostream &error_msgs) const
void reserve(const std::string &w)
boost::phoenix::function< remove_loop_identifier > remove_loop_identifier_f
boost::phoenix::function< add_conditional_body > add_conditional_body_f
boost::phoenix::function< transpose_expr > transpose_f
boost::phoenix::function< validate_definition > validate_definition_f
void operator()(std::string &fname, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< multiplication_expr > multiplication_f
bool is_nil(const expression &e)
Definition: ast_def.cpp:1008
var_decl_t decl_
Definition: ast.hpp:833
void operator()(expression &fun_result, fun &fun, const var_origin &var_origin, bool &pass, std::ostream &error_msgs) const
void operator()(conditional_op &cond_expr, const var_origin &var_origin, bool &pass, const variable_map &var_map, std::ostream &error_msgs) const
expression left
Definition: ast.hpp:466
boost::phoenix::function< validate_identifier > validate_identifier_f
void operator()(expression &expr_result, const expression &expr, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< validate_int_expression_warn > validate_int_expression_warn_f
void operator()(const bool &allow_sample, bool &pass, std::stringstream &error_msgs) const
void remove(const std::string &name)
Definition: ast_def.cpp:1365
base_var_decl base_decl() const
Definition: ast_def.cpp:1816
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
const int void_function_argument_origin_rng
Definition: ast.hpp:90
boost::phoenix::function< validate_int_expr > validate_int_expr_f
bool discrete_first_arg(const std::string &name) const
Definition: ast_def.cpp:183
bool fun_name_exists(const std::string &name)
Definition: ast_def.cpp:2303
void operator()(expression &expr1, const expression &expr2, const var_origin &var_origin, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< validate_decl_constraints > validate_decl_constraints_f
void operator()(range &r, std::stringstream &) const
void operator()(while_statement &ws, const expression &e, bool &pass, std::stringstream &error_msgs) const
bool exists(const std::string &name) const
Definition: ast_def.cpp:1335
void operator()(no_op_statement &s) const
var_origin var_origin_
Definition: ast.hpp:457
size_t get_num_dims(const std::string &name) const
Definition: ast_def.cpp:1349
bool ends_with(const std::string &suffix, const std::string &s)
Definition: ast_def.cpp:2225
bool returns_type(const expr_type &return_type, const statement &statement, std::ostream &error_msgs)
Definition: ast_def.cpp:695
boost::phoenix::function< add_expression_dimss > add_expression_dimss_f
void operator()(function_decl_def &decl, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< validate_prob_fun > validate_prob_fun_f
boost::phoenix::function< add_line_number > add_line_number_f
bool is_defined(const std::string &name, const function_signature_t &sig)
Definition: ast_def.cpp:172
bool lhs_var_occurs_on_rhs() const
Definition: ast_def.cpp:2067
void operator()(const integrate_ode_control &ode_fun, const variable_map &var_map, bool &pass, std::ostream &error_msgs) const
void operator()(const expression &expr, bool &pass, std::stringstream &error_msgs) const
base_expr_type type() const
Definition: ast_def.cpp:113
boost::phoenix::function< validate_int_data_expr > validate_int_data_expr_f
std::vector< idx > idxs_
Definition: ast.hpp:1107
void operator()(omni_idx &val) const
std::vector< expression > args_
Definition: ast.hpp:228
const int VOID_T
Definition: ast.hpp:69
boost::phoenix::function< validate_int_expr_silent > validate_int_expr_silent_f
void operator()(assignment &a, const var_origin &origin_allowed, bool &pass, variable_map &vm, std::ostream &error_msgs) const
var_origin get_origin(const std::string &name) const
Definition: ast_def.cpp:1353
expr_type indexed_type(const expression &e, const std::vector< idx > &idxs)
Return the type of the expression indexed by the generalized index sequence.
Definition: ast_def.cpp:2082
void operator()(expression &expr1, const expression &expr2, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< is_prob_fun > is_prob_fun_f
int var_origin
Definition: ast.hpp:77
const int void_function_argument_origin
Definition: ast.hpp:88
boost::phoenix::function< set_omni_idx > set_omni_idx_f
void generate_expression(const expression &e, std::ostream &o)
Definition: generator.hpp:446
base_expr_type base_type_
Definition: ast.hpp:571
std::pair< expr_type, std::vector< expr_type > > function_signature_t
Definition: ast.hpp:131
bool has_non_param_var(const expression &e, const variable_map &var_map)
Returns true if the specified expression contains a variable that is defined as a transformed paramet...
Definition: ast_def.cpp:978
expression rhs_
Definition: ast.hpp:1108
void operator()(function_decl_def &decl, variable_map &vm) const
void operator()(const integrate_ode &ode_fun, const variable_map &var_map, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< validate_allow_sample > validate_allow_sample_f
const int data_origin
Definition: ast.hpp:79
boost::phoenix::function< assign_lhs > assign_lhs_f
size_t begin_line_
Definition: ast.hpp:879
boost::phoenix::function< validate_integrate_ode > validate_integrate_ode_f
void operator()(variable_map &vm) const
const int void_function_argument_origin_lp
Definition: ast.hpp:89
boost::phoenix::function< validate_double_expr > validate_double_expr_f
base_expr_type base_type_
Definition: ast.hpp:102
expression def() const
Definition: ast_def.cpp:1828
boost::phoenix::function< expression_as_statement > expression_as_statement_f
expr_type infer_type_indexing(const base_expr_type &expr_base_type, size_t num_expr_dims, size_t num_index_dims)
Definition: ast_def.cpp:1133
const int INT_T
Definition: ast.hpp:70
std::string integration_function_name_
Definition: ast.hpp:394
boost::phoenix::function< validate_pmf_pdf_variate > validate_pmf_pdf_variate_f
std::string name_
Definition: ast.hpp:1011
std::vector< expression > conditions_
Definition: ast.hpp:966
bool contains(const std::set< std::string > &s, const std::string &x) const
void operator()(size_t &lhs) const
void operator()(const expression &e, bool &pass, std::ostream &error_msgs) const
std::vector< arg_decl > arg_decls_
Definition: ast.hpp:1026
void qualify(fun &f)
Set original name of specified function to name and add "stan::math::" namespace qualifier to name...
variable lhs_var_
Definition: ast.hpp:1106
boost::phoenix::function< add_lp_var > add_lp_var_f
bool has_var(const expression &e, const variable_map &var_map)
Returns true if the specified expression contains a variable that is defined as a parameter...
Definition: ast_def.cpp:888
boost::phoenix::function< elt_multiplication_expr > elt_multiplication_f
bool is_univariate(const expr_type &et)
expression expr_
Definition: ast.hpp:1066
void operator()(const std::vector< var_decl > &var_decls, variable_map &vm) const
void operator()(L &lhs, const R &rhs) const
void operator()(const expression &e, bool &pass, std::ostream &error_msgs) const
bool is_primitive() const
Definition: ast_def.cpp:95
std::vector< expression > dims_
Definition: ast.hpp:331
bool has_ccdf_suffix(const std::string &name)
Definition: ast_def.cpp:2290
void operator()(const assgn &a, bool &pass, std::ostream &error_msgs) const
base_var_decl base_variable_declaration()
Definition: ast_def.cpp:569
void operator()(range &range, const expression &expr, bool &pass, std::stringstream &error_msgs) const
expression low_
Definition: ast.hpp:484
boost::phoenix::function< set_allows_sampling_origin > set_allows_sampling_origin_f
std::string name_
Definition: ast.hpp:330
boost::phoenix::function< logical_negate_expr > logical_negate_expr_f
expression expr_
Definition: ast.hpp:1079
boost::phoenix::function< validate_sample > validate_sample_f
boost::phoenix::function< increment_size_t > increment_size_t_f
std::set< std::string > key_set() const
Definition: ast_def.cpp:543
const int VECTOR_T
Definition: ast.hpp:72
boost::phoenix::function< add_function_signature > add_function_signature_f
void operator()(std::ostream &error_msgs) const
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
bool is_defined(const std::string &function_name, const std::vector< expr_type > &arg_types)
boost::phoenix::function< set_double_range_upper > set_double_range_upper_f
boost::phoenix::function< add_idxs > add_idxs_f
expression right
Definition: ast.hpp:467
std::string strip_prob_fun_suffix(const std::string &dist_fun)
Definition: ast_def.cpp:2266
void operator()(const std::string &identifier, bool &allow_sampling, int &origin) const
expression subject
Definition: ast.hpp:477
std::vector< expression > args_
Definition: ast.hpp:357
const int local_origin
Definition: ast.hpp:84
boost::phoenix::function< unscope_locals > unscope_locals_f
std::ostream & write_base_expr_type(std::ostream &o, base_expr_type type)
Definition: ast_def.cpp:25
void set_user_defined(const std::pair< std::string, function_signature_t > &name_sig)
Definition: ast_def.cpp:158
boost::phoenix::function< division_expr > division_f
void operator()(const std::string &name, std::string &name_local, bool &pass, variable_map &vm, std::stringstream &error_msgs) const
boost::phoenix::function< unscope_variables > unscope_variables_f
boost::phoenix::function< elt_division_expr > elt_division_f
void operator()(bool &pass, std::set< std::pair< std::string, function_signature_t > > &declared, std::set< std::pair< std::string, function_signature_t > > &defined, std::ostream &error_msgs, bool allow_undefined) const
bool is_void() const
Definition: ast_def.cpp:110
void operator()(const expr_type &return_type, var_origin &origin, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< identifier_to_var > identifier_to_var_f
void operator()(cholesky_factor_var_decl &var_decl) const
boost::phoenix::function< validate_in_loop > validate_in_loop_f
boost::phoenix::function< negate_expr > negate_expr_f
boost::phoenix::function< copy_square_cholesky_dimension_if_necessary > copy_square_cholesky_dimension_if_necessary_f
boost::phoenix::function< validate_return_type > validate_return_type_f
void operator()(bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< add_fun_var > add_fun_var_f
void operator()(const expression &e, bool &pass) const
std::vector< std::vector< expression > > dimss_
Definition: ast.hpp:442
boost::phoenix::function< add_while_condition > add_while_condition_f
boost::phoenix::function< validate_assignment > validate_assignment_f
bool deprecate_suffix(const std::string &deprecated_suffix, const std::string &replacement, fun &f, std::ostream &msgs)
boost::phoenix::function< validate_integrate_ode_control > validate_integrate_ode_control_f
Placeholder struct for boost::variant default ctors.
Definition: ast.hpp:18
boost::phoenix::function< validate_declarations > validate_declarations_f
const int ILL_FORMED_T
Definition: ast.hpp:75
boost::phoenix::function< left_division_expr > left_division_f
boost::phoenix::function< set_void_return > set_void_return_f
const int MATRIX_T
Definition: ast.hpp:74
boost::phoenix::function< modulus_expr > modulus_f
expression false_val_
Definition: ast.hpp:454
base_expr_type get_base_type(const std::string &name) const
Definition: ast_def.cpp:1345
data_only_expression(std::stringstream &error_msgs, variable_map &var_map)
boost::phoenix::function< scope_lp > scope_lp_f
const int transformed_data_origin
Definition: ast.hpp:80
boost::phoenix::function< deprecate_old_assignment_op > deprecate_old_assignment_op_f
void operator()(arg_decl &decl, bool &pass, variable_map &vm, std::ostream &error_msgs) const
void operator()(bool in_loop, bool &pass, std::ostream &error_msgs) const
void operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
base_var_decl get(const std::string &name) const
Definition: ast_def.cpp:1339
void operator()(expression &expression, std::vector< std::vector< stan::lang::expression > > &dimss, bool &pass, std::ostream &error_msgs) const
std::vector< expression > dims() const
Definition: ast_def.cpp:1820
boost::phoenix::function< validate_non_void_expression > validate_non_void_expression_f
void qualify_cpp11_builtins(fun &f)
Add namespace qualifier stan::math:: to specify Stan versions of functions to avoid ambiguities with ...
void operator()(const var_origin &origin, const var_decl &var_decl, bool &pass, std::stringstream &error_msgs) const
void operator()(expression &expr1, const expression &expr2, const std::string &op, const std::string &fun_name, std::ostream &error_msgs) const

     [ Stan Home Page ] © 2011–2016, Stan Development Team.