SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
LongFormulaEncoder.cpp
Go to the documentation of this file.
1 #include "LongFormulaEncoder.h"
2 
3 namespace smtrat {
4  std::optional<FormulaT> LongFormulaEncoder::doEncode(const ConstraintT& constraint) {
5  const auto& cLHS = constraint.lhs();
6  carl::Relation cRel = constraint.relation();
7  std::set<carl::Variable> cVars = constraint.variables().as_set();
8  Rational cRHS = -constraint.lhs().constant_part();
9  bool positive = true;
10  bool negative = true;
11  Rational sum = 0;
12 
13  for(const auto& it : cLHS){
14  if (it.is_constant()) continue;
15 
16  if(it.coeff() < 0){
17  positive = false;
18  }else if(it.coeff() > 0){
19  negative = false;
20  }
21  sum += it.coeff();
22  }
23 
24  if(positive && cRel == carl::Relation::LEQ){
25  if(cRHS < 0){
26  //5 x1 +2 x2 +3 x3 <= -5 or 5 x1 +2 x2 +3 x3 < -5 ===> FALSE
27  return FormulaT(carl::FormulaType::FALSE);
28  }else if(cRHS == 0){
29  if(cRel == carl::Relation::LEQ){
30  //5 x1 +2 x2 +3 x3 <= 0 ===> (x1 or x2 or x3) -> false
31  FormulaT subformulaA = generateVarChain(cVars, carl::FormulaType::OR);
32  return FormulaT(carl::FormulaType::NOT, subformulaA);
33  }else{ //cRel == carl::Relation::LESS
34  //5 x1 +2 x2 +3 x3 < 0 ===> FALSE
35  return FormulaT(carl::FormulaType::FALSE);
36  }
37  }else{ //cRHS > 0
38  if(sum == cRHS && cRel == carl::Relation::LEQ){
39  //5 x1 +2 x2 +3 x3 <= 10 ===> false -> x1 and x2 and x3 ===> TRUE
40  return FormulaT(carl::FormulaType::TRUE);
41  }else if(sum == cRHS && cRel == carl::Relation::LESS){
42  //5 x1 +2 x2 +3 x3 < 10 ===> x1 and x2 and x3 -> false
43  FormulaT subformulaA = generateVarChain(cVars, carl::FormulaType::AND);
44  return FormulaT(carl::FormulaType::NOT, subformulaA);
45  }else if(sum < cRHS){
46  //5 x1 +2 x2 +3 x3 <= 20 or 5 x1 +2 x2 +3 x3 < 20 ===> false -> x1 and x2 and x3 ===> TRUE
47  return FormulaT(carl::FormulaType::TRUE);
48  }//sum > cRHS
49  }
50  }else if(negative && cRel == carl::Relation::LEQ){
51  if(cRHS > 0){
52  //-5 x1 -2 x2 -3 x3 <= 5 or -5 x1 -2 x2 -3 x3 < 5 ===> false -> x1 and x2 and x3 ===> TRUE
53  return FormulaT(carl::FormulaType::TRUE);
54  }else if(cRHS == 0){
55  if(cRel == carl::Relation::LEQ){
56  //-5 x1 -2 x2 -3 x3 <= 0 ===> false -> x1 and x2 and x3 ===> TRUE
57  return FormulaT(carl::FormulaType::TRUE);
58  }else{ //cRel == carl::Relation::LESS
59  //-5 x1 -2 x2 -3 x3 < 0 ===> true -> x1 or x2 or x3
61  }
62  }else{ //cRHS < 0
63  if(sum > cRHS){
64  //-5 x1 -2 x2 -3 x3 < -15 or -5 x1 -2 x2 -3 x3 <= -15 ===> FALSE
65  return FormulaT(carl::FormulaType::FALSE);
66  }else if(sum == cRHS && cRel == carl::Relation::LEQ){
67  //-5 x1 -2 x2 -3 x3 <= -10 ===> x1 and x2 and x3 -> false
68  FormulaT subformulaA = generateVarChain(cVars, carl::FormulaType::AND);
69  return FormulaT(carl::FormulaType::NOT, subformulaA);
70  }else if(sum == cRHS && cRel == carl::Relation::LESS){
71  //-5 x1 -2 x2 -3 x3 < -10 ===> FALSE
72  return FormulaT(carl::FormulaType::FALSE);
73  }// sum < cRHS
74  }
75  }else if(cRel == carl::Relation::EQ){
76  if(sum == cRHS){
77  //5 x1 +2 x2 +3 x3 = 10 ===> x1 and x2 and x3
79  }else if(sum != cRHS && cRHS == 0){
80  //5 x1 +2 x2 +3 x3 = 0 ===> (x1 or x2 or x3 -> false)
81  FormulaT subformulaA = generateVarChain(cVars, carl::FormulaType::OR);
82  return FormulaT(carl::FormulaType::NOT, subformulaA);
83  }
84  }else if(cRel == carl::Relation::NEQ){
85  if(sum != cRHS && cRHS == 0){
86  //5 x1 +2 x2 +3 x3 = 0 ===> not(x1 and x2 and x3)
87  FormulaT subformulaA = generateVarChain(cVars, carl::FormulaType::AND);
88  return FormulaT(carl::FormulaType::NOT, subformulaA);
89  }
90  }
91 
92  return {};
93 
94  }
95 
96  bool LongFormulaEncoder::canEncode(const ConstraintT& constraint) {
97  bool positive = true;
98  bool negative = true;
99  bool onlyOnes = true;
100  for (const auto& term : constraint.lhs()) {
101  if (term.is_constant()) continue;
102 
103  if (carl::abs(term.coeff()) > 1) {
104  onlyOnes = false;
105  }
106 
107  if (term.coeff() > 0) {
108  negative = false;
109  } else if (term.coeff() < 0) {
110  positive = false;
111  }
112  }
113 
114  return positive != negative && !onlyOnes;
115  }
116 
118  if (!canEncode(constraint)) return PseudoBoolEncoder::encodingSize(constraint);
119 
120  return 1;
121  }
122 }
std::optional< FormulaT > doEncode(const ConstraintT &constraint)
Rational encodingSize(const ConstraintT &constraint)
bool canEncode(const ConstraintT &constraint)
virtual Rational encodingSize(const ConstraintT &constraint)
FormulaT generateVarChain(const std::set< carl::Variable > &vars, carl::FormulaType type)
Numeric abs(const Numeric &_value)
Calculates the absolute value of the given Numeric.
Definition: Numeric.cpp:276
Class to create the formulas for axioms.
carl::Formula< Poly > FormulaT
Definition: types.h:37
carl::Constraint< Poly > ConstraintT
Definition: types.h:29
mpq_class Rational
Definition: types.h:19