carl  24.04
Computer ARithmetic Library
FormulaParser.h
Go to the documentation of this file.
1 /**
2  * @file FormulaParser.h
3  * @author Florian Corzilius <corzilius@cs.rwth-aachen.de>
4  */
5 
6 #pragma once
7 
8 #include "Common.h"
9 
10 namespace carl::io {
11 namespace parser {
12 
13 template<typename Pol>
14 struct FormulaParser: public qi::grammar<Iterator, Formula<Pol>(), Skipper> {
16  FormulaParser<Pol>::base_type(main, "formula"),
17  varmap(), binaryop(), naryop(),
18  varname(), variable(), formula_op(), formula(), main()
19  {
20  binaryop.add("IMPLIES", FormulaType::IMPLIES);
21  binaryop.add("iff", FormulaType::IFF);
22  binaryop.add("xor", FormulaType::XOR);
23  naryop.add("and", FormulaType::AND);
24  naryop.add("or", FormulaType::OR);
25 
26  varname = qi::lexeme[ (qi::alpha | qi::char_("~!@$%^&*_+=<>.?/-")) > *(qi::alnum | qi::char_("~!@$%^&*_+=<>.?/-"))];
27  varname.name("varname");
28 // qi::debug(varname);
29 
30  variable = (varmap[qi::_val = qi::_1]) | (varname[qi::_val = px::bind(&FormulaParser<Pol>::newVariable, px::ref(*this), qi::_1)]);
31  variable.name("variable");
32 // qi::debug(variable);
33 
34  formula_op =
35  ((qi::lit("not") | qi::lit("NOT")) > formula)[qi::_val = px::construct<Formula<Pol>>(FormulaType::NOT, qi::_1)]
36  | formula[qi::_a = qi::_1] >> (
37  (binaryop > formula)[qi::_val = px::bind(&FormulaParser::createBinary, px::ref(*this), qi::_1, qi::_a, qi::_2)]
38  | (+("AND" > formula))[qi::_val = px::bind(&FormulaParser::createNary, px::ref(*this), FormulaType::AND, qi::_a, qi::_1)]
39  | (+("OR" > formula))[qi::_val = px::bind(&FormulaParser::createNary, px::ref(*this), FormulaType::OR, qi::_a, qi::_1)]
40  | qi::eps[qi::_val = qi::_a]
41  );
42  formula_op.name("formula operation");
43 // qi::debug(formula_op);
44 
45  formula = (variable [qi::_val = px::construct<Formula<Pol>>(qi::_1)])
46  | ("(" >> formula_op > ")")[qi::_val = qi::_1]
47  //| ("(" >> formula > ")")[qi::_val = qi::_1]
48  ;
49  formula.name("formula");
50 // qi::debug(formula);
51 
52  main = formula;
53  main.name("main");
54 // qi::debug(main);
55  }
56 
58  varmap.add(VariablePool::getInstance().get_name(v), v);
59  }
60 
61 private:
62 
63  Variable newVariable(const std::string& s) {
65  varmap.add(s, v);
66  return v;
67  }
68 
70  return Formula<Pol>(op, {lhs, rhs});
71  }
72  Formula<Pol> createNary(FormulaType op, const Formula<Pol>& first, const std::vector<Formula<Pol>>& ops) {
73  assert(!ops.empty());
74  switch (op) {
75  case FormulaType::AND: {
76  if( first.type() == FormulaType::FALSE )
78  Formulas<Pol> subFormulas;
79  subFormulas.push_back( first );
80  for (const auto& subop: ops) {
81  if( subop.type() == FormulaType::FALSE )
83  subFormulas.push_back( subop );
84  }
85  return Formula<Pol>( FormulaType::AND, subFormulas );
86  }
87  case FormulaType::OR: {
88  if( first.type() == FormulaType::TRUE )
90  Formulas<Pol> subFormulas;
91  subFormulas.push_back( first );
92  for (const auto& subop: ops) {
93  if( subop.type() == FormulaType::TRUE )
95  subFormulas.push_back( subop );
96  }
97  return Formula<Pol>( FormulaType::OR, subFormulas );
98  }
99  default:
100  assert(false);
101  }
103  }
104 
105  Formula<Pol> mkAnd(const Formula<Pol>& first, const std::vector<Formula<Pol>>& ops) {
106 // std::cout << __func__ << " of " << first << " and " << ops << std::endl;
107  assert(!ops.empty());
108  if( first.type() == FormulaType::FALSE )
110  Formulas<Pol> subFormulas;
111  subFormulas.push_back( first );
112  for (const auto& op: ops) {
113  if( op.type() == FormulaType::FALSE )
115  subFormulas.push_back( op );
116  }
117 // std::cout << __func__ << ":" << __LINE__ << std::endl;
118  return Formula<Pol>( FormulaType::AND, subFormulas );
119  }
120 
121  Formula<Pol> mkOr(const Formula<Pol>& first, const std::vector<Formula<Pol>>& ops) {
122 // std::cout << __func__ << " of " << first << " and " << ops << std::endl;
123  assert(!ops.empty());
124  if( first.type() == FormulaType::TRUE )
126  Formulas<Pol> subFormulas;
127  subFormulas.push_back( first );
128  for (const auto& op: ops) {
129  if( op.type() == FormulaType::TRUE )
131  subFormulas.push_back( op );
132  }
133 // std::cout << __func__ << ":" << __LINE__ << std::endl;
134  return Formula<Pol>( FormulaType::OR, subFormulas );
135  }
136 
137  qi::symbols<char, Variable> varmap;
138  qi::symbols<char, FormulaType> binaryop;
139  qi::symbols<char, FormulaType> naryop;
140  qi::rule<Iterator, std::string(), Skipper> varname;
142  qi::rule<Iterator, Formula<Pol>(), Skipper, qi::locals<Formula<Pol>>> formula_op;
143  qi::rule<Iterator, Formula<Pol>(), Skipper> formula;
144  qi::rule<Iterator, Formula<Pol>(), Skipper> main;
145 };
146 
147 
148 }
149 }
MultivariatePolynomial< Rational > Pol
Definition: HornerTest.cpp:17
FormulaType
Represent the type of a formula to allow faster/specialized processing.
std::vector< Formula< Poly > > Formulas
Variable fresh_boolean_variable() noexcept
Definition: VariablePool.h:192
boost::spirit::qi::space_type Skipper
Definition: Common.h:34
std::string::const_iterator Iterator
Definition: Common.h:33
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
static VariablePool & getInstance()
Returns the single instance of this class by reference.
Definition: Singleton.h:45
Represent an SMT formula, which can be an atom for some background theory or a boolean combination of...
Definition: Formula.h:47
FormulaType type() const
Definition: Formula.h:254
qi::rule< Iterator, Variable(), Skipper > variable
void addVariable(Variable::Arg v)
Definition: FormulaParser.h:57
qi::symbols< char, Variable > varmap
qi::rule< Iterator, Formula< Pol >), Skipper, qi::locals< Formula< Pol > > > formula_op
qi::rule< Iterator, Formula< Pol >), Skipper > formula
Formula< Pol > createBinary(FormulaType op, const Formula< Pol > &lhs, const Formula< Pol > &rhs)
Definition: FormulaParser.h:69
qi::rule< Iterator, std::string(), Skipper > varname
qi::symbols< char, FormulaType > binaryop
qi::rule< Iterator, Formula< Pol >), Skipper > main
Formula< Pol > createNary(FormulaType op, const Formula< Pol > &first, const std::vector< Formula< Pol >> &ops)
Definition: FormulaParser.h:72
Formula< Pol > mkOr(const Formula< Pol > &first, const std::vector< Formula< Pol >> &ops)
Formula< Pol > mkAnd(const Formula< Pol > &first, const std::vector< Formula< Pol >> &ops)
qi::symbols< char, FormulaType > naryop
Variable newVariable(const std::string &s)
Definition: FormulaParser.h:63