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

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