SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
ExactlyOneCommanderEncoder.cpp
Go to the documentation of this file.
2 
3 namespace smtrat {
4 
5  // https://github.com/Z3Prover/z3/issues/755 show experiments which state that a group size of 4 is optimal.
6  static constexpr int COMMANDER_GROUP_SIZE = 4;
7 
9  if (!canEncode(constraint)) return PseudoBoolEncoder::encodingSize(constraint);
10 
11  // groups * (vars * (vars + 1)/2) + 1
12  size_t nVars = constraint.variables().size();
13 
14  return 4 * (nVars * (nVars + 1))/2 + 1;
15  }
16 
18  if (constraint.relation() != carl::Relation::EQ) return false;
19  if (constraint.variables().size() <= COMMANDER_GROUP_SIZE) return false;
20 
21  for (const auto &term : constraint.lhs()) {
22  if (term.is_constant()) continue;
23 
24  if (term.coeff() != Rational(1)) {
25  return false;
26  }
27  }
28 
29  return constraint.lhs().constant_part() == Rational(-1);
30  }
31 
32  std::optional<FormulaT> ExactlyOneCommanderEncoder::doEncode(const ConstraintT& constraint) {
33  assert(canEncode(constraint));
34 
35  // 1. partition into groups of (mostly) equal size and introduce a group commander variable (bool)
36  std::map<carl::Variable, std::vector<carl::Variable>> commanderPartitions = partition(constraint.variables().as_set());
37 
39  std::vector<carl::Variable> commanders;
40  for (const auto& entry : commanderPartitions) {
41  carl::Variable commander = entry.first;
42  commanders.push_back(commander);
43  std::vector<carl::Variable> group = entry.second;
44 
45  // 2. atmost one variable in the group is true
46  for (size_t i = 0; i < group.size(); i++) {
47  for (size_t j = 0; j < i; j++) {
48  // group_i -> not group_j
49  result.push_back(FormulaT(carl::FormulaType::OR, !FormulaT(group[i]), !FormulaT(group[j])));
50  }
51  }
52 
53  carl::Variables groupVarSet(group.begin(), group.end());
54  // 3. group commander implies atleast 1 of the group true
56 
57  // 4. not group commander implies none true
58  for (size_t i = 0; i < group.size(); i++) {
59  result.push_back(FormulaT(carl::FormulaType::OR, FormulaT(commander), !FormulaT(group[i])));
60  }
61  }
62 
63  // 5. exactly one commander true (recursively or directly via existing encoding)
64  Poly commanderConstraintPoly;
65  commanderConstraintPoly += Rational(-1);
66  for (const auto& cmdVar : commanders) {
67  commanderConstraintPoly += Poly(cmdVar);
68  }
69 
70  ConstraintT commanderConstraint(commanderConstraintPoly, carl::Relation::EQ);
71  result.push_back(*mCardinalityEncoder.encode(commanderConstraint));
72 
74  }
75 
76  std::map<carl::Variable, std::vector<carl::Variable>> ExactlyOneCommanderEncoder::partition(carl::Variables vars) {
77  std::map<carl::Variable, std::vector<carl::Variable>> result;
78 
79  std::vector<carl::Variable> varVector;
80  std::copy(vars.begin(), vars.end(), std::back_inserter(varVector));
81 
82  // initialize result map
83  std::vector<carl::Variable> commanders;
84  for (int i = 0; i < COMMANDER_GROUP_SIZE; i++) {
85  carl::Variable commander = carl::fresh_boolean_variable();
86  commanders.push_back(commander);
87  result[commander] = std::vector<carl::Variable>();
88  }
89 
90  // fill result map
91  for (size_t i = 0; i < varVector.size(); i++) {
92  carl::Variable commander = commanders[i % COMMANDER_GROUP_SIZE];
93  result[commander].push_back(varVector[i]);
94  }
95 
96  return result;
97 
98  }
99 
100 }
std::optional< FormulaT > doEncode(const ConstraintT &constraint)
std::map< carl::Variable, std::vector< carl::Variable > > partition(carl::Variables)
bool canEncode(const ConstraintT &constraint)
Rational encodingSize(const ConstraintT &constraint)
virtual Rational encodingSize(const ConstraintT &constraint)
std::optional< FormulaT > encode(const ConstraintT &constraint)
Encodes an arbitrary constraint.
FormulaT generateVarChain(const std::set< carl::Variable > &vars, carl::FormulaType type)
static void copy(const T &from, T &to)
Definition: Alg.h:60
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Definition: QEQuery.h:43
Class to create the formulas for axioms.
static constexpr int COMMANDER_GROUP_SIZE
carl::Formula< Poly > FormulaT
Definition: types.h:37
carl::MultivariatePolynomial< Rational > Poly
Definition: types.h:25
carl::Constraint< Poly > ConstraintT
Definition: types.h:29
carl::Formulas< Poly > FormulasT
Definition: types.h:39
mpq_class Rational
Definition: types.h:19