Stan  1.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
var_decls_grammar_def.hpp
Go to the documentation of this file.
1 #ifndef __STAN__GM__PARSER__VAR_DECLS_GRAMMAR_DEF__HPP__
2 #define __STAN__GM__PARSER__VAR_DECLS_GRAMMAR_DEF__HPP__
3 
4 #include <cstddef>
5 #include <iomanip>
6 #include <iostream>
7 #include <istream>
8 #include <map>
9 #include <set>
10 #include <sstream>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 #include <stdexcept>
15 
16 #include <boost/spirit/include/qi.hpp>
17 // FIXME: get rid of unused include
18 #include <boost/spirit/include/phoenix_core.hpp>
19 #include <boost/spirit/include/phoenix_function.hpp>
20 #include <boost/spirit/include/phoenix_fusion.hpp>
21 #include <boost/spirit/include/phoenix_object.hpp>
22 #include <boost/spirit/include/phoenix_operator.hpp>
23 #include <boost/spirit/include/phoenix_stl.hpp>
24 
25 #include <boost/lexical_cast.hpp>
26 #include <boost/fusion/include/adapt_struct.hpp>
27 #include <boost/fusion/include/std_pair.hpp>
28 #include <boost/config/warning_disable.hpp>
29 #include <boost/spirit/include/qi.hpp>
30 #include <boost/spirit/include/qi_numeric.hpp>
31 #include <boost/spirit/include/classic_position_iterator.hpp>
32 #include <boost/spirit/include/phoenix_core.hpp>
33 #include <boost/spirit/include/phoenix_function.hpp>
34 #include <boost/spirit/include/phoenix_fusion.hpp>
35 #include <boost/spirit/include/phoenix_object.hpp>
36 #include <boost/spirit/include/phoenix_operator.hpp>
37 #include <boost/spirit/include/phoenix_stl.hpp>
38 #include <boost/spirit/include/support_multi_pass.hpp>
39 #include <boost/tuple/tuple.hpp>
40 #include <boost/variant/apply_visitor.hpp>
41 #include <boost/variant/recursive_variant.hpp>
42 
43 #include <stan/gm/ast.hpp>
48 
50  (stan::gm::range, range_)
51  (std::string, name_)
52  (std::vector<stan::gm::expression>, dims_) )
53 
54 BOOST_FUSION_ADAPT_STRUCT(stan::gm::double_var_decl,
55  (stan::gm::range, range_)
56  (std::string, name_)
57  (std::vector<stan::gm::expression>, dims_) )
58 
59 BOOST_FUSION_ADAPT_STRUCT(stan::gm::vector_var_decl,
60  (stan::gm::range, range_)
61  (stan::gm::expression, M_)
62  (std::string, name_)
63  (std::vector<stan::gm::expression>, dims_) )
64 
65 BOOST_FUSION_ADAPT_STRUCT(stan::gm::row_vector_var_decl,
66  (stan::gm::range, range_)
67  (stan::gm::expression, N_)
68  (std::string, name_)
69  (std::vector<stan::gm::expression>, dims_) )
70 
71 BOOST_FUSION_ADAPT_STRUCT(stan::gm::matrix_var_decl,
72  (stan::gm::range, range_)
73  (stan::gm::expression, M_)
74  (stan::gm::expression, N_)
75  (std::string, name_)
76  (std::vector<stan::gm::expression>, dims_) )
77 
78 BOOST_FUSION_ADAPT_STRUCT(stan::gm::simplex_var_decl,
79  (stan::gm::expression, K_)
80  (std::string, name_)
81  (std::vector<stan::gm::expression>, dims_) )
82 
83 BOOST_FUSION_ADAPT_STRUCT(stan::gm::ordered_var_decl,
84  (stan::gm::expression, K_)
85  (std::string, name_)
86  (std::vector<stan::gm::expression>, dims_) )
87 
88 BOOST_FUSION_ADAPT_STRUCT(stan::gm::positive_ordered_var_decl,
89  (stan::gm::expression, K_)
90  (std::string, name_)
91  (std::vector<stan::gm::expression>, dims_) )
92 
93 BOOST_FUSION_ADAPT_STRUCT(stan::gm::cov_matrix_var_decl,
94  (stan::gm::expression, K_)
95  (std::string, name_)
96  (std::vector<stan::gm::expression>, dims_) )
97 
98 BOOST_FUSION_ADAPT_STRUCT(stan::gm::corr_matrix_var_decl,
99  (stan::gm::expression, K_)
100  (std::string, name_)
101  (std::vector<stan::gm::expression>, dims_) )
102 
103 namespace stan {
104 
105  namespace gm {
106 
107  struct validate_no_constraints_vis : public boost::static_visitor<bool> {
108  std::stringstream& error_msgs_;
109  validate_no_constraints_vis(std::stringstream& error_msgs)
110  : error_msgs_(error_msgs) {
111  }
112  bool operator()(const nil& x) const {
113  error_msgs_ << "nil declarations not allowed";
114  return false; // fail if arises
115  }
116  bool operator()(const int_var_decl& x) const {
117  if (x.range_.has_low() || x.range_.has_high()) {
118  error_msgs_ << "require unconstrained."
119  << " found range constraint." << std::endl;
120  return false;
121  }
122  return true;
123  }
124  bool operator()(const double_var_decl& x) const {
125  if (x.range_.has_low() || x.range_.has_high()) {
126  error_msgs_ << "require unconstrained."
127  << " found range constraint." << std::endl;
128  return false;
129  }
130  return true;
131  }
132  bool operator()(const vector_var_decl& x) const {
133  return true;
134  }
135  bool operator()(const row_vector_var_decl& x) const {
136  return true;
137  }
138  bool operator()(const matrix_var_decl& x) const {
139  return true;
140  }
141  bool operator()(const simplex_var_decl& x) const {
142  error_msgs_ << "require unconstrained variable declaration."
143  << " found simplex." << std::endl;
144  return false;
145  }
146  bool operator()(const ordered_var_decl& x) const {
147  error_msgs_ << "require unconstrained variable declaration."
148  << " found ordered." << std::endl;
149  return false;
150  }
151  bool operator()(const positive_ordered_var_decl& x) const {
152  error_msgs_ << "require unconstrained variable declaration."
153  << " found positive_ordered." << std::endl;
154  return false;
155  }
156  bool operator()(const cov_matrix_var_decl& x) const {
157  error_msgs_ << "require unconstrained variable declaration."
158  << " found cov_matrix." << std::endl;
159  return false;
160  }
161  bool operator()(const corr_matrix_var_decl& x) const {
162  error_msgs_ << "require unconstrained variable declaration."
163  << " found corr_matrix." << std::endl;
164  return false;
165  }
166  };
167 
168  struct data_only_expression : public boost::static_visitor<bool> {
169  std::stringstream& error_msgs_;
170  variable_map& var_map_;
171  data_only_expression(std::stringstream& error_msgs,
172  variable_map& var_map)
173  : error_msgs_(error_msgs),
174  var_map_(var_map) {
175  }
176  bool operator()(const nil& e) const {
177  return true;
178  }
179  bool operator()(const int_literal& x) const {
180  return true;
181  }
182  bool operator()(const double_literal& x) const {
183  return true;
184  }
185  bool operator()(const variable& x) const {
186  var_origin origin = var_map_.get_origin(x.name_);
187  bool is_data = (origin == data_origin) || (origin == transformed_data_origin);
188  if (!is_data) {
189  error_msgs_ << "non-data variables not allowed in dimension declarations."
190  << std::endl
191  << " found variable=" << x.name_
192  << "; declared in block=";
193  print_var_origin(error_msgs_,origin);
194  error_msgs_ << std::endl;
195  }
196  return is_data;
197  }
198  bool operator()(const fun& x) const {
199  for (size_t i = 0; i < x.args_.size(); ++i)
200  if (!boost::apply_visitor(*this,x.args_[i].expr_))
201  return false;
202  return true;
203  }
204  bool operator()(const index_op& x) const {
205  if (!boost::apply_visitor(*this,x.expr_.expr_))
206  return false;
207  for (size_t i = 0; i < x.dimss_.size(); ++i)
208  for (size_t j = 0; j < x.dimss_[i].size(); ++j)
209  if (!boost::apply_visitor(*this,x.dimss_[i][j].expr_))
210  return false;
211  return true;
212  }
213  bool operator()(const binary_op& x) const {
214  return boost::apply_visitor(*this,x.left.expr_)
215  && boost::apply_visitor(*this,x.right.expr_);
216  }
217  bool operator()(const unary_op& x) const {
218  return boost::apply_visitor(*this,x.subject.expr_);
219  }
220  };
221 
222 
223  struct add_var {
224  template <typename T1, typename T2, typename T3, typename T4, typename T5>
225  struct result { typedef T1 type; };
226  // each type derived from base_var_decl gets own instance
227  template <typename T>
228  T operator()(const T& var_decl,
229  variable_map& vm,
230  bool& pass,
231  const var_origin& vo,
232  std::ostream& error_msgs) const {
233  if (vm.exists(var_decl.name_)) {
234  // variable already exists
235  pass = false;
236  error_msgs << "variable already declared, name="
237  << var_decl.name_
238  << std::endl;
239  return var_decl;
240  }
242  && var_decl.base_type_ == INT_T) {
243  pass = false;
244  error_msgs << "integer parameters or transformed parameters are not allowed; "
245  << " found declared type int, parameter name=" << var_decl.name_
246  << std::endl;
247  return var_decl;
248  }
249  pass = true; // probably don't need to set true
250  vm.add(var_decl.name_,var_decl,vo);
251  return var_decl;
252  }
253  };
254  boost::phoenix::function<add_var> add_var_f;
255 
256  struct validate_decl_constraints {
257  template <typename T1, typename T2, typename T3, typename T4>
258  struct result { typedef bool type; };
259 
260  bool operator()(const bool& allow_constraints,
261  const bool& declaration_ok,
262  const var_decl& var_decl,
263  std::stringstream& error_msgs) const {
264  if (!declaration_ok) {
265  error_msgs << "Problem with declaration." << std::endl;
266  return false; // short-circuits test of constraints
267  }
268  if (allow_constraints)
269  return true;
270  validate_no_constraints_vis vis(error_msgs);
271  bool constraints_ok = boost::apply_visitor(vis,var_decl.decl_);
272  return constraints_ok;
273  }
274  };
275  boost::phoenix::function<validate_decl_constraints>
276  validate_decl_constraints_f;
277 
278  struct validate_identifier {
279  template <typename T1, typename T2>
280  struct result { typedef bool type; };
281 
282  bool operator()(const std::string& identifier,
283  std::stringstream& error_msgs) const {
284  int len = identifier.size();
285  if (len >= 2
286  && identifier[len-1] == '_'
287  && identifier[len-2] == '_') {
288  error_msgs << "identifiers cannot end in double underscore (__)"
289  << "; found identifer=" << identifier;
290  return false;
291  }
292  return true;
293  }
294  };
295  boost::phoenix::function<validate_identifier> validate_identifier_f;
296 
297  struct empty_range {
298  template <typename T1>
299  struct result { typedef range type; };
300  range operator()(std::stringstream& error_msgs) const {
301  return range();
302  }
303  };
304  boost::phoenix::function<empty_range> empty_range_f;
305 
306  struct validate_int_expr {
307  template <typename T1, typename T2>
308  struct result { typedef bool type; };
309 
310  bool operator()(const expression& expr,
311  std::stringstream& error_msgs) const {
312  if (!expr.expression_type().is_primitive_int()) {
313  error_msgs << "expression denoting integer required; found type="
314  << expr.expression_type() << std::endl;
315  return false;
316  }
317  return true;
318  }
319  };
320  boost::phoenix::function<validate_int_expr> validate_int_expr_f;
321 
322  struct set_int_range_lower {
323  template <typename T1, typename T2, typename T3>
324  struct result { typedef bool type; };
325  bool operator()(range& range,
326  const expression& expr,
327  std::stringstream& error_msgs) const {
328  range.low_ = expr;
329  validate_int_expr validator;
330  return validator(expr,error_msgs);
331  }
332  };
333  boost::phoenix::function<set_int_range_lower> set_int_range_lower_f;
334 
335  struct set_int_range_upper {
336  template <typename T1, typename T2, typename T3>
337  struct result { typedef bool type; };
338  bool operator()(range& range,
339  const expression& expr,
340  std::stringstream& error_msgs) const {
341  range.high_ = expr;
342  validate_int_expr validator;
343  return validator(expr,error_msgs);
344  }
345  };
346  boost::phoenix::function<set_int_range_upper> set_int_range_upper_f;
347 
348 
349 
350  struct validate_int_data_expr {
351  template <typename T1, typename T2, typename T3>
352  struct result { typedef bool type; };
353 
354  bool operator()(const expression& expr,
355  variable_map& var_map,
356  std::stringstream& error_msgs) const {
357  if (!expr.expression_type().is_primitive_int()) {
358  error_msgs << "dimension declaration requires expression denoting integer;"
359  << " found type="
360  << expr.expression_type()
361  << std::endl;
362  return false;
363  }
364  data_only_expression vis(error_msgs,var_map);
365  bool only_data_dimensions = boost::apply_visitor(vis,expr.expr_);
366  return only_data_dimensions;
367  }
368  };
369  boost::phoenix::function<validate_int_data_expr> validate_int_data_expr_f;
370 
371  struct validate_double_expr {
372  template <typename T1, typename T2>
373  struct result { typedef bool type; };
374 
375  bool operator()(const expression& expr,
376  std::stringstream& error_msgs) const {
377  if (!expr.expression_type().is_primitive_double()
378  && !expr.expression_type().is_primitive_int()) {
379  error_msgs << "expression denoting double required; found type="
380  << expr.expression_type() << std::endl;
381  return false;
382  }
383  return true;
384  }
385  };
386  boost::phoenix::function<validate_double_expr> validate_double_expr_f;
387 
388 
389  struct set_double_range_lower {
390  template <typename T1, typename T2, typename T3>
391  struct result { typedef bool type; };
392  bool operator()(range& range,
393  const expression& expr,
394  std::stringstream& error_msgs) const {
395  range.low_ = expr;
396  validate_double_expr validator;
397  return validator(expr,error_msgs);
398  }
399  };
400  boost::phoenix::function<set_double_range_lower> set_double_range_lower_f;
401 
402  struct set_double_range_upper {
403  template <typename T1, typename T2, typename T3>
404  struct result { typedef bool type; };
405  bool operator()(range& range,
406  const expression& expr,
407  std::stringstream& error_msgs) const {
408  range.high_ = expr;
409  validate_double_expr validator;
410  return validator(expr,error_msgs);
411  }
412  };
413  boost::phoenix::function<set_double_range_upper> set_double_range_upper_f;
414 
415 
416  template <typename Iterator>
417  var_decls_grammar<Iterator>::var_decls_grammar(variable_map& var_map,
418  std::stringstream& error_msgs)
419  : var_decls_grammar::base_type(var_decls_r),
420  var_map_(var_map),
421  error_msgs_(error_msgs),
422  expression_g(var_map,error_msgs)
423  {
424 
425  using boost::spirit::qi::_1;
426  using boost::spirit::qi::char_;
427  using boost::spirit::qi::eps;
428  using boost::spirit::qi::lexeme;
429  using boost::spirit::qi::lit;
430  using boost::spirit::qi::no_skip;
431  using boost::spirit::qi::_pass;
432  using boost::spirit::qi::_val;
433  using boost::spirit::qi::labels::_a;
434  using boost::spirit::qi::labels::_r1;
435  using boost::spirit::qi::labels::_r2;
436 
437  var_decls_r.name("variable declarations");
438  var_decls_r
439  %= *var_decl_r(_r1,_r2);
440 
441  // _a = error state local, _r1 constraints allowed inherited
442  var_decl_r.name("variable declaration");
443  var_decl_r
444  %= (int_decl_r
445  [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
446  boost::phoenix::ref(error_msgs))]
447  | double_decl_r
448  [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
449  boost::phoenix::ref(error_msgs_))]
450  | vector_decl_r
451  [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
452  boost::phoenix::ref(error_msgs_))]
453  | row_vector_decl_r
454  [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
455  boost::phoenix::ref(error_msgs_))]
456  | matrix_decl_r
457  [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
458  boost::phoenix::ref(error_msgs_))]
459  | simplex_decl_r
460  [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
461  boost::phoenix::ref(error_msgs_))]
462  | ordered_decl_r
463  [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
464  boost::phoenix::ref(error_msgs_))]
465  | positive_ordered_decl_r
466  [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
467  boost::phoenix::ref(error_msgs_))]
468  | corr_matrix_decl_r
469  [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
470  boost::phoenix::ref(error_msgs_))]
471  | cov_matrix_decl_r
472  [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
473  boost::phoenix::ref(error_msgs_))]
474  )
475  > eps
476  [_pass
477  = validate_decl_constraints_f(_r1,_a,_val,
478  boost::phoenix::ref(error_msgs_))]
479  ;
480 
481  int_decl_r.name("integer declaration");
482  int_decl_r
483  %= lit("int")
484  >> no_skip[!char_("a-zA-Z0-9_")]
485  > -range_brackets_int_r
486  // >> (lit(' ') | lit('\n') | lit('\t') | lit('\r'))
487  > identifier_r
488  > opt_dims_r
489  > lit(';');
490 
491  double_decl_r.name("real declaration");
492  double_decl_r
493  %= lit("real")
494  >> no_skip[!char_("a-zA-Z0-9_")]
495  > -range_brackets_double_r
496  > identifier_r
497  > opt_dims_r
498  > lit(';');
499 
500  vector_decl_r.name("vector declaration");
501  vector_decl_r
502  %= lit("vector")
503  > -range_brackets_double_r
504  > lit('[')
505  > expression_g
506  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
507  > lit(']')
508  > identifier_r
509  > opt_dims_r
510  > lit(';');
511 
512  row_vector_decl_r.name("row vector declaration");
513  row_vector_decl_r
514  %= lit("row_vector")
515  > -range_brackets_double_r
516  > lit('[')
517  > expression_g
518  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
519  > lit(']')
520  > identifier_r
521  > opt_dims_r
522  > lit(';');
523 
524  matrix_decl_r.name("matrix declaration");
525  matrix_decl_r
526  %= lit("matrix")
527  > -range_brackets_double_r
528  > lit('[')
529  > expression_g
530  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
531  > lit(',')
532  > expression_g
533  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
534  > lit(']')
535  > identifier_r
536  > opt_dims_r
537  > lit(';');
538 
539  simplex_decl_r.name("simplex declaration");
540  simplex_decl_r
541  %= lit("simplex")
542  > lit('[')
543  > expression_g
544  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
545  > lit(']')
546  > identifier_r
547  > opt_dims_r
548  > lit(';');
549 
550  ordered_decl_r.name("ordered declaration");
551  ordered_decl_r
552  %= lit("ordered")
553  > lit('[')
554  > expression_g
555  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
556  > lit(']')
557  > identifier_r
558  > opt_dims_r
559  > lit(';');
560 
561  positive_ordered_decl_r.name("positive_ordered declaration");
562  positive_ordered_decl_r
563  %= lit("positive_ordered")
564  > lit('[')
565  > expression_g
566  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
567  > lit(']')
568  > identifier_r
569  > opt_dims_r
570  > lit(';');
571 
572  corr_matrix_decl_r.name("correlation matrix declaration");
573  corr_matrix_decl_r
574  %= lit("corr_matrix")
575  > lit('[')
576  > expression_g
577  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
578  > lit(']')
579  > identifier_r
580  > opt_dims_r
581  > lit(';');
582 
583  cov_matrix_decl_r.name("covariance matrix declaration");
584  cov_matrix_decl_r
585  %= lit("cov_matrix")
586  > lit('[')
587  > expression_g
588  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
589  > lit(']')
590  > identifier_r
591  > opt_dims_r
592  > lit(';');
593 
594  opt_dims_r.name("array dimensions (optional)");
595  opt_dims_r
596  %= - dims_r;
597 
598  dims_r.name("array dimensions");
599  dims_r
600  %= lit('[')
601  > (expression_g
602  [_pass = validate_int_data_expr_f(_1,
603  boost::phoenix::ref(var_map_),
604  boost::phoenix::ref(error_msgs_))]
605  % ',')
606  > lit(']')
607  ;
608 
609  range_brackets_int_r.name("integer range expression pair, brackets");
610  range_brackets_int_r
611  = lit('<') [_val = empty_range_f(boost::phoenix::ref(error_msgs_))]
612  > (
613  ( (lit("lower")
614  > lit('=')
615  > expression_g
616  [ _pass = set_int_range_lower_f(_val,_1,
617  boost::phoenix::ref(error_msgs_)) ])
618  > -( lit(',')
619  > lit("upper")
620  > lit('=')
621  > expression_g
622  [ _pass = set_int_range_upper_f(_val,_1,
623  boost::phoenix::ref(error_msgs_)) ] ) )
624  |
625  ( lit("upper")
626  > lit('=')
627  > expression_g
628  [ _pass = set_int_range_upper_f(_val,_1,
629  boost::phoenix::ref(error_msgs_)) ])
630  )
631  > lit('>');
632 
633  range_brackets_double_r.name("real range expression pair, brackets");
634  range_brackets_double_r
635  = lit('<') [_val = empty_range_f(boost::phoenix::ref(error_msgs_))]
636  > (
637  ( (lit("lower")
638  > lit('=')
639  > expression_g
640  [ _pass = set_double_range_lower_f(_val,_1,
641  boost::phoenix::ref(error_msgs_)) ])
642  > -( lit(',')
643  > lit("upper")
644  > lit('=')
645  > expression_g
646  [ _pass = set_double_range_upper_f(_val,_1,
647  boost::phoenix::ref(error_msgs_)) ] ) )
648  |
649  ( lit("upper")
650  > lit('=')
651  > expression_g
652  [ _pass = set_double_range_upper_f(_val,_1,
653  boost::phoenix::ref(error_msgs_)) ])
654  )
655  > lit('>');
656 
657  identifier_r.name("identifier");
658  identifier_r
659  %= identifier_name_r
660  [_pass = validate_identifier_f(_1,boost::phoenix::ref(error_msgs_))]
661  ;
662 
663  identifier_name_r.name("identifier subrule");
664  identifier_name_r
665  %= lexeme[char_("a-zA-Z")
666  >> *char_("a-zA-Z0-9_.")]
667  ;
668 
669 
670  range_r.name("range expression pair, colon");
671  range_r
672  %= expression_g
673  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
674  >> lit(':')
675  >> expression_g
676  [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))];
677 
678  }
679 
680 
681  }
682 }
683 #endif

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