1 2 /* 3 * File Constraint.hpp. 4 * 5 * This file is part of the source code of the software program 6 * Vampire. It is protected by applicable 7 * copyright laws. 8 * 9 * This source code is distributed under the licence found here 10 * https://vprover.github.io/license.html 11 * and in the source directory 12 * 13 * In summary, you are allowed to use Vampire for non-commercial 14 * purposes but not allowed to distribute, modify, copy, create derivatives, 15 * or use in competitions. 16 * For other uses of Vampire please contact developers for a different 17 * licence, which we will make an effort to provide. 18 */ 19 /** 20 * @file Kernel/Constraint.hpp 21 * Defines class Constraint. 22 */ 23 24 #ifndef __Constraint__ 25 #define __Constraint__ 26 #if GNUMP 27 28 #include "Forwards.hpp" 29 30 #include "Lib/Allocator.hpp" 31 #include "Lib/DArray.hpp" 32 33 #include "Number.hpp" 34 35 namespace Kernel { 36 37 enum ConstraintType { 38 CT_GR, 39 CT_GREQ, 40 CT_EQ 41 }; 42 43 /** 44 * Constraint object 45 * 46 * Object represents a constraint 47 * 48 * c0*x0 + ... + cN*xN # C 49 * 50 * where c0,x0,...cN,xN come from the @c _coeffs array, C is equal to @c _constVat 51 * and # is either >, >= or =, depending on @c _type. 52 * 53 * The coefficients are sorted in ascending order by variable number. 54 */ 55 class Constraint { 56 public: 57 58 struct Coeff { CoeffKernel::Constraint::Coeff59 Coeff() {} CoeffKernel::Constraint::Coeff60 Coeff(Var var, const CoeffNumber& value) : var(var), value(value) {} 61 isPositiveKernel::Constraint::Coeff62 bool isPositive() const { return value.isPositiveAssumingNonzero(); } isNegativeKernel::Constraint::Coeff63 bool isNegative() const { return value.isNegativeAssumingNonzero(); } 64 operator ==Kernel::Constraint::Coeff65 bool operator==(const Coeff& o) const 66 { return var==o.var && value==o.value; } operator !=Kernel::Constraint::Coeff67 bool operator!=(const Coeff& o) const 68 { return !(*this==o); } 69 70 static unsigned hash(const Coeff& c); 71 72 Var var; 73 CoeffNumber value; 74 }; 75 typedef DArray<Coeff> CoeffArray; 76 typedef DArray<Coeff>::Iterator CoeffIterator; 77 freeCoeff() const78 const CoeffNumber& freeCoeff() const { return _freeCoeff; } type() const79 ConstraintType type() const { return _type; } setType(ConstraintType t)80 void setType(ConstraintType t) { _type = t; } 81 82 /** 83 * Return true if constraint was generated as a collapsing constraint. 84 * 85 * Input constraints can too appear as collapsing constraints, but 86 * for those the mark is not set. 87 */ collapsing() const88 bool collapsing() const { return _collapsing; } markCollapsing()89 void markCollapsing() { ASS(!_collapsing); _collapsing = true; } 90 coeffCnt() const91 size_t coeffCnt() const { return _coeffs.size(); } 92 CoeffIterator coeffs() const; coeffArray() const93 const CoeffArray& coeffArray() const { return _coeffs; } operator [](unsigned i) const94 const Coeff& operator[](unsigned i) const { return _coeffs[i]; } 95 int getVarIdx(Var v) const; 96 bool hasVar(Var v) const; 97 const Coeff& getCoeff(Var v) const; 98 99 void multiplyCoeffs(CoeffNumber num); 100 void reduce(bool allowDecimals=true); 101 isEquality() const102 bool isEquality() const { return type()==CT_EQ; } 103 isTautology() const104 bool isTautology() const { 105 ASS(!isEquality()); 106 return coeffCnt()==0 107 && (freeCoeff().isNegative() || (freeCoeff().isZero() && type()==CT_GREQ)); 108 } 109 isRefutation() const110 bool isRefutation() const { 111 ASS(!isEquality()); 112 return coeffCnt()==0 113 && (freeCoeff().isPositive() || (freeCoeff().isZero() && type()==CT_GR)); 114 } 115 116 vstring toString() const; 117 incRefCnt()118 void incRefCnt() { _refCnt++; } decRefCnt()119 void decRefCnt() { 120 _refCnt--; 121 if(_refCnt==0) { 122 delete this; 123 } 124 } 125 126 bool operator==(const Constraint& o) const; operator !=(const Constraint & o) const127 bool operator!=(const Constraint& o) const 128 { return !(*this==o); } 129 private: 130 /** 131 * Comparator that allows to order coeffitients by their variable 132 * number (in ascending number) 133 */ 134 struct CoeffComparator { compareKernel::Constraint::CoeffComparator135 Comparison compare(Coeff& c1, Coeff& c2) { 136 return DefaultComparatorTKV::compare(c1.var, c2.var); 137 } 138 }; 139 public: 140 141 /** 142 * Create a constraint of type @c t, with coefficients from @c coeffIterator and with 143 * the constant value @c constVal. Each variable can appear only once among the 144 * coefficients. Coefficients must be non-zero. 145 */ 146 template<class Iter> fromIterator(ConstraintType t,Iter coeffIterator,const CoeffNumber & freeCoeff)147 static Constraint* fromIterator(ConstraintType t, Iter coeffIterator, const CoeffNumber& freeCoeff) 148 { 149 CALL("Constraint::fromIterator"); 150 151 Constraint* res = new Constraint(); 152 res->_coeffs.initFromIterator(coeffIterator); 153 res->_freeCoeff = freeCoeff; 154 res->_type = t; 155 156 res->_coeffs.sort(CoeffComparator()); 157 158 #if VDEBUG 159 for(size_t i=0; i<res->_coeffs.size(); i++) { 160 if(i>0) { 161 ASS_G(res->_coeffs[i].var,res->_coeffs[i-1].var); 162 } 163 ASS_REP2(!res->_coeffs[i].value.isZero(), res->toString(), i); 164 } 165 #endif 166 167 return res; 168 } 169 170 /** 171 * Create a constraint of type @c t, with coeffitients from @c coeffIterator and with 172 * the constant value @c constVal. Variables are allowed to appear multiple times among 173 * the coeffitients. 174 */ 175 template<class Iter> fromBagIterator(ConstraintType t,Iter coeffIterator,const CoeffNumber & freeCoeff)176 static Constraint* fromBagIterator(ConstraintType t, Iter coeffIterator, const CoeffNumber& freeCoeff) 177 { 178 CALL("Constraint::fromBagIterator"); 179 180 static CoeffArray bag; 181 bag.initFromIterator(coeffIterator); 182 bag.sort(CoeffComparator()); 183 184 unsigned bagSize = bag.size(); 185 unsigned rIdx = 1; 186 unsigned wIdx = 0; 187 while(rIdx<bagSize) { 188 ASS_L(wIdx, rIdx); 189 if(bag[wIdx].var==bag[rIdx].var) { 190 bag[wIdx].value+=bag[rIdx].value; 191 } 192 else { 193 ASS_L(bag[wIdx].var,bag[rIdx].var); 194 if(!bag[wIdx].value.isZero()) { 195 wIdx++; 196 } 197 if(wIdx!=rIdx) { 198 bag[wIdx]=bag[rIdx]; 199 } 200 } 201 rIdx++; 202 } 203 if(bag[wIdx].value.isZero()) { 204 bag.shrink(wIdx); 205 } 206 else { 207 bag.shrink(wIdx+1); 208 } 209 return fromSortedIterator(t, CoeffArray::Iterator(bag), freeCoeff); 210 } 211 212 /** 213 * Create a constraint of type @c t, with coeffitients from @c coeffIterator and with 214 * the constant value @c constVal. The coeffitients in @c coeffIterator must be in 215 * ascending order. Each variable can appear only once among the coeffitients. 216 * Coeffitients must be non-zero. 217 */ 218 template<class Iter> fromSortedIterator(ConstraintType t,Iter coeffIterator,const CoeffNumber & freeCoeff)219 static Constraint* fromSortedIterator(ConstraintType t, Iter coeffIterator, const CoeffNumber& freeCoeff) 220 { 221 CALL("Constraint::fromSortedIterator"); 222 223 Constraint* res = new Constraint(); 224 res->_coeffs.initFromIterator(coeffIterator); 225 res->_freeCoeff = freeCoeff; 226 res->_type = t; 227 228 #if VDEBUG 229 for(size_t i=0; i<res->_coeffs.size(); i++) { 230 if(i>0) { 231 ASS_G(res->_coeffs[i].var, res->_coeffs[i-1].var); 232 } 233 ASS_REP2(!res->_coeffs[i].value.isZero(), res->toString(), i); 234 } 235 #endif 236 237 return res; 238 } 239 240 static Constraint* resolve(Var resolvedVar, Constraint& c1, Constraint& c2, 241 bool allowDecimalCoeffitiets=true); 242 static Constraint* clone(Constraint& c); 243 244 CLASS_NAME("Constraint"); 245 USE_ALLOCATOR(Constraint); 246 private: Constraint()247 Constraint() : _collapsing(false), _refCnt(0) {} 248 249 /** Coeffitients with variables in ascending order */ 250 CoeffArray _coeffs; 251 CoeffNumber _freeCoeff; 252 ConstraintType _type; 253 /** 254 * @see collapsing() 255 */ 256 bool _collapsing; 257 unsigned _refCnt; 258 }; 259 260 } 261 #endif //GNUMP 262 #endif // __Constraint__ 263