carl  24.04
Computer ARithmetic Library
DIMACSExporter.h
Go to the documentation of this file.
1 #pragma once
2 
4 
7 
8 #include <iostream>
9 #include <map>
10 #include <vector>
11 
12 
13 namespace carl::io {
14 
15 /**
16  * Write formulas to the DIMAS format.
17  */
18 template<typename Pol>
20 private:
21  std::map<carl::Variable, std::size_t> mVariables;
22  std::vector<std::vector<long long>> mClauses;
23 
24  std::size_t id(carl::Variable::Arg v) {
25  auto it = mVariables.find(v);
26  if (it != mVariables.end()) return it->second;
27  std::size_t res = mVariables.size() + 1;
28  mVariables.emplace(v, res);
29  return res;
30  }
31 
32  long long getLiteral(const Formula<Pol>& f) {
33  if (f.type() == BOOL) {
34  return (long long)(id(f.boolean()));
35  }
36  if (f.type() == NOT) {
37  return -getLiteral(f.subformula());
38  }
39  CARL_LOG_ERROR("carl.dimacs", "Formula is not in pure-boolean CNF: " << f);
40  return 0;
41  }
42 
43  bool addDisjunction(const Formula<Pol>& f) {
44  if (f.type() == BOOL || f.type() == NOT) {
45  long long lit = getLiteral(f);
46  if (lit == 0) return false;
47  mClauses.emplace_back(1, lit);
48  return true;
49  }
50  if (f.type() == OR) {
51  std::vector<long long> clause;
52  for (const auto& sub: f) {
53  if (sub.type() == BOOL || sub.type() == NOT) {
54  long long lit = getLiteral(sub);
55  if (lit == 0) return false;
56  clause.push_back(lit);
57  } else {
58  CARL_LOG_ERROR("carl.dimacs", "Added formula to DIMACSExporter has a clause that is not pure-boolean: " << f);
59  return false;
60  }
61  }
62  mClauses.push_back(std::move(clause));
63  return true;
64  }
65  CARL_LOG_ERROR("carl.dimacs", "Added formula to DIMACSExporter has a clause that is not pure-boolean: " << f);
66  return false;
67  }
68 
69 public:
70  bool operator()(const Formula<Pol>& formula) {
71  Formula<Pol> f = carl::to_cnf(formula);
72  if (f.type() == TRUE) {
73  CARL_LOG_INFO("carl.dimacs", "Added TRUE to DIMACSExporter. Skipping...");
74  return true;
75  }
76  if (f.type() == FALSE) {
77  CARL_LOG_WARN("carl.dimacs", "Added FALSE to DIMACSExporter. Skipping...");
78  return true;
79  }
80  if (f.type() == OR || f.type() == BOOL || f.type() == NOT) {
81  return addDisjunction(f);
82  }
83  if (f.type() == AND) {
84  for (const auto& sub: f) {
85  if (!addDisjunction(sub)) return false;
86  }
87  return true;
88  }
89  CARL_LOG_ERROR("carl.dimacs", "Added formula to DIMACSExporter that is not convertible to pure-boolean cnf: " << formula);
90  return false;
91  }
92  void clear() {
93  mVariables.clear();
94  mClauses.clear();
95  }
96  template<typename P>
97  friend std::ostream& operator<<(std::ostream& os, const DIMACSExporter<P>& de) {
98  os << "p cnf " << de.mVariables.size() << " " << de.mClauses.size() << std::endl;
99  for (const auto& clause: de.mClauses) {
100  for (const auto& l: clause) os << l << " ";
101  os << "0" << std::endl;
102  }
103  return os;
104  }
105 };
106 
107 }
A small wrapper that configures logging for carl.
#define CARL_LOG_WARN(channel, msg)
Definition: carl-logging.h:41
#define CARL_LOG_ERROR(channel, msg)
Definition: carl-logging.h:40
#define CARL_LOG_INFO(channel, msg)
Definition: carl-logging.h:42
Formula< Poly > to_cnf(const Formula< Poly > &f, bool keep_constraints=true, bool simplify_combinations=false, bool tseitin_equivalence=true)
Converts the given formula to CNF.
Definition: CNF.h:167
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
Represent an SMT formula, which can be an atom for some background theory or a boolean combination of...
Definition: Formula.h:47
const Formula & subformula() const
Definition: Formula.h:327
carl::Variable::Arg boolean() const
Definition: Formula.h:436
FormulaType type() const
Definition: Formula.h:254
Write formulas to the DIMAS format.
std::size_t id(carl::Variable::Arg v)
std::map< carl::Variable, std::size_t > mVariables
std::vector< std::vector< long long > > mClauses
friend std::ostream & operator<<(std::ostream &os, const DIMACSExporter< P > &de)
bool addDisjunction(const Formula< Pol > &f)
long long getLiteral(const Formula< Pol > &f)
bool operator()(const Formula< Pol > &formula)