carl  24.04
Computer ARithmetic Library
OPBImporter.cpp
Go to the documentation of this file.
1 #include "OPBImporter.h"
2 
3 #include "SpiritHelper.h"
4 
5 #include <tuple>
6 #include <vector>
7 
8 #define BOOST_SPIRIT_USE_PHOENIX_V3
9 #include <boost/fusion/adapted/std_tuple.hpp>
10 #include <boost/fusion/include/std_pair.hpp>
11 #include <boost/spirit/include/phoenix.hpp>
12 #include <boost/spirit/include/qi.hpp>
13 #include <boost/spirit/include/qi_parse.hpp>
14 #include <boost/spirit/include/support_line_pos_iterator.hpp>
15 
16 namespace carl::io {
17  namespace spirit = boost::spirit;
18  namespace qi = boost::spirit::qi;
19  namespace px = boost::phoenix;
20 
21  using BaseIteratorType = spirit::istream_iterator;
22  using PositionIteratorType = spirit::line_pos_iterator<BaseIteratorType>;
25 
26  struct Skipper: public qi::grammar<Iterator> {
27  Skipper(): Skipper::base_type(main, "skipper") {
28  main = (qi::space | (qi::lit("*") > *(qi::char_ - qi::eol) > qi::eol));
29  };
30  qi::rule<Iterator> main;
31  };
32 
33  struct OPBParser: public qi::grammar<Iterator, OPBFile(), Skipper> {
34  OPBParser(): OPBParser::base_type(mMain, "OPBFile") {
35  mRelation.add
36  ("=", Relation::EQ)
37  ("!=", Relation::NEQ)
38  ("<", Relation::LESS)
39  ("<=", Relation::LEQ)
40  (">", Relation::GREATER)
41  (">=", Relation::GEQ)
42  ;
43  mVarname = qi::lexeme[ qi::alpha > *(qi::alnum | qi::char_("_"))];
44  mNewVarWrapper = mVarname[qi::_val = px::bind(&OPBParser::addVariable, px::ref(*this), qi::_1)];
45  mTerm = qi::int_ >> (qi::lexeme[mVariables >> !(qi::alnum | qi::char_("_"))] | mNewVarWrapper);
46  mPolynomial = +mTerm;
47  mConstraint = mPolynomial > mRelation > qi::int_;
48  mObjective = -(qi::lit("min:") > mPolynomial > qi::lit(";"));
49  mMain = (mObjective >> *(mConstraint > ";"))[qi::_val = px::bind(&OPBParser::createFile, px::ref(*this), qi::_1, qi::_2)];
50  qi::on_error<qi::fail>(mMain, errorHandler(qi::_1, qi::_2, qi::_3, qi::_4));
51  }
52  std::optional<OPBFile> parse(std::istream& in) {
53  in.unsetf(std::ios::skipws);
54  Skipper skipper;
55  BaseIteratorType basebegin(in);
56  Iterator begin(basebegin);
57  Iterator end;
58  OPBFile res;
59  if (qi::phrase_parse(begin, end, *this, skipper, res)) {
60  if (begin != end) {
61  std::cout << "Failed to parse:" << std::endl;
62  std::cout << "\"" << std::string(begin, end) << "\"" << std::endl;
63  return std::nullopt;
64  }
65  return res;
66  } else {
67  std::cout << "Failed to parse:" << std::endl;
68  std::cout << "\"" << std::string(begin, end) << "\"" << std::endl;
69  return std::nullopt;
70  }
71  }
72 
73  private:
74  Variable addVariable(const std::string& s) {
76  mVariables.add(s, var);
77  return var;
78  }
79  OPBFile createFile(const OPBPolynomial& obj, const std::vector<OPBConstraint>& constraints) {
80  return OPBFile(obj, constraints);
81  }
82 
83  qi::symbols<char, Relation> mRelation;
84  qi::symbols<char, Variable> mVariables;
85  qi::rule<Iterator, std::string(), Skipper> mVarname;
87  qi::rule<Iterator, std::pair<int,Variable>(), Skipper> mTerm;
91  qi::rule<Iterator, OPBFile(), Skipper> mMain;
92  px::function<ErrorHandler> errorHandler;
93  };
94 
95  std::optional<OPBFile> parseOPBFile(std::ifstream& in) {
96  OPBParser parser;
97  return parser.parse(in);
98  }
99 
100 }
Variable fresh_integer_variable() noexcept
Definition: VariablePool.h:204
@ GREATER
Definition: SignCondition.h:15
PositionIteratorType Iterator
Definition: OPBImporter.cpp:23
std::optional< OPBFile > parseOPBFile(std::ifstream &in)
Definition: OPBImporter.cpp:95
spirit::istream_iterator BaseIteratorType
Definition: OPBImporter.cpp:21
spirit::line_pos_iterator< BaseIteratorType > PositionIteratorType
Definition: OPBImporter.cpp:22
carl::io::helper::ErrorHandler ErrorHandler
Definition: OPBImporter.cpp:24
std::vector< std::pair< int, carl::Variable > > OPBPolynomial
Definition: OPBImporter.h:16
std::tuple< OPBPolynomial, Relation, int > OPBConstraint
Definition: OPBImporter.h:17
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
qi::rule< Iterator > main
Definition: OPBImporter.cpp:29
qi::rule< Iterator, Variable(), Skipper > mNewVarWrapper
Definition: OPBImporter.cpp:86
qi::rule< Iterator, std::pair< int, Variable >), Skipper > mTerm
Definition: OPBImporter.cpp:87
qi::rule< Iterator, OPBPolynomial(), Skipper > mObjective
Definition: OPBImporter.cpp:90
qi::symbols< char, Variable > mVariables
Definition: OPBImporter.cpp:84
qi::rule< Iterator, OPBConstraint(), Skipper > mConstraint
Definition: OPBImporter.cpp:89
Variable addVariable(const std::string &s)
Definition: OPBImporter.cpp:74
px::function< ErrorHandler > errorHandler
Definition: OPBImporter.cpp:92
qi::rule< Iterator, std::string(), Skipper > mVarname
Definition: OPBImporter.cpp:85
qi::rule< Iterator, OPBPolynomial(), Skipper > mPolynomial
Definition: OPBImporter.cpp:88
qi::rule< Iterator, OPBFile(), Skipper > mMain
Definition: OPBImporter.cpp:91
std::optional< OPBFile > parse(std::istream &in)
Definition: OPBImporter.cpp:52
qi::symbols< char, Relation > mRelation
Definition: OPBImporter.cpp:83
OPBFile createFile(const OPBPolynomial &obj, const std::vector< OPBConstraint > &constraints)
Definition: OPBImporter.cpp:79