LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/arith/linear - constraint.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1081 1461 74.0 %
Date: 2026-01-28 13:01:50 Functions: 92 126 73.0 %
Branches: 773 1717 45.0 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Tim King, Alex Ozdemir, Gereon Kremer
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS
       8                 :            :  * in the top-level source directory and their institutional affiliations.
       9                 :            :  * All rights reserved.  See the file COPYING in the top-level source
      10                 :            :  * directory for licensing information.
      11                 :            :  * ****************************************************************************
      12                 :            :  *
      13                 :            :  * [[ Add one-line brief description here ]]
      14                 :            :  *
      15                 :            :  * [[ Add lengthier description here ]]
      16                 :            :  * \todo document this file
      17                 :            :  */
      18                 :            : #include "theory/arith/linear/constraint.h"
      19                 :            : 
      20                 :            : #include <algorithm>
      21                 :            : #include <ostream>
      22                 :            : #include <unordered_set>
      23                 :            : 
      24                 :            : #include "base/output.h"
      25                 :            : #include "options/smt_options.h"
      26                 :            : #include "proof/eager_proof_generator.h"
      27                 :            : #include "proof/proof_node_manager.h"
      28                 :            : #include "smt/env.h"
      29                 :            : #include "theory/arith/arith_proof_utilities.h"
      30                 :            : #include "theory/arith/arith_utilities.h"
      31                 :            : #include "theory/arith/linear/congruence_manager.h"
      32                 :            : #include "theory/arith/linear/normal_form.h"
      33                 :            : #include "theory/arith/linear/partial_model.h"
      34                 :            : #include "theory/builtin/proof_checker.h"
      35                 :            : #include "theory/rewriter.h"
      36                 :            : 
      37                 :            : using namespace std;
      38                 :            : using namespace cvc5::internal::kind;
      39                 :            : 
      40                 :            : namespace cvc5::internal {
      41                 :            : namespace theory {
      42                 :            : namespace arith::linear {
      43                 :            : 
      44                 :          0 : ConstraintRule::ConstraintRule()
      45                 :            :     : d_constraint(NullConstraint),
      46                 :            :       d_proofType(NoAP),
      47                 :          0 :       d_antecedentEnd(AntecedentIdSentinel)
      48                 :            : {
      49                 :          0 :   d_farkasCoefficients = RationalVectorCPSentinel;
      50                 :          0 : }
      51                 :            : 
      52                 :   10338000 : ConstraintRule::ConstraintRule(ConstraintP con, ArithProofType pt)
      53                 :   10338000 :     : d_constraint(con), d_proofType(pt), d_antecedentEnd(AntecedentIdSentinel)
      54                 :            : {
      55                 :   10338000 :   d_farkasCoefficients = RationalVectorCPSentinel;
      56                 :   10338000 : }
      57                 :    3511010 : ConstraintRule::ConstraintRule(ConstraintP con,
      58                 :            :                                ArithProofType pt,
      59                 :    3511010 :                                AntecedentId antecedentEnd)
      60                 :    3511010 :     : d_constraint(con), d_proofType(pt), d_antecedentEnd(antecedentEnd)
      61                 :            : {
      62                 :    3511010 :   d_farkasCoefficients = RationalVectorCPSentinel;
      63                 :    3511010 : }
      64                 :            : 
      65                 :    3959530 : ConstraintRule::ConstraintRule(ConstraintP con,
      66                 :            :                                ArithProofType pt,
      67                 :            :                                AntecedentId antecedentEnd,
      68                 :    3959530 :                                RationalVectorCP coeffs)
      69                 :    3959530 :     : d_constraint(con), d_proofType(pt), d_antecedentEnd(antecedentEnd)
      70                 :            : {
      71 [ +  + ][ -  + ]:    3959530 :   Assert(con->isProofProducing() || coeffs == RationalVectorCPSentinel);
         [ -  + ][ -  - ]
      72                 :    3959530 :   d_farkasCoefficients = coeffs;
      73                 :    3959530 : }
      74                 :            : 
      75                 :            : /** Given a simplifiedKind this returns the corresponding ConstraintType. */
      76                 :            : //ConstraintType constraintTypeOfLiteral(Kind k);
      77                 :    1166590 : ConstraintType Constraint::constraintTypeOfComparison(const Comparison& cmp){
      78                 :    1166590 :   Kind k = cmp.comparisonKind();
      79 [ +  + ][ +  + ]:    1166590 :   switch(k){
                    [ - ]
      80                 :     316713 :     case Kind::LT:
      81                 :            :     case Kind::LEQ:
      82                 :            :     {
      83                 :     633426 :       Polynomial l = cmp.getLeft();
      84         [ +  + ]:     316713 :       if(l.leadingCoefficientIsPositive()){ // (< x c)
      85                 :     274571 :         return UpperBound;
      86                 :            :       }else{
      87                 :      42142 :         return LowerBound; // (< (-x) c)
      88                 :            :       }
      89                 :            :     }
      90                 :     319416 :     case Kind::GT:
      91                 :            :     case Kind::GEQ:
      92                 :            :     {
      93                 :     638832 :       Polynomial l = cmp.getLeft();
      94         [ +  + ]:     319416 :       if(l.leadingCoefficientIsPositive()){
      95                 :     276911 :         return LowerBound; // (> x c)
      96                 :            :       }else{
      97                 :      42505 :         return UpperBound; // (> (-x) c)
      98                 :            :       }
      99                 :            :     }
     100                 :     265475 :     case Kind::EQUAL: return Equality;
     101                 :     264983 :     case Kind::DISTINCT: return Disequality;
     102                 :          0 :     default: Unhandled() << k;
     103                 :            :   }
     104                 :            : }
     105                 :            : 
     106                 :    1476240 : Constraint::Constraint(ArithVar x,
     107                 :            :                        ConstraintType t,
     108                 :            :                        const DeltaRational& v,
     109                 :    1476240 :                        bool produceProofs)
     110                 :            :     : d_variable(x),
     111                 :            :       d_type(t),
     112                 :            :       d_value(v),
     113                 :            :       d_database(NULL),
     114                 :            :       d_literal(Node::null()),
     115                 :            :       d_negation(NullConstraint),
     116                 :            :       d_canBePropagated(false),
     117                 :            :       d_assertionOrder(AssertionOrderSentinel),
     118                 :            :       d_witness(TNode::null()),
     119                 :            :       d_crid(ConstraintRuleIdSentinel),
     120                 :            :       d_split(false),
     121                 :            :       d_variablePosition(),
     122                 :    1476240 :       d_produceProofs(produceProofs)
     123                 :            : {
     124 [ -  + ][ -  + ]:    1476240 :   Assert(!initialized());
                 [ -  - ]
     125                 :    1476240 : }
     126                 :            : 
     127                 :            : 
     128                 :          0 : std::ostream& operator<<(std::ostream& o, const ArithProofType apt){
     129 [ -  - ][ -  - ]:          0 :   switch(apt){
         [ -  - ][ -  - ]
                    [ - ]
     130                 :          0 :   case NoAP:  o << "NoAP"; break;
     131                 :          0 :   case AssumeAP:  o << "AssumeAP"; break;
     132                 :          0 :   case InternalAssumeAP:  o << "InternalAssumeAP"; break;
     133                 :          0 :   case FarkasAP:  o << "FarkasAP"; break;
     134                 :          0 :   case TrichotomyAP:  o << "TrichotomyAP"; break;
     135                 :          0 :   case EqualityEngineAP:  o << "EqualityEngineAP"; break;
     136                 :          0 :   case IntTightenAP: o << "IntTightenAP"; break;
     137                 :          0 :   case IntHoleAP: o << "IntHoleAP"; break;
     138                 :          0 :   default: break;
     139                 :            :   }
     140                 :          0 :   return o;
     141                 :            : }
     142                 :            : 
     143                 :          0 : std::ostream& operator<<(std::ostream& o, const ConstraintCP c){
     144         [ -  - ]:          0 :   if(c == NullConstraint){
     145                 :          0 :     return o << "NullConstraint";
     146                 :            :   }else{
     147                 :          0 :     return o << *c;
     148                 :            :   }
     149                 :            : }
     150                 :            : 
     151                 :          0 : std::ostream& operator<<(std::ostream& o, const ConstraintP c){
     152         [ -  - ]:          0 :   if(c == NullConstraint){
     153                 :          0 :     return o << "NullConstraint";
     154                 :            :   }else{
     155                 :          0 :     return o << *c;
     156                 :            :   }
     157                 :            : }
     158                 :            : 
     159                 :          0 : std::ostream& operator<<(std::ostream& o, const ConstraintType t){
     160 [ -  - ][ -  - ]:          0 :   switch(t){
                    [ - ]
     161                 :          0 :   case LowerBound:
     162                 :          0 :     return o << ">=";
     163                 :          0 :   case UpperBound:
     164                 :          0 :     return o << "<=";
     165                 :          0 :   case Equality:
     166                 :          0 :     return o << "=";
     167                 :          0 :   case Disequality:
     168                 :          0 :     return o << "!=";
     169                 :          0 :   default:
     170                 :          0 :     Unreachable();
     171                 :            :   }
     172                 :            : }
     173                 :            : 
     174                 :          0 : std::ostream& operator<<(std::ostream& o, const Constraint& c){
     175                 :          0 :   o << c.getVariable() << ' ' << c.getType() << ' ' << c.getValue();
     176         [ -  - ]:          0 :   if(c.hasLiteral()){
     177                 :          0 :     o << "(node " << c.getLiteral() << ')';
     178                 :            :   }
     179                 :          0 :   return o;
     180                 :            : }
     181                 :            : 
     182                 :          0 : std::ostream& operator<<(std::ostream& o, const ValueCollection& vc){
     183                 :          0 :   o << "{";
     184                 :          0 :   bool pending = false;
     185         [ -  - ]:          0 :   if(vc.hasEquality()){
     186                 :          0 :     o << "eq: " << vc.getEquality();
     187                 :          0 :     pending = true;
     188                 :            :   }
     189         [ -  - ]:          0 :   if(vc.hasLowerBound()){
     190         [ -  - ]:          0 :     if(pending){
     191                 :          0 :       o << ", ";
     192                 :            :     }
     193                 :          0 :     o << "lb: " << vc.getLowerBound();
     194                 :          0 :     pending = true;
     195                 :            :   }
     196         [ -  - ]:          0 :   if(vc.hasUpperBound()){
     197         [ -  - ]:          0 :     if(pending){
     198                 :          0 :       o << ", ";
     199                 :            :     }
     200                 :          0 :     o << "ub: " << vc.getUpperBound();
     201                 :          0 :     pending = true;
     202                 :            :   }
     203         [ -  - ]:          0 :   if(vc.hasDisequality()){
     204         [ -  - ]:          0 :     if(pending){
     205                 :          0 :       o << ", ";
     206                 :            :     }
     207                 :          0 :     o << "de: " << vc.getDisequality();
     208                 :            :   }
     209                 :          0 :   return o << "}";
     210                 :            : }
     211                 :            : 
     212                 :          0 : std::ostream& operator<<(std::ostream& o, const ConstraintCPVec& v){
     213                 :          0 :   o << "[" << v.size() << "x";
     214                 :          0 :   ConstraintCPVec::const_iterator i, end;
     215         [ -  - ]:          0 :   for(i=v.begin(), end=v.end(); i != end; ++i){
     216                 :          0 :     ConstraintCP c = *i;
     217                 :          0 :     o << ", " << (*c);
     218                 :            :   }
     219                 :          0 :   o << "]";
     220                 :          0 :   return o;
     221                 :            : }
     222                 :            : 
     223                 :    4629050 : ValueCollection::ValueCollection()
     224                 :            :   : d_lowerBound(NullConstraint),
     225                 :            :     d_upperBound(NullConstraint),
     226                 :            :     d_equality(NullConstraint),
     227                 :    4629050 :     d_disequality(NullConstraint)
     228                 :    4629050 : {}
     229                 :            : 
     230                 :   34411200 : bool ValueCollection::hasLowerBound() const{
     231                 :   34411200 :   return d_lowerBound != NullConstraint;
     232                 :            : }
     233                 :            : 
     234                 :   37770600 : bool ValueCollection::hasUpperBound() const{
     235                 :   37770600 :   return d_upperBound != NullConstraint;
     236                 :            : }
     237                 :            : 
     238                 :   10573400 : bool ValueCollection::hasEquality() const{
     239                 :   10573400 :   return d_equality != NullConstraint;
     240                 :            : }
     241                 :            : 
     242                 :   30771200 : bool ValueCollection::hasDisequality() const {
     243                 :   30771200 :   return d_disequality != NullConstraint;
     244                 :            : }
     245                 :            : 
     246                 :    6467080 : ConstraintP ValueCollection::getLowerBound() const {
     247 [ -  + ][ -  + ]:    6467080 :   Assert(hasLowerBound());
                 [ -  - ]
     248                 :    6467080 :   return d_lowerBound;
     249                 :            : }
     250                 :            : 
     251                 :    6847260 : ConstraintP ValueCollection::getUpperBound() const {
     252 [ -  + ][ -  + ]:    6847260 :   Assert(hasUpperBound());
                 [ -  - ]
     253                 :    6847260 :   return d_upperBound;
     254                 :            : }
     255                 :            : 
     256                 :     996545 : ConstraintP ValueCollection::getEquality() const {
     257 [ -  + ][ -  + ]:     996545 :   Assert(hasEquality());
                 [ -  - ]
     258                 :     996545 :   return d_equality;
     259                 :            : }
     260                 :            : 
     261                 :    4207830 : ConstraintP ValueCollection::getDisequality() const {
     262 [ -  + ][ -  + ]:    4207830 :   Assert(hasDisequality());
                 [ -  - ]
     263                 :    4207830 :   return d_disequality;
     264                 :            : }
     265                 :            : 
     266                 :            : 
     267                 :    1004920 : void ValueCollection::push_into(std::vector<ConstraintP>& vec) const {
     268         [ +  - ]:    1004920 :   Trace("arith::constraint") << "push_into " << *this << endl;
     269         [ +  + ]:    1004920 :   if(hasEquality()){
     270                 :     274029 :     vec.push_back(d_equality);
     271                 :            :   }
     272         [ +  + ]:    1004920 :   if(hasLowerBound()){
     273                 :     462085 :     vec.push_back(d_lowerBound);
     274                 :            :   }
     275         [ +  + ]:    1004920 :   if(hasUpperBound()){
     276                 :     462085 :     vec.push_back(d_upperBound);
     277                 :            :   }
     278         [ +  + ]:    1004920 :   if(hasDisequality()){
     279                 :     274029 :     vec.push_back(d_disequality);
     280                 :            :   }
     281                 :    1004920 : }
     282                 :            : 
     283                 :          0 : ValueCollection ValueCollection::mkFromConstraint(ConstraintP c){
     284                 :          0 :   ValueCollection ret;
     285                 :          0 :   Assert(ret.empty());
     286 [ -  - ][ -  - ]:          0 :   switch(c->getType()){
                    [ - ]
     287                 :          0 :   case LowerBound:
     288                 :          0 :     ret.d_lowerBound = c;
     289                 :          0 :     break;
     290                 :          0 :   case UpperBound:
     291                 :          0 :     ret.d_upperBound = c;
     292                 :          0 :     break;
     293                 :          0 :   case Equality:
     294                 :          0 :     ret.d_equality = c;
     295                 :          0 :     break;
     296                 :          0 :   case Disequality:
     297                 :          0 :     ret.d_disequality = c;
     298                 :          0 :     break;
     299                 :          0 :   default:
     300                 :          0 :     Unreachable();
     301                 :            :   }
     302                 :          0 :   return ret;
     303                 :            : }
     304                 :            : 
     305                 :    7771780 : bool ValueCollection::hasConstraintOfType(ConstraintType t) const{
     306 [ +  + ][ +  - ]:    7771780 :   switch(t){
                    [ - ]
     307                 :    2536120 :   case LowerBound:
     308                 :    2536120 :     return hasLowerBound();
     309                 :    4140890 :   case UpperBound:
     310                 :    4140890 :     return hasUpperBound();
     311                 :    1094770 :   case Equality:
     312                 :    1094770 :     return hasEquality();
     313                 :          0 :   case Disequality:
     314                 :          0 :     return hasDisequality();
     315                 :          0 :   default:
     316                 :          0 :     Unreachable();
     317                 :            :   }
     318                 :            : }
     319                 :            : 
     320                 :     482594 : ArithVar ValueCollection::getVariable() const{
     321 [ -  + ][ -  + ]:     482594 :   Assert(!empty());
                 [ -  - ]
     322                 :     482594 :   return nonNull()->getVariable();
     323                 :            : }
     324                 :            : 
     325                 :     482594 : const DeltaRational& ValueCollection::getValue() const{
     326 [ -  + ][ -  + ]:     482594 :   Assert(!empty());
                 [ -  - ]
     327                 :     482594 :   return nonNull()->getValue();
     328                 :            : }
     329                 :            : 
     330                 :    1473040 : void ValueCollection::add(ConstraintP c){
     331 [ -  + ][ -  + ]:    1473040 :   Assert(c != NullConstraint);
                 [ -  - ]
     332                 :            : 
     333 [ +  + ][ -  + ]:    1473040 :   Assert(empty() || getVariable() == c->getVariable());
         [ -  + ][ -  - ]
     334 [ +  + ][ -  + ]:    1473040 :   Assert(empty() || getValue() == c->getValue());
         [ -  + ][ -  - ]
     335                 :            : 
     336 [ +  + ][ +  + ]:    1473040 :   switch(c->getType()){
                    [ - ]
     337                 :     462400 :   case LowerBound:
     338 [ -  + ][ -  + ]:     462400 :     Assert(!hasLowerBound());
                 [ -  - ]
     339                 :     462400 :     d_lowerBound = c;
     340                 :     462400 :     break;
     341                 :     274120 :   case Equality:
     342 [ -  + ][ -  + ]:     274120 :     Assert(!hasEquality());
                 [ -  - ]
     343                 :     274120 :     d_equality = c;
     344                 :     274120 :     break;
     345                 :     462400 :   case UpperBound:
     346 [ -  + ][ -  + ]:     462400 :     Assert(!hasUpperBound());
                 [ -  - ]
     347                 :     462400 :     d_upperBound = c;
     348                 :     462400 :     break;
     349                 :     274120 :   case Disequality:
     350 [ -  + ][ -  + ]:     274120 :     Assert(!hasDisequality());
                 [ -  - ]
     351                 :     274120 :     d_disequality = c;
     352                 :     274120 :     break;
     353                 :          0 :   default:
     354                 :          0 :     Unreachable();
     355                 :            :   }
     356                 :    1473040 : }
     357                 :            : 
     358                 :    5828100 : ConstraintP ValueCollection::getConstraintOfType(ConstraintType t) const{
     359 [ +  + ][ +  - ]:    5828100 :   switch(t){
                    [ - ]
     360 [ -  + ][ -  + ]:    1529930 :     case LowerBound: Assert(hasLowerBound()); return d_lowerBound;
                 [ -  - ]
     361 [ -  + ][ -  + ]:     820654 :     case Equality: Assert(hasEquality()); return d_equality;
                 [ -  - ]
     362 [ -  + ][ -  + ]:    3477520 :     case UpperBound: Assert(hasUpperBound()); return d_upperBound;
                 [ -  - ]
     363                 :          0 :     case Disequality: Assert(hasDisequality()); return d_disequality;
     364                 :          0 :     default: Unreachable();
     365                 :            :   }
     366                 :            : }
     367                 :            : 
     368                 :    1472230 : void ValueCollection::remove(ConstraintType t){
     369 [ +  + ][ +  + ]:    1472230 :   switch(t){
                    [ - ]
     370                 :     462085 :   case LowerBound:
     371 [ -  + ][ -  + ]:     462085 :     Assert(hasLowerBound());
                 [ -  - ]
     372                 :     462085 :     d_lowerBound = NullConstraint;
     373                 :     462085 :     break;
     374                 :     274029 :   case Equality:
     375 [ -  + ][ -  + ]:     274029 :     Assert(hasEquality());
                 [ -  - ]
     376                 :     274029 :     d_equality = NullConstraint;
     377                 :     274029 :     break;
     378                 :     462085 :   case UpperBound:
     379 [ -  + ][ -  + ]:     462085 :     Assert(hasUpperBound());
                 [ -  - ]
     380                 :     462085 :     d_upperBound = NullConstraint;
     381                 :     462085 :     break;
     382                 :     274029 :   case Disequality:
     383 [ -  + ][ -  + ]:     274029 :     Assert(hasDisequality());
                 [ -  - ]
     384                 :     274029 :     d_disequality = NullConstraint;
     385                 :     274029 :     break;
     386                 :          0 :   default:
     387                 :          0 :     Unreachable();
     388                 :            :   }
     389                 :    1472230 : }
     390                 :            : 
     391                 :    5383500 : bool ValueCollection::empty() const{
     392                 :            :   return
     393         [ +  + ]:    9993100 :     !(hasLowerBound() ||
     394         [ +  + ]:    4609600 :       hasUpperBound() ||
     395         [ +  + ]:    4419060 :       hasEquality() ||
     396         [ +  - ]:    8399450 :       hasDisequality());
     397                 :            : }
     398                 :            : 
     399                 :     965188 : ConstraintP ValueCollection::nonNull() const{
     400                 :            :   //This can be optimized by caching, but this is not necessary yet!
     401                 :            :   /* "Premature optimization is the root of all evil." */
     402         [ +  + ]:     965188 :   if(hasLowerBound()){
     403                 :     311674 :     return d_lowerBound;
     404         [ +  + ]:     653514 :   }else if(hasUpperBound()){
     405                 :      88978 :     return d_upperBound;
     406         [ +  - ]:     564536 :   }else if(hasEquality()){
     407                 :     564536 :     return d_equality;
     408         [ -  - ]:          0 :   }else if(hasDisequality()){
     409                 :          0 :     return d_disequality;
     410                 :            :   }else{
     411                 :          0 :     return NullConstraint;
     412                 :            :   }
     413                 :            : }
     414                 :            : 
     415                 :    5361290 : bool Constraint::initialized() const {
     416                 :    5361290 :   return d_database != NULL;
     417                 :            : }
     418                 :            : 
     419                 :          0 : const ConstraintDatabase& Constraint::getDatabase() const{
     420                 :          0 :   Assert(initialized());
     421                 :          0 :   return *d_database;
     422                 :            : }
     423                 :            : 
     424                 :    1473040 : void Constraint::initialize(ConstraintDatabase* db, SortedConstraintMapIterator v, ConstraintP negation){
     425 [ -  + ][ -  + ]:    1473040 :   Assert(!initialized());
                 [ -  - ]
     426                 :    1473040 :   d_database = db;
     427                 :    1473040 :   d_variablePosition = v;
     428                 :    1473040 :   d_negation = negation;
     429                 :    1473040 : }
     430                 :            : 
     431                 :    1475420 : Constraint::~Constraint() {
     432                 :            :   // Call this instead of safeToGarbageCollect()
     433 [ -  + ][ -  + ]:    1475420 :   Assert(!contextDependentDataIsSet());
     434                 :            : 
     435         [ +  + ]:    1475420 :   if(initialized()){
     436                 :    1472230 :     ValueCollection& vc =  d_variablePosition->second;
     437         [ +  - ]:    1472230 :     Trace("arith::constraint") << "removing" << vc << endl;
     438                 :            : 
     439                 :    1472230 :     vc.remove(getType());
     440                 :            : 
     441         [ +  + ]:    1472230 :     if(vc.empty()){
     442         [ +  - ]:    1004920 :       Trace("arith::constraint") << "erasing" << vc << endl;
     443                 :    1004920 :       SortedConstraintMap& perVariable = d_database->getVariableSCM(getVariable());
     444                 :    1004920 :       perVariable.erase(d_variablePosition);
     445                 :            :     }
     446                 :            : 
     447         [ +  + ]:    1472230 :     if(hasLiteral()){
     448                 :    1169120 :       d_database->d_nodetoConstraintMap.erase(getLiteral());
     449                 :            :     }
     450                 :            :   }
     451                 :    1475420 : }
     452                 :            : 
     453                 :   48552600 : const ConstraintRule& Constraint::getConstraintRule() const {
     454 [ -  + ][ -  + ]:   48552600 :   Assert(hasProof());
                 [ -  - ]
     455                 :   48552600 :   return d_database->d_watches->d_constraintProofs[d_crid];
     456                 :            : }
     457                 :            : 
     458                 :    6446950 : const ValueCollection& Constraint::getValueCollection() const{
     459                 :    6446950 :   return d_variablePosition->second;
     460                 :            : }
     461                 :            : 
     462                 :            : 
     463                 :     135672 : ConstraintP Constraint::getCeiling() {
     464         [ +  - ]:     135672 :   Trace("getCeiling") << "Constraint_::getCeiling on " << *this << endl;
     465 [ -  + ][ -  + ]:     135672 :   Assert(getValue().getInfinitesimalPart().sgn() > 0);
                 [ -  - ]
     466                 :            : 
     467                 :     407016 :   const DeltaRational ceiling(getValue().ceiling());
     468                 :     271344 :   return d_database->getConstraint(getVariable(), getType(), ceiling);
     469                 :            : }
     470                 :            : 
     471                 :    2601710 : ConstraintP Constraint::getFloor() {
     472 [ -  + ][ -  + ]:    2601710 :   Assert(getValue().getInfinitesimalPart().sgn() < 0);
                 [ -  - ]
     473                 :            : 
     474                 :    7805140 :   const DeltaRational floor(Rational(getValue().floor()));
     475                 :    5203430 :   return d_database->getConstraint(getVariable(), getType(), floor);
     476                 :            : }
     477                 :            : 
     478                 :    1756180 : void Constraint::setCanBePropagated() {
     479 [ -  + ][ -  + ]:    1756180 :   Assert(!canBePropagated());
                 [ -  - ]
     480                 :    1756180 :   d_database->pushCanBePropagatedWatch(this);
     481                 :    1756180 : }
     482                 :            : 
     483                 :   11615400 : void Constraint::setAssertedToTheTheory(TNode witness, bool nowInConflict) {
     484 [ -  + ][ -  + ]:   11615400 :   Assert(hasLiteral());
                 [ -  - ]
     485 [ -  + ][ -  + ]:   11615400 :   Assert(!assertedToTheTheory());
                 [ -  - ]
     486 [ -  + ][ -  + ]:   11615400 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
     487                 :   11615400 :   d_database->pushAssertionOrderWatch(this, witness);
     488                 :            : 
     489                 :   11615400 :   if(TraceIsOn("constraint::conflictCommit") && nowInConflict ){
     490         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "inConflict@setAssertedToTheTheory";
     491         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "\t" << this << std::endl;
     492         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "\t" << getNegation() << std::endl;
     493                 :          0 :     Trace("constraint::conflictCommit") << "\t" << getNegation()->externalExplainByAssertions() << std::endl;
     494                 :            : 
     495                 :            :   }
     496                 :   11615400 : }
     497                 :            : 
     498                 :          0 : bool Constraint::satisfiedBy(const DeltaRational& dr) const {
     499 [ -  - ][ -  - ]:          0 :   switch(getType()){
                    [ - ]
     500                 :          0 :   case LowerBound:
     501                 :          0 :     return getValue() <= dr;
     502                 :          0 :   case Equality:
     503                 :          0 :     return getValue() == dr;
     504                 :          0 :   case UpperBound:
     505                 :          0 :     return getValue() >= dr;
     506                 :          0 :   case Disequality:
     507                 :          0 :     return getValue() != dr;
     508                 :            :   }
     509                 :          0 :   Unreachable();
     510                 :            : }
     511                 :            : 
     512                 :   19729100 : bool Constraint::isInternalAssumption() const {
     513                 :   19729100 :   return getProofType() == InternalAssumeAP;
     514                 :            : }
     515                 :            : 
     516                 :          0 : TrustNode Constraint::externalExplainByAssertions() const
     517                 :            : {
     518                 :          0 :   NodeBuilder nb(d_database->nodeManager(), Kind::AND);
     519                 :          0 :   auto pfFromAssumptions = externalExplain(nb, AssertionOrderSentinel);
     520                 :          0 :   Node exp = mkAndFromBuilder(d_database->nodeManager(), nb);
     521         [ -  - ]:          0 :   if (d_database->isProofEnabled())
     522                 :            :   {
     523                 :          0 :     std::vector<Node> assumptions;
     524         [ -  - ]:          0 :     if (exp.getKind() == Kind::AND)
     525                 :            :     {
     526                 :          0 :       assumptions.insert(assumptions.end(), exp.begin(), exp.end());
     527                 :            :     }
     528                 :            :     else
     529                 :            :     {
     530                 :          0 :       assumptions.push_back(exp);
     531                 :            :     }
     532                 :          0 :     auto pf = d_database->d_pnm->mkScope(pfFromAssumptions, assumptions);
     533                 :          0 :     return d_database->d_pfGen->mkTrustedPropagation(
     534                 :          0 :         getLiteral(), d_database->nodeManager()->mkAnd(assumptions), pf);
     535                 :            :   }
     536                 :          0 :   return TrustNode::mkTrustPropExp(getLiteral(), exp);
     537                 :            : }
     538                 :            : 
     539                 :   21164500 : bool Constraint::isAssumption() const {
     540                 :   21164500 :   return getProofType() == AssumeAP;
     541                 :            : }
     542                 :            : 
     543                 :    1419650 : bool Constraint::hasEqualityEngineProof() const {
     544                 :    1419650 :   return getProofType() == EqualityEngineAP;
     545                 :            : }
     546                 :            : 
     547                 :          0 : bool Constraint::hasFarkasProof() const {
     548                 :          0 :   return getProofType() == FarkasAP;
     549                 :            : }
     550                 :            : 
     551                 :          0 : bool Constraint::hasSimpleFarkasProof() const
     552                 :            : {
     553         [ -  - ]:          0 :   Trace("constraints::hsfp") << "hasSimpleFarkasProof " << this << std::endl;
     554         [ -  - ]:          0 :   if (!hasFarkasProof())
     555                 :            :   {
     556         [ -  - ]:          0 :     Trace("constraints::hsfp") << "There is no simple Farkas proof because "
     557                 :          0 :                                   "there is no farkas proof."
     558                 :          0 :                                << std::endl;
     559                 :          0 :     return false;
     560                 :            :   }
     561                 :            : 
     562                 :            :   // For each antecdent ...
     563                 :          0 :   AntecedentId i = getConstraintRule().d_antecedentEnd;
     564         [ -  - ]:          0 :   for (ConstraintCP a = d_database->getAntecedent(i); a != NullConstraint;
     565                 :          0 :        a = d_database->getAntecedent(--i))
     566                 :            :   {
     567                 :            :     // ... that antecdent must be an assumption OR a tightened assumption ...
     568         [ -  - ]:          0 :     if (a->isPossiblyTightenedAssumption())
     569                 :            :     {
     570                 :          0 :       continue;
     571                 :            :     }
     572                 :            : 
     573                 :            :     // ... otherwise, we do not have a simple Farkas proof.
     574         [ -  - ]:          0 :     if (TraceIsOn("constraints::hsfp"))
     575                 :            :     {
     576         [ -  - ]:          0 :       Trace("constraints::hsfp") << "There is no simple Farkas proof b/c there "
     577                 :          0 :                                     "is an antecdent w/ rule ";
     578         [ -  - ]:          0 :       a->getConstraintRule().print(Trace("constraints::hsfp"), d_produceProofs);
     579         [ -  - ]:          0 :       Trace("constraints::hsfp") << std::endl;
     580                 :            :     }
     581                 :            : 
     582                 :          0 :     return false;
     583                 :            :   }
     584                 :          0 :   return true;
     585                 :            : }
     586                 :            : 
     587                 :          0 : bool Constraint::isPossiblyTightenedAssumption() const
     588                 :            : {
     589                 :            :   // ... that antecdent must be an assumption ...
     590                 :            : 
     591         [ -  - ]:          0 :   if (isAssumption()) return true;
     592         [ -  - ]:          0 :   if (!hasIntTightenProof()) return false;
     593         [ -  - ]:          0 :   if (getConstraintRule().d_antecedentEnd == AntecedentIdSentinel) return false;
     594                 :          0 :   return d_database->getAntecedent(getConstraintRule().d_antecedentEnd)
     595                 :          0 :       ->isAssumption();
     596                 :            : }
     597                 :            : 
     598                 :          0 : bool Constraint::hasIntTightenProof() const {
     599                 :          0 :   return getProofType() == IntTightenAP;
     600                 :            : }
     601                 :            : 
     602                 :          0 : bool Constraint::hasIntHoleProof() const {
     603                 :          0 :   return getProofType() == IntHoleAP;
     604                 :            : }
     605                 :            : 
     606                 :          0 : bool Constraint::hasTrichotomyProof() const {
     607                 :          0 :   return getProofType() == TrichotomyAP;
     608                 :            : }
     609                 :            : 
     610                 :          0 : void Constraint::printProofTree(std::ostream& out, size_t depth) const
     611                 :            : {
     612         [ -  - ]:          0 :   if (d_produceProofs)
     613                 :            :   {
     614                 :          0 :     const ConstraintRule& rule = getConstraintRule();
     615                 :          0 :     out << std::string(2 * depth, ' ') << "* " << getVariable() << " [";
     616                 :          0 :     out << getProofLiteral();
     617         [ -  - ]:          0 :     if (assertedToTheTheory())
     618                 :            :     {
     619                 :          0 :       out << " | wit: " << getWitness();
     620                 :            :     }
     621                 :          0 :     out << "]" << ' ' << getType() << ' ' << getValue() << " ("
     622                 :          0 :         << getProofType() << ")";
     623         [ -  - ]:          0 :     if (getProofType() == FarkasAP)
     624                 :            :     {
     625                 :          0 :       out << " [";
     626                 :          0 :       bool first = true;
     627         [ -  - ]:          0 :       for (const auto& coeff : *rule.d_farkasCoefficients)
     628                 :            :       {
     629         [ -  - ]:          0 :         if (!first)
     630                 :            :         {
     631                 :          0 :           out << ", ";
     632                 :            :         }
     633                 :          0 :         first = false;
     634                 :          0 :         out << coeff;
     635                 :            :       }
     636                 :          0 :       out << "]";
     637                 :            :     }
     638                 :          0 :     out << endl;
     639                 :            : 
     640         [ -  - ]:          0 :     for (AntecedentId i = rule.d_antecedentEnd; i != AntecedentIdSentinel; --i)
     641                 :            :     {
     642                 :          0 :       ConstraintCP antecdent = d_database->getAntecedent(i);
     643         [ -  - ]:          0 :       if (antecdent == NullConstraint)
     644                 :            :       {
     645                 :          0 :         break;
     646                 :            :       }
     647                 :          0 :       antecdent->printProofTree(out, depth + 1);
     648                 :            :     }
     649                 :          0 :     return;
     650                 :            :   }
     651                 :          0 :   out << "Cannot print proof. This is not a proof build." << endl;
     652                 :            : }
     653                 :            : 
     654                 :    1169780 : bool Constraint::sanityChecking(Node n) const {
     655                 :    2339560 :   Comparison cmp = Comparison::parseNormalForm(n);
     656                 :    1169780 :   Kind k = cmp.comparisonKind();
     657                 :    2339560 :   Polynomial pleft = cmp.normalizedVariablePart();
     658 [ +  + ][ +  + ]:    1169780 :   Assert(k == Kind::EQUAL || k == Kind::DISTINCT
         [ -  + ][ -  + ]
                 [ -  - ]
     659                 :            :          || pleft.leadingCoefficientIsPositive());
     660                 :    1169780 :   Assert(
     661                 :            :       k != Kind::EQUAL
     662                 :            :       || Monomial::isMember(n[0].getKind() == Kind::TO_REAL ? n[0][0] : n[0]));
     663                 :    1169780 :   Assert(k != Kind::DISTINCT
     664                 :            :          || Monomial::isMember(n[0][0].getKind() == Kind::TO_REAL ? n[0][0][0]
     665                 :            :                                                                   : n[0][0]));
     666                 :            : 
     667                 :    2339560 :   TNode left = pleft.getNode();
     668                 :    2339560 :   DeltaRational right = cmp.normalizedDeltaRational();
     669                 :            : 
     670                 :    1169780 :   const ArithVariables& avariables = d_database->getArithVariables();
     671                 :            : 
     672         [ +  - ]:    1169780 :   Trace("Constraint::sanityChecking") << cmp.getNode() << endl;
     673         [ +  - ]:    1169780 :   Trace("Constraint::sanityChecking") << k << endl;
     674         [ +  - ]:    1169780 :   Trace("Constraint::sanityChecking") << pleft.getNode() << endl;
     675         [ +  - ]:    1169780 :   Trace("Constraint::sanityChecking") << left << endl;
     676         [ +  - ]:    1169780 :   Trace("Constraint::sanityChecking") << right << endl;
     677         [ +  - ]:    1169780 :   Trace("Constraint::sanityChecking") << getValue() << endl;
     678 [ +  - ][ -  + ]:    1169780 :   Trace("Constraint::sanityChecking") << avariables.hasArithVar(left) << endl;
                 [ -  - ]
     679 [ +  - ][ -  + ]:    1169780 :   Trace("Constraint::sanityChecking") << avariables.asArithVar(left) << endl;
                 [ -  - ]
     680         [ +  - ]:    1169780 :   Trace("Constraint::sanityChecking") << getVariable() << endl;
     681                 :            : 
     682                 :            : 
     683 [ +  - ][ +  - ]:    2339560 :   if(avariables.hasArithVar(left) &&
                 [ -  - ]
     684 [ +  - ][ +  - ]:    2339560 :      avariables.asArithVar(left) == getVariable() &&
         [ +  - ][ -  - ]
     685         [ +  - ]:    1169780 :      getValue() == right){
     686 [ +  + ][ +  - ]:    1169780 :     switch(getType()){
     687                 :     638832 :     case LowerBound:
     688                 :            :     case UpperBound:
     689                 :            :       //Be overapproximate
     690 [ +  - ][ +  + ]:     638832 :       return k == Kind::GT || k == Kind::GEQ || k == Kind::LT || k == Kind::LEQ;
         [ -  + ][ -  - ]
     691                 :     265475 :     case Equality: return k == Kind::EQUAL;
     692                 :     265475 :     case Disequality: return k == Kind::DISTINCT;
     693                 :          0 :     default:
     694                 :          0 :       Unreachable();
     695                 :            :     }
     696                 :            :   }else{
     697                 :          0 :     return false;
     698                 :            :   }
     699                 :            : }
     700                 :            : 
     701                 :          0 : ConstraintCP ConstraintDatabase::getAntecedent (AntecedentId p) const {
     702                 :          0 :   Assert(p < d_antecedents.size());
     703                 :          0 :   return d_antecedents[p];
     704                 :            : }
     705                 :            : 
     706                 :          0 : void ConstraintRule::print(std::ostream& out, bool produceProofs) const
     707                 :            : {
     708         [ -  - ]:          0 :   RationalVectorCP coeffs = produceProofs ? d_farkasCoefficients : nullptr;
     709                 :          0 :   out << "{ConstraintRule, ";
     710                 :          0 :   out << d_constraint << std::endl;
     711                 :          0 :   out << "d_proofType= " << d_proofType << ", " << std::endl;
     712                 :          0 :   out << "d_antecedentEnd= "<< d_antecedentEnd << std::endl;
     713                 :            : 
     714 [ -  - ][ -  - ]:          0 :   if (d_constraint != NullConstraint && d_antecedentEnd != AntecedentIdSentinel)
     715                 :            :   {
     716                 :          0 :     const ConstraintDatabase& database = d_constraint->getDatabase();
     717                 :            : 
     718         [ -  - ]:          0 :     size_t coeffIterator = (coeffs != RationalVectorCPSentinel) ? coeffs->size()-1 : 0;
     719                 :          0 :     AntecedentId p = d_antecedentEnd;
     720                 :            :     // must have at least one antecedent
     721                 :          0 :     ConstraintCP antecedent = database.getAntecedent(p);
     722         [ -  - ]:          0 :     while(antecedent != NullConstraint){
     723         [ -  - ]:          0 :       if(coeffs != RationalVectorCPSentinel){
     724                 :          0 :         out << coeffs->at(coeffIterator);
     725                 :            :       } else {
     726                 :          0 :         out << "_";
     727                 :            :       }
     728                 :          0 :       out << " * (" << *antecedent << ")" << std::endl;
     729                 :            : 
     730                 :          0 :       Assert((coeffs == RationalVectorCPSentinel) || coeffIterator > 0);
     731                 :          0 :       --p;
     732         [ -  - ]:          0 :       coeffIterator = (coeffs != RationalVectorCPSentinel) ? coeffIterator-1 : 0;
     733                 :          0 :       antecedent = database.getAntecedent(p);
     734                 :            :     }
     735         [ -  - ]:          0 :     if(coeffs != RationalVectorCPSentinel){
     736                 :          0 :       out << coeffs->front();
     737                 :            :     } else {
     738                 :          0 :       out << "_";
     739                 :            :     }
     740                 :          0 :     out << " * (" << *(d_constraint->getNegation()) << ")";
     741                 :          0 :     out << " [not d_constraint] " << endl;
     742                 :            :   }
     743                 :          0 :   out << "}";
     744                 :          0 : }
     745                 :            : 
     746                 :    3959530 : bool Constraint::wellFormedFarkasProof(NodeManager* nm) const
     747                 :            : {
     748 [ -  + ][ -  + ]:    3959530 :   Assert(hasProof());
                 [ -  - ]
     749                 :            : 
     750                 :    3959530 :   const ConstraintRule& cr = getConstraintRule();
     751         [ -  + ]:    3959530 :   if(cr.d_constraint != this){ return false; }
     752         [ -  + ]:    3959530 :   if(cr.d_proofType != FarkasAP){ return false; }
     753                 :            : 
     754                 :    3959530 :   AntecedentId p = cr.d_antecedentEnd;
     755                 :            : 
     756                 :            :   // must have at least one antecedent
     757                 :    3959530 :   ConstraintCP antecedent = d_database->d_antecedents[p];
     758         [ -  + ]:    3959530 :   if(antecedent  == NullConstraint) { return false; }
     759                 :            : 
     760         [ +  + ]:    3959530 :   if (!d_produceProofs)
     761                 :            :   {
     762                 :    1171930 :     return cr.d_farkasCoefficients == RationalVectorCPSentinel;
     763                 :            :   }
     764 [ -  + ][ -  + ]:    2787600 :   Assert(d_produceProofs);
                 [ -  - ]
     765                 :            : 
     766         [ -  + ]:    2787600 :   if(cr.d_farkasCoefficients == RationalVectorCPSentinel){ return false; }
     767         [ -  + ]:    2787600 :   if(cr.d_farkasCoefficients->size() < 2){ return false; }
     768                 :            : 
     769                 :    2787600 :   const ArithVariables& vars = d_database->getArithVariables();
     770                 :            : 
     771                 :    5575200 :   DeltaRational rhs(0);
     772                 :    5575200 :   Node lhs = Polynomial::mkZero(nm).getNode();
     773                 :            : 
     774                 :    2787600 :   RationalVector::const_iterator coeffIterator = cr.d_farkasCoefficients->end()-1;
     775                 :    2787600 :   RationalVector::const_iterator coeffBegin = cr.d_farkasCoefficients->begin();
     776                 :            : 
     777         [ +  + ]:    6471120 :   while(antecedent != NullConstraint){
     778                 :    3683520 :     Assert(lhs.isNull() || Polynomial::isMember(lhs));
     779                 :            : 
     780                 :    3683520 :     const Rational& coeff = *coeffIterator;
     781                 :    3683520 :     int coeffSgn = coeff.sgn();
     782                 :            : 
     783                 :    3683520 :     rhs += antecedent->getValue() * coeff;
     784                 :            : 
     785                 :    3683520 :     ArithVar antVar = antecedent->getVariable();
     786 [ +  - ][ +  - ]:    3683520 :     if(!lhs.isNull() && vars.hasNode(antVar)){
                 [ +  - ]
     787                 :    7367030 :       Node antAsNode = vars.asNode(antVar);
     788         [ +  - ]:    3683520 :       if(Polynomial::isMember(antAsNode)){
     789                 :    7367030 :         Polynomial lhsPoly = Polynomial::parsePolynomial(lhs);
     790                 :    7367030 :         Polynomial antPoly = Polynomial::parsePolynomial(antAsNode);
     791                 :    7367030 :         Polynomial sum = lhsPoly + (antPoly * coeff);
     792                 :    3683520 :         lhs = sum.getNode();
     793                 :            :       }else{
     794                 :          0 :         lhs = Node::null();
     795                 :            :       }
     796                 :            :     } else {
     797                 :          0 :       lhs = Node::null();
     798                 :            :     }
     799         [ +  - ]:    3683520 :     Trace("constraints::wffp") << "running sum: " << lhs << " <= " << rhs << endl;
     800                 :            : 
     801 [ +  + ][ +  - ]:    3683520 :     switch( antecedent->getType() ){
     802                 :    1483540 :     case LowerBound:
     803                 :            :       // fc[l] < 0, therefore return false if coeffSgn >= 0
     804         [ -  + ]:    1483540 :       if(coeffSgn >= 0){ return false; }
     805                 :    1483540 :       break;
     806                 :     551089 :     case UpperBound:
     807                 :            :       // fc[u] > 0, therefore return false if coeffSgn <= 0
     808         [ -  + ]:     551089 :       if(coeffSgn <= 0){ return false; }
     809                 :     551089 :       break;
     810                 :    1648890 :     case Equality:
     811         [ -  + ]:    1648890 :       if(coeffSgn == 0) { return false; }
     812                 :    1648890 :       break;
     813                 :          0 :     case Disequality:
     814                 :            :     default:
     815                 :          0 :       return false;
     816                 :            :     }
     817                 :            : 
     818         [ -  + ]:    3683520 :     if(coeffIterator == coeffBegin){ return false; }
     819                 :    3683520 :     --coeffIterator;
     820                 :    3683520 :     --p;
     821                 :    3683520 :     antecedent = d_database->d_antecedents[p];
     822                 :            :   }
     823         [ -  + ]:    2787600 :   if(coeffIterator != coeffBegin){ return false; }
     824                 :            : 
     825                 :    2787600 :   const Rational& firstCoeff = (*coeffBegin);
     826                 :    2787600 :   int firstCoeffSgn = firstCoeff.sgn();
     827                 :    2787600 :   rhs += (getNegation()->getValue()) * firstCoeff;
     828 [ +  - ][ +  - ]:    2787600 :   if(!lhs.isNull() && vars.hasNode(getVariable())){
                 [ +  - ]
     829                 :    5575200 :     Node firstAsNode = vars.asNode(getVariable());
     830         [ +  - ]:    2787600 :     if(Polynomial::isMember(firstAsNode)){
     831                 :    5575200 :       Polynomial lhsPoly = Polynomial::parsePolynomial(lhs);
     832                 :    5575200 :       Polynomial firstPoly = Polynomial::parsePolynomial(firstAsNode);
     833                 :    5575200 :       Polynomial sum = lhsPoly + (firstPoly * firstCoeff);
     834                 :    2787600 :       lhs = sum.getNode();
     835                 :            :     }else{
     836                 :          0 :       lhs = Node::null();
     837                 :            :     }
     838                 :            :   }else{
     839                 :          0 :     lhs = Node::null();
     840                 :            :   }
     841                 :            : 
     842 [ +  + ][ +  - ]:    2787600 :   switch( getNegation()->getType() ){
     843                 :     592720 :   case LowerBound:
     844                 :            :     // fc[l] < 0, therefore return false if coeffSgn >= 0
     845         [ -  + ]:     592720 :     if(firstCoeffSgn >= 0){ return false; }
     846                 :     592720 :     break;
     847                 :    1198830 :   case UpperBound:
     848                 :            :     // fc[u] > 0, therefore return false if coeffSgn <= 0
     849         [ -  + ]:    1198830 :     if(firstCoeffSgn <= 0){ return false; }
     850                 :    1198830 :     break;
     851                 :     996046 :   case Equality:
     852         [ -  + ]:     996046 :     if(firstCoeffSgn == 0) { return false; }
     853                 :     996046 :     break;
     854                 :          0 :   case Disequality:
     855                 :            :   default:
     856                 :          0 :     return false;
     857                 :            :   }
     858         [ +  - ]:    2787600 :   Trace("constraints::wffp") << "final sum: " << lhs << " <= " << rhs << endl;
     859                 :            :   // 0 = lhs <= rhs < 0
     860                 :    5575200 :   return (lhs.isNull() || (Constant::isMember(lhs) && Constant(lhs).isZero()))
     861 [ +  - ][ +  - ]:    5575200 :          && rhs.sgn() < 0;
                 [ +  - ]
     862                 :            : }
     863                 :            : 
     864                 :     154824 : ConstraintP Constraint::makeNegation(ArithVar v,
     865                 :            :                                      ConstraintType t,
     866                 :            :                                      const DeltaRational& r,
     867                 :            :                                      bool produceProofs)
     868                 :            : {
     869 [ +  + ][ +  - ]:     154824 :   switch(t){
                    [ - ]
     870                 :       6427 :   case LowerBound:
     871                 :            :     {
     872 [ -  + ][ -  + ]:       6427 :       Assert(r.infinitesimalSgn() >= 0);
                 [ -  - ]
     873         [ -  + ]:       6427 :       if(r.infinitesimalSgn() > 0){
     874                 :          0 :         Assert(r.getInfinitesimalPart() == 1);
     875                 :            :         // make (not (v > r)), which is (v <= r)
     876                 :          0 :         DeltaRational dropInf(r.getNoninfinitesimalPart(), 0);
     877                 :          0 :         return new Constraint(v, UpperBound, dropInf, produceProofs);
     878                 :            :       }else{
     879 [ -  + ][ -  + ]:       6427 :         Assert(r.infinitesimalSgn() == 0);
                 [ -  - ]
     880                 :            :         // make (not (v >= r)), which is (v < r)
     881                 :       6427 :         DeltaRational addInf(r.getNoninfinitesimalPart(), -1);
     882                 :       6427 :         return new Constraint(v, UpperBound, addInf, produceProofs);
     883                 :            :       }
     884                 :            :     }
     885                 :     139260 :   case UpperBound:
     886                 :            :     {
     887 [ -  + ][ -  + ]:     139260 :       Assert(r.infinitesimalSgn() <= 0);
                 [ -  - ]
     888         [ -  + ]:     139260 :       if(r.infinitesimalSgn() < 0){
     889                 :          0 :         Assert(r.getInfinitesimalPart() == -1);
     890                 :            :         // make (not (v < r)), which is (v >= r)
     891                 :          0 :         DeltaRational dropInf(r.getNoninfinitesimalPart(), 0);
     892                 :          0 :         return new Constraint(v, LowerBound, dropInf, produceProofs);
     893                 :            :       }else{
     894 [ -  + ][ -  + ]:     139260 :         Assert(r.infinitesimalSgn() == 0);
                 [ -  - ]
     895                 :            :         // make (not (v <= r)), which is (v > r)
     896                 :     139260 :         DeltaRational addInf(r.getNoninfinitesimalPart(), 1);
     897                 :     139260 :         return new Constraint(v, LowerBound, addInf, produceProofs);
     898                 :            :       }
     899                 :            :     }
     900                 :       9137 :     case Equality: return new Constraint(v, Disequality, r, produceProofs);
     901                 :          0 :     case Disequality: return new Constraint(v, Equality, r, produceProofs);
     902                 :          0 :     default: Unreachable(); return NullConstraint;
     903                 :            :   }
     904                 :            : }
     905                 :            : 
     906                 :      50287 : ConstraintDatabase::ConstraintDatabase(Env& env,
     907                 :            :                                        const ArithVariables& avars,
     908                 :            :                                        ArithCongruenceManager& cm,
     909                 :            :                                        RaiseConflict raiseConflict,
     910                 :      50287 :                                        EagerProofGenerator* pfGen)
     911                 :            :     : EnvObj(env),
     912                 :            :       d_varDatabases(),
     913                 :            :       d_toPropagate(context()),
     914                 :            :       d_antecedents(context(), false),
     915                 :      50287 :       d_watches(new Watches(context(), userContext())),
     916                 :            :       d_avariables(avars),
     917                 :            :       d_congruenceManager(cm),
     918                 :            :       d_pfGen(pfGen),
     919         [ +  + ]:      50287 :       d_pnm(d_env.isTheoryProofProducing() ? d_env.getProofNodeManager()
     920                 :            :                                            : nullptr),
     921                 :            :       d_raiseConflict(raiseConflict),
     922                 :            :       d_one(1),
     923                 :            :       d_negOne(-1),
     924                 :     150861 :       d_statistics(statisticsRegistry())
     925                 :            : {
     926                 :      50287 : }
     927                 :            : 
     928                 :   14348900 : SortedConstraintMap& ConstraintDatabase::getVariableSCM(ArithVar v) const{
     929 [ -  + ][ -  + ]:   14348900 :   Assert(variableDatabaseIsSetup(v));
                 [ -  - ]
     930                 :   14348900 :   return d_varDatabases[v]->d_constraints;
     931                 :            : }
     932                 :            : 
     933                 :      71094 : void ConstraintDatabase::pushSplitWatch(ConstraintP c){
     934 [ -  + ][ -  + ]:      71094 :   Assert(!c->d_split);
                 [ -  - ]
     935                 :      71094 :   c->d_split = true;
     936                 :      71094 :   d_watches->d_splitWatches.push_back(c);
     937                 :      71094 : }
     938                 :            : 
     939                 :            : 
     940                 :    1756180 : void ConstraintDatabase::pushCanBePropagatedWatch(ConstraintP c){
     941 [ -  + ][ -  + ]:    1756180 :   Assert(!c->d_canBePropagated);
                 [ -  - ]
     942                 :    1756180 :   c->d_canBePropagated = true;
     943                 :    1756180 :   d_watches->d_canBePropagatedWatches.push_back(c);
     944                 :    1756180 : }
     945                 :            : 
     946                 :   11615400 : void ConstraintDatabase::pushAssertionOrderWatch(ConstraintP c, TNode witness){
     947 [ -  + ][ -  + ]:   11615400 :   Assert(!c->assertedToTheTheory());
                 [ -  - ]
     948                 :   11615400 :   c->d_assertionOrder = d_watches->d_assertionOrderWatches.size();
     949                 :   11615400 :   c->d_witness = witness;
     950                 :   11615400 :   d_watches->d_assertionOrderWatches.push_back(c);
     951                 :   11615400 : }
     952                 :            : 
     953                 :            : 
     954                 :   17808600 : void ConstraintDatabase::pushConstraintRule(const ConstraintRule& crp){
     955                 :   17808600 :   ConstraintP c = crp.d_constraint;
     956 [ -  + ][ -  + ]:   17808600 :   Assert(c->d_crid == ConstraintRuleIdSentinel);
                 [ -  - ]
     957 [ -  + ][ -  + ]:   17808600 :   Assert(!c->hasProof());
                 [ -  - ]
     958                 :   17808600 :   c->d_crid = d_watches->d_constraintProofs.size();
     959                 :   17808600 :   d_watches->d_constraintProofs.push_back(crp);
     960                 :   17808600 : }
     961                 :            : 
     962                 :    3581760 : ConstraintP ConstraintDatabase::getConstraint(ArithVar v, ConstraintType t, const DeltaRational& r){
     963                 :            :   //This must always return a constraint.
     964                 :            : 
     965                 :    3581760 :   SortedConstraintMap& scm = getVariableSCM(v);
     966                 :    3581760 :   pair<SortedConstraintMapIterator, bool> insertAttempt;
     967                 :    3581760 :   insertAttempt = scm.insert(make_pair(r, ValueCollection()));
     968                 :            : 
     969                 :    3581760 :   SortedConstraintMapIterator pos = insertAttempt.first;
     970                 :    3581760 :   ValueCollection& vc = pos->second;
     971         [ +  + ]:    3581760 :   if(vc.hasConstraintOfType(t)){
     972                 :    3426930 :     return vc.getConstraintOfType(t);
     973                 :            :   }else{
     974                 :     154824 :     ConstraintP c = new Constraint(v, t, r, options().smt.produceProofs);
     975                 :            :     ConstraintP negC =
     976                 :     154824 :         Constraint::makeNegation(v, t, r, options().smt.produceProofs);
     977                 :            : 
     978                 :     154824 :     SortedConstraintMapIterator negPos;
     979 [ +  + ][ -  + ]:     154824 :     if(t == Equality || t == Disequality){
     980                 :       9137 :       negPos = pos;
     981                 :            :     }else{
     982                 :     145687 :       pair<SortedConstraintMapIterator, bool> negInsertAttempt;
     983                 :     145687 :       negInsertAttempt = scm.insert(make_pair(negC->getValue(), ValueCollection()));
     984 [ -  + ][ -  - ]:     145687 :       Assert(negInsertAttempt.second
         [ -  + ][ -  - ]
     985                 :            :              || !negInsertAttempt.first->second.hasConstraintOfType(
     986                 :            :                  negC->getType()));
     987                 :     145687 :       negPos = negInsertAttempt.first;
     988                 :            :     }
     989                 :            : 
     990                 :     154824 :     c->initialize(this, pos, negC);
     991                 :     154824 :     negC->initialize(this, negPos, c);
     992                 :            : 
     993                 :     154824 :     vc.add(c);
     994                 :     154824 :     negPos->second.add(negC);
     995                 :            : 
     996                 :     154824 :     return c;
     997                 :            :   }
     998                 :            : }
     999                 :            : 
    1000                 :     421789 : ConstraintP ConstraintDatabase::ensureConstraint(ValueCollection& vc, ConstraintType t){
    1001         [ +  + ]:     421789 :   if(vc.hasConstraintOfType(t)){
    1002                 :     406718 :     return vc.getConstraintOfType(t);
    1003                 :            :   }else{
    1004                 :      15071 :     return getConstraint(vc.getVariable(), t, vc.getValue());
    1005                 :            :   }
    1006                 :            : }
    1007                 :            : 
    1008                 :          0 : bool ConstraintDatabase::emptyDatabase(const std::vector<PerVariableDatabase>& vec){
    1009                 :          0 :   std::vector<PerVariableDatabase>::const_iterator first = vec.begin();
    1010                 :          0 :   std::vector<PerVariableDatabase>::const_iterator last = vec.end();
    1011                 :          0 :   return std::find_if(first, last, PerVariableDatabase::IsEmpty) == last;
    1012                 :            : }
    1013                 :            : 
    1014                 :      49942 : ConstraintDatabase::~ConstraintDatabase(){
    1015         [ +  - ]:      49942 :   delete d_watches;
    1016                 :            : 
    1017                 :      49942 :   std::vector<ConstraintP> constraintList;
    1018                 :            : 
    1019         [ +  + ]:     409056 :   while(!d_varDatabases.empty()){
    1020                 :     359114 :     PerVariableDatabase* back = d_varDatabases.back();
    1021                 :            : 
    1022                 :     359114 :     SortedConstraintMap& scm = back->d_constraints;
    1023                 :     359114 :     SortedConstraintMapIterator i = scm.begin(), i_end = scm.end();
    1024         [ +  + ]:    1364040 :     for(; i != i_end; ++i){
    1025                 :    1004920 :       (i->second).push_into(constraintList);
    1026                 :            :     }
    1027         [ +  + ]:    1831340 :     while(!constraintList.empty()){
    1028                 :    1472230 :       ConstraintP c = constraintList.back();
    1029                 :    1472230 :       constraintList.pop_back();
    1030         [ +  - ]:    1472230 :       delete c;
    1031                 :            :     }
    1032 [ -  + ][ -  + ]:     359114 :     Assert(scm.empty());
    1033                 :     359114 :     d_varDatabases.pop_back();
    1034         [ +  - ]:     359114 :     delete back;
    1035                 :            :   }
    1036                 :            : 
    1037 [ -  + ][ -  + ]:      49942 :   Assert(d_nodetoConstraintMap.empty());
    1038                 :      49942 : }
    1039                 :            : 
    1040                 :      50287 : ConstraintDatabase::Statistics::Statistics(StatisticsRegistry& sr)
    1041                 :            :     : d_unatePropagateCalls(
    1042                 :      50287 :         sr.registerInt("theory::arith::cd::unatePropagateCalls")),
    1043                 :            :       d_unatePropagateImplications(
    1044                 :      50287 :           sr.registerInt("theory::arith::cd::unatePropagateImplications"))
    1045                 :            : {
    1046                 :      50287 : }
    1047                 :            : 
    1048                 :          0 : void ConstraintDatabase::deleteConstraintAndNegation(ConstraintP c){
    1049                 :          0 :   Assert(c->safeToGarbageCollect());
    1050                 :          0 :   ConstraintP neg = c->getNegation();
    1051                 :          0 :   Assert(neg->safeToGarbageCollect());
    1052         [ -  - ]:          0 :   delete c;
    1053         [ -  - ]:          0 :   delete neg;
    1054                 :          0 : }
    1055                 :            : 
    1056                 :     363258 : void ConstraintDatabase::addVariable(ArithVar v){
    1057         [ +  + ]:     363258 :   if(d_reclaimable.isMember(v)){
    1058                 :       3925 :     SortedConstraintMap& scm = getVariableSCM(v);
    1059                 :            : 
    1060                 :       7850 :     std::vector<ConstraintP> constraintList;
    1061                 :            : 
    1062         [ -  + ]:       3925 :     for(SortedConstraintMapIterator i = scm.begin(), end = scm.end(); i != end; ++i){
    1063                 :          0 :       (i->second).push_into(constraintList);
    1064                 :            :     }
    1065         [ -  + ]:       3925 :     while(!constraintList.empty()){
    1066                 :          0 :       ConstraintP c = constraintList.back();
    1067                 :          0 :       constraintList.pop_back();
    1068                 :          0 :       Assert(c->safeToGarbageCollect());
    1069         [ -  - ]:          0 :       delete c;
    1070                 :            :     }
    1071 [ -  + ][ -  + ]:       3925 :     Assert(scm.empty());
                 [ -  - ]
    1072                 :            : 
    1073                 :       3925 :     d_reclaimable.remove(v);
    1074                 :            :   }else{
    1075         [ +  - ]:     359333 :     Trace("arith::constraint") << "about to fail" << v << " " << d_varDatabases.size() << endl;
    1076 [ -  + ][ -  + ]:     359333 :     Assert(v == d_varDatabases.size());
                 [ -  - ]
    1077                 :     359333 :     d_varDatabases.push_back(new PerVariableDatabase(v));
    1078                 :            :   }
    1079                 :     363258 : }
    1080                 :            : 
    1081                 :       3943 : void ConstraintDatabase::removeVariable(ArithVar v){
    1082 [ -  + ][ -  + ]:       3943 :   Assert(!d_reclaimable.isMember(v));
                 [ -  - ]
    1083                 :       3943 :   d_reclaimable.add(v);
    1084                 :       3943 : }
    1085                 :            : 
    1086                 :          0 : bool Constraint::safeToGarbageCollect() const{
    1087                 :            :   // Do not call during destructor as getNegation() may be Null by this point
    1088                 :          0 :   Assert(getNegation() != NullConstraint);
    1089 [ -  - ][ -  - ]:          0 :   return !contextDependentDataIsSet() && ! getNegation()->contextDependentDataIsSet();
    1090                 :            : }
    1091                 :            : 
    1092                 :    1475420 : bool Constraint::contextDependentDataIsSet() const{
    1093 [ +  - ][ +  - ]:    1475420 :   return hasProof() || isSplit() || canBePropagated() || assertedToTheTheory();
         [ +  - ][ -  + ]
    1094                 :            : }
    1095                 :            : 
    1096                 :      35547 : TrustNode Constraint::split()
    1097                 :            : {
    1098 [ +  + ][ -  + ]:      35547 :   Assert(isEquality() || isDisequality());
         [ -  + ][ -  - ]
    1099                 :            : 
    1100                 :      35547 :   bool isEq = isEquality();
    1101                 :            : 
    1102         [ +  + ]:      35547 :   ConstraintP eq = isEq ? this : d_negation;
    1103         [ +  + ]:      35547 :   ConstraintP diseq = isEq ? d_negation : this;
    1104                 :            : 
    1105                 :      71094 :   TNode eqNode = eq->getLiteral();
    1106 [ -  + ][ -  + ]:      35547 :   Assert(eqNode.getKind() == Kind::EQUAL);
                 [ -  - ]
    1107                 :      71094 :   TNode lhs = eqNode[0];
    1108                 :      71094 :   TNode rhs = eqNode[1];
    1109                 :            : 
    1110                 :      35547 :   NodeManager* nm = d_database->nodeManager();
    1111                 :     106641 :   Node leqNode = NodeBuilder(nm, Kind::LEQ) << lhs << rhs;
    1112                 :     106641 :   Node ltNode = NodeBuilder(nm, Kind::LT) << lhs << rhs;
    1113                 :     106641 :   Node gtNode = NodeBuilder(nm, Kind::GT) << lhs << rhs;
    1114                 :     106641 :   Node geqNode = NodeBuilder(nm, Kind::GEQ) << lhs << rhs;
    1115                 :            : 
    1116                 :     106641 :   Node lemma = NodeBuilder(nm, Kind::OR) << leqNode << geqNode;
    1117                 :            : 
    1118                 :      35547 :   TrustNode trustedLemma;
    1119         [ +  + ]:      35547 :   if (d_database->isProofEnabled())
    1120                 :            :   {
    1121                 :      24812 :     TypeNode type = lhs.getType();
    1122                 :            :     // Farkas proof that this works.
    1123                 :      24812 :     auto nLeqPf = d_database->d_pnm->mkAssume(leqNode.negate());
    1124                 :      24812 :     auto gtPf = ensurePredTransform(d_database->d_pnm, nLeqPf, gtNode);
    1125                 :      24812 :     auto nGeqPf = d_database->d_pnm->mkAssume(geqNode.negate());
    1126                 :      24812 :     auto ltPf = ensurePredTransform(d_database->d_pnm, nGeqPf, ltNode);
    1127                 :      62030 :     std::vector<Pf> args{gtPf, ltPf};
    1128                 :      74436 :     std::vector<Node> coeffs{nm->mkConstReal(-1), nm->mkConstReal(1)};
    1129                 :      24812 :     std::vector<Node> coeffsUse = getMacroSumUbCoeff(nm, args, coeffs);
    1130                 :      12406 :     auto sumPf = d_database->d_pnm->mkNode(
    1131                 :      24812 :         ProofRule::MACRO_ARITH_SCALE_SUM_UB, args, coeffsUse);
    1132                 :            :     auto botPf =
    1133                 :      24812 :         ensurePredTransform(d_database->d_pnm, sumPf, nm->mkConst(false));
    1134                 :      62030 :     std::vector<Node> a = {leqNode.negate(), geqNode.negate()};
    1135                 :      37218 :     auto notAndNotPf = d_database->d_pnm->mkScope(botPf, a);
    1136                 :            :     // No need to ensure that the expected node aggrees with `a` because we are
    1137                 :            :     // not providing an expected node.
    1138                 :            :     auto orNotNotPf =
    1139                 :      62030 :         d_database->d_pnm->mkNode(ProofRule::NOT_AND, {notAndNotPf}, {});
    1140                 :      12406 :     auto orPf = ensurePredTransform(d_database->d_pnm, orNotNotPf, lemma);
    1141                 :      12406 :     trustedLemma = d_database->d_pfGen->mkTrustNode(lemma, orPf);
    1142                 :            :   }
    1143                 :            :   else
    1144                 :            :   {
    1145                 :      23141 :     trustedLemma = TrustNode::mkTrustLemma(lemma);
    1146                 :            :   }
    1147                 :            : 
    1148                 :      35547 :   eq->d_database->pushSplitWatch(eq);
    1149                 :      35547 :   diseq->d_database->pushSplitWatch(diseq);
    1150                 :            : 
    1151                 :      71094 :   return trustedLemma;
    1152                 :            : }
    1153                 :            : 
    1154                 :    2339560 : bool ConstraintDatabase::hasLiteral(TNode literal) const {
    1155                 :    2339560 :   return lookup(literal) != NullConstraint;
    1156                 :            : }
    1157                 :            : 
    1158                 :     584891 : ConstraintP ConstraintDatabase::addLiteral(TNode literal){
    1159 [ -  + ][ -  + ]:     584891 :   Assert(!hasLiteral(literal));
                 [ -  - ]
    1160                 :     584891 :   bool isNot = (literal.getKind() == Kind::NOT);
    1161         [ -  + ]:    1169780 :   Node atomNode = (isNot ? literal[0] : literal);
    1162                 :    1169780 :   Node negationNode  = atomNode.notNode();
    1163                 :            : 
    1164 [ -  + ][ -  + ]:     584891 :   Assert(!hasLiteral(atomNode));
                 [ -  - ]
    1165 [ -  + ][ -  + ]:     584891 :   Assert(!hasLiteral(negationNode));
                 [ -  - ]
    1166                 :    1169780 :   Comparison posCmp = Comparison::parseNormalForm(atomNode);
    1167                 :            : 
    1168                 :     584891 :   ConstraintType posType = Constraint::constraintTypeOfComparison(posCmp);
    1169                 :            : 
    1170                 :    1169780 :   Polynomial nvp = posCmp.normalizedVariablePart();
    1171                 :     584891 :   ArithVar v = d_avariables.asArithVar(nvp.getNode());
    1172                 :            : 
    1173                 :    1169780 :   DeltaRational posDR = posCmp.normalizedDeltaRational();
    1174                 :            : 
    1175                 :            :   ConstraintP posC =
    1176                 :     584891 :       new Constraint(v, posType, posDR, options().smt.produceProofs);
    1177                 :            : 
    1178         [ +  - ]:     584891 :   Trace("arith::constraint") << "addliteral( literal ->" << literal << ")" << endl;
    1179         [ +  - ]:     584891 :   Trace("arith::constraint") << "addliteral( posC ->" << posC << ")" << endl;
    1180                 :            : 
    1181                 :     584891 :   SortedConstraintMap& scm = getVariableSCM(posC->getVariable());
    1182                 :     584891 :   pair<SortedConstraintMapIterator, bool> insertAttempt;
    1183                 :     584891 :   insertAttempt = scm.insert(make_pair(posC->getValue(), ValueCollection()));
    1184                 :            : 
    1185                 :     584891 :   SortedConstraintMapIterator posI = insertAttempt.first;
    1186                 :            :   // If the attempt succeeds, i points to a new empty ValueCollection
    1187                 :            :   // If the attempt fails, i points to a pre-existing ValueCollection
    1188                 :            : 
    1189         [ +  + ]:     584891 :   if(posI->second.hasConstraintOfType(posC->getType())){
    1190                 :            :     //This is the situation where the ConstraintP exists, but
    1191                 :            :     //the literal has not been  associated with it.
    1192                 :       3195 :     ConstraintP hit = posI->second.getConstraintOfType(posC->getType());
    1193         [ +  - ]:       3195 :     Trace("arith::constraint") << "hit " << hit << endl;
    1194         [ +  - ]:       3195 :     Trace("arith::constraint") << "posC " << posC << endl;
    1195                 :            : 
    1196         [ +  - ]:       3195 :     delete posC;
    1197                 :            : 
    1198                 :       3195 :     hit->setLiteral(atomNode);
    1199                 :       3195 :     hit->getNegation()->setLiteral(negationNode);
    1200         [ -  + ]:       3195 :     return isNot ? hit->getNegation(): hit;
    1201                 :            :   }else{
    1202                 :    1163390 :     Comparison negCmp = Comparison::parseNormalForm(negationNode);
    1203                 :            : 
    1204                 :     581696 :     ConstraintType negType = Constraint::constraintTypeOfComparison(negCmp);
    1205                 :     581696 :     DeltaRational negDR = negCmp.normalizedDeltaRational();
    1206                 :            : 
    1207                 :            :     ConstraintP negC =
    1208                 :     581696 :         new Constraint(v, negType, negDR, options().smt.produceProofs);
    1209                 :            : 
    1210                 :     581696 :     SortedConstraintMapIterator negI;
    1211                 :            : 
    1212         [ +  + ]:     581696 :     if(posC->isEquality()){
    1213                 :     264983 :       negI = posI;
    1214                 :            :     }else{
    1215 [ +  + ][ -  + ]:     316713 :       Assert(posC->isLowerBound() || posC->isUpperBound());
         [ -  + ][ -  - ]
    1216                 :            : 
    1217                 :     316713 :       pair<SortedConstraintMapIterator, bool> negInsertAttempt;
    1218                 :     316713 :       negInsertAttempt = scm.insert(make_pair(negC->getValue(), ValueCollection()));
    1219                 :            : 
    1220         [ +  - ]:     316713 :       Trace("nf::tmp") << "sdhjfgdhjkldfgljkhdfg" << endl;
    1221         [ +  - ]:     316713 :       Trace("nf::tmp") << negC << endl;
    1222         [ +  - ]:     316713 :       Trace("nf::tmp") << negC->getValue() << endl;
    1223                 :            : 
    1224                 :            :       //This should always succeed as the DeltaRational for the negation is unique!
    1225 [ -  + ][ -  + ]:     316713 :       Assert(negInsertAttempt.second);
                 [ -  - ]
    1226                 :            : 
    1227                 :     316713 :       negI = negInsertAttempt.first;
    1228                 :            :     }
    1229                 :            : 
    1230                 :     581696 :     (posI->second).add(posC);
    1231                 :     581696 :     (negI->second).add(negC);
    1232                 :            : 
    1233                 :     581696 :     posC->initialize(this, posI, negC);
    1234                 :     581696 :     negC->initialize(this, negI, posC);
    1235                 :            : 
    1236                 :     581696 :     posC->setLiteral(atomNode);
    1237                 :     581696 :     negC->setLiteral(negationNode);
    1238                 :            : 
    1239         [ -  + ]:     581696 :     return isNot ? negC : posC;
    1240                 :            :   }
    1241                 :            : }
    1242                 :            : 
    1243                 :            : 
    1244                 :   20223800 : ConstraintP ConstraintDatabase::lookup(TNode literal) const{
    1245                 :   20223800 :   NodetoConstraintMap::const_iterator iter = d_nodetoConstraintMap.find(literal);
    1246         [ +  + ]:   20223800 :   if(iter == d_nodetoConstraintMap.end()){
    1247                 :    4101070 :     return NullConstraint;
    1248                 :            :   }else{
    1249                 :   16122700 :     return iter->second;
    1250                 :            :   }
    1251                 :            : }
    1252                 :            : 
    1253                 :    9964580 : void Constraint::setAssumption(bool nowInConflict){
    1254         [ +  - ]:    9964580 :   Trace("constraints::pf") << "setAssumption(" << this << ")" << std::endl;
    1255 [ -  + ][ -  + ]:    9964580 :   Assert(!hasProof());
                 [ -  - ]
    1256 [ -  + ][ -  + ]:    9964580 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
    1257 [ -  + ][ -  + ]:    9964580 :   Assert(hasLiteral());
                 [ -  - ]
    1258 [ -  + ][ -  + ]:    9964580 :   Assert(assertedToTheTheory());
                 [ -  - ]
    1259                 :            : 
    1260                 :    9964580 :   d_database->pushConstraintRule(ConstraintRule(this, AssumeAP));
    1261                 :            : 
    1262 [ -  + ][ -  + ]:    9964580 :   Assert(inConflict() == nowInConflict);
                 [ -  - ]
    1263                 :    9964580 :   if(TraceIsOn("constraint::conflictCommit") && inConflict()){
    1264         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "inConflict@setAssumption " << this << std::endl;
    1265                 :            :   }
    1266                 :    9964580 : }
    1267                 :            : 
    1268                 :    7360910 : void Constraint::tryToPropagate(){
    1269 [ -  + ][ -  + ]:    7360910 :   Assert(hasProof());
                 [ -  - ]
    1270 [ -  + ][ -  + ]:    7360910 :   Assert(!isAssumption());
                 [ -  - ]
    1271 [ -  + ][ -  + ]:    7360910 :   Assert(!isInternalAssumption());
                 [ -  - ]
    1272                 :            : 
    1273 [ +  + ][ +  - ]:    7360910 :   if(canBePropagated() && !assertedToTheTheory() && !isAssumption() && !isInternalAssumption()){
         [ +  - ][ +  - ]
                 [ +  + ]
    1274                 :    1353640 :     propagate();
    1275                 :            :   }
    1276                 :    7360910 : }
    1277                 :            : 
    1278                 :    1385550 : void Constraint::propagate(){
    1279 [ -  + ][ -  + ]:    1385550 :   Assert(hasProof());
                 [ -  - ]
    1280 [ -  + ][ -  + ]:    1385550 :   Assert(canBePropagated());
                 [ -  - ]
    1281 [ -  + ][ -  + ]:    1385550 :   Assert(!assertedToTheTheory());
                 [ -  - ]
    1282 [ -  + ][ -  + ]:    1385550 :   Assert(!isAssumption());
                 [ -  - ]
    1283 [ -  + ][ -  + ]:    1385550 :   Assert(!isInternalAssumption());
                 [ -  - ]
    1284                 :            : 
    1285                 :    1385550 :   d_database->d_toPropagate.push(this);
    1286                 :    1385550 : }
    1287                 :            : 
    1288                 :            : 
    1289                 :            : /*
    1290                 :            :  * Example:
    1291                 :            :  *    x <= a and a < b
    1292                 :            :  * |= x <= b
    1293                 :            :  * ---
    1294                 :            :  *  1*(x <= a) + (-1)*(x > b) => (0 <= a-b)
    1295                 :            :  */
    1296                 :    3792390 : void Constraint::impliedByUnate(NodeManager* nm,
    1297                 :            :                                 ConstraintCP imp,
    1298                 :            :                                 bool nowInConflict)
    1299                 :            : {
    1300         [ +  - ]:    3792390 :   Trace("constraints::pf") << "impliedByUnate(" << this << ", " << *imp << ")" << std::endl;
    1301 [ -  + ][ -  + ]:    3792390 :   Assert(!hasProof());
                 [ -  - ]
    1302 [ -  + ][ -  + ]:    3792390 :   Assert(imp->hasProof());
                 [ -  - ]
    1303 [ -  + ][ -  + ]:    3792390 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
    1304                 :            : 
    1305                 :    3792390 :   d_database->d_antecedents.push_back(NullConstraint);
    1306                 :    3792390 :   d_database->d_antecedents.push_back(imp);
    1307                 :            : 
    1308                 :    3792390 :   AntecedentId antecedentEnd = d_database->d_antecedents.size() - 1;
    1309                 :            : 
    1310                 :            :   RationalVectorP coeffs;
    1311         [ +  + ]:    3792390 :   if (d_produceProofs)
    1312                 :            :   {
    1313                 :    2674510 :     std::pair<int, int> sgns = unateFarkasSigns(getNegation(), imp);
    1314                 :            : 
    1315                 :    5349030 :     Rational first(sgns.first);
    1316                 :    5349030 :     Rational second(sgns.second);
    1317                 :            : 
    1318                 :    2674510 :     coeffs = new RationalVector();
    1319                 :    2674510 :     coeffs->push_back(first);
    1320                 :    2674510 :     coeffs->push_back(second);
    1321                 :            :   }
    1322                 :            :   else
    1323                 :            :   {
    1324                 :    1117870 :     coeffs = RationalVectorPSentinel;
    1325                 :            :   }
    1326                 :            :   // no need to delete coeffs the memory is owned by ConstraintRule
    1327                 :    3792390 :   d_database->pushConstraintRule(ConstraintRule(this, FarkasAP, antecedentEnd, coeffs));
    1328                 :            : 
    1329 [ -  + ][ -  + ]:    3792390 :   Assert(inConflict() == nowInConflict);
                 [ -  - ]
    1330                 :    3792390 :   if(TraceIsOn("constraint::conflictCommit") && inConflict()){
    1331         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "inConflict@impliedByUnate " << this << std::endl;
    1332                 :            :   }
    1333                 :            : 
    1334                 :    3792390 :   if (TraceIsOn("constraints::wffp") && !wellFormedFarkasProof(nm))
    1335                 :            :   {
    1336         [ -  - ]:          0 :     getConstraintRule().print(Trace("constraints::wffp"), d_produceProofs);
    1337                 :            :   }
    1338 [ -  + ][ -  + ]:    3792390 :   Assert(wellFormedFarkasProof(nm));
                 [ -  - ]
    1339                 :    3792390 : }
    1340                 :            : 
    1341                 :    1123490 : void Constraint::impliedByTrichotomy(ConstraintCP a, ConstraintCP b, bool nowInConflict){
    1342         [ +  - ]:    1123490 :   Trace("constraints::pf") << "impliedByTrichotomy(" << this << ", " << *a << ", ";
    1343         [ +  - ]:    1123490 :   Trace("constraints::pf") << *b << ")" << std::endl;
    1344 [ -  + ][ -  + ]:    1123490 :   Assert(!hasProof());
                 [ -  - ]
    1345 [ -  + ][ -  + ]:    1123490 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
    1346 [ -  + ][ -  + ]:    1123490 :   Assert(a->hasProof());
                 [ -  - ]
    1347 [ -  + ][ -  + ]:    1123490 :   Assert(b->hasProof());
                 [ -  - ]
    1348                 :            : 
    1349                 :    1123490 :   d_database->d_antecedents.push_back(NullConstraint);
    1350                 :    1123490 :   d_database->d_antecedents.push_back(a);
    1351                 :    1123490 :   d_database->d_antecedents.push_back(b);
    1352                 :            : 
    1353                 :    1123490 :   AntecedentId antecedentEnd = d_database->d_antecedents.size() - 1;
    1354                 :    1123490 :   d_database->pushConstraintRule(ConstraintRule(this, TrichotomyAP, antecedentEnd));
    1355                 :            : 
    1356 [ -  + ][ -  + ]:    1123490 :   Assert(inConflict() == nowInConflict);
                 [ -  - ]
    1357                 :    1123490 :   if(TraceIsOn("constraint::conflictCommit") && inConflict()){
    1358         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "inConflict@impliedByTrichotomy " << this << std::endl;
    1359                 :            :   }
    1360                 :    1123490 : }
    1361                 :            : 
    1362                 :            : 
    1363                 :     167140 : bool Constraint::allHaveProof(const ConstraintCPVec& b){
    1364         [ +  + ]:    2189090 :   for(ConstraintCPVec::const_iterator i=b.begin(), i_end=b.end(); i != i_end; ++i){
    1365                 :    2021950 :     ConstraintCP cp = *i;
    1366         [ -  + ]:    2021950 :     if(! (cp->hasProof())){ return false; }
    1367                 :            :   }
    1368                 :     167140 :   return true;
    1369                 :            : }
    1370                 :            : 
    1371                 :    2387520 : void Constraint::impliedByIntTighten(ConstraintCP a, bool nowInConflict){
    1372         [ +  - ]:    2387520 :   Trace("constraints::pf") << "impliedByIntTighten(" << this << ", " << *a << ")" << std::endl;
    1373 [ -  + ][ -  + ]:    2387520 :   Assert(!hasProof());
                 [ -  - ]
    1374 [ -  + ][ -  + ]:    2387520 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
    1375 [ -  + ][ -  + ]:    2387520 :   Assert(a->hasProof());
                 [ -  - ]
    1376         [ +  - ]:    4775030 :   Trace("pf::arith") << "impliedByIntTighten(" << this << ", " << a << ")"
    1377                 :    2387520 :                      << std::endl;
    1378                 :            : 
    1379                 :    2387520 :   d_database->d_antecedents.push_back(NullConstraint);
    1380                 :    2387520 :   d_database->d_antecedents.push_back(a);
    1381                 :    2387520 :   AntecedentId antecedentEnd = d_database->d_antecedents.size() - 1;
    1382                 :    2387520 :   d_database->pushConstraintRule(ConstraintRule(this, IntTightenAP, antecedentEnd));
    1383                 :            : 
    1384 [ -  + ][ -  + ]:    2387520 :   Assert(inConflict() == nowInConflict);
                 [ -  - ]
    1385         [ +  + ]:    2387520 :   if(inConflict()){
    1386         [ +  - ]:       3619 :     Trace("constraint::conflictCommit") << "inConflict impliedByIntTighten" << this << std::endl;
    1387                 :            :   }
    1388                 :    2387520 : }
    1389                 :            : 
    1390                 :          0 : void Constraint::impliedByIntHole(ConstraintCP a, bool nowInConflict){
    1391         [ -  - ]:          0 :   Trace("constraints::pf") << "impliedByIntHole(" << this << ", " << *a << ")" << std::endl;
    1392                 :          0 :   Assert(!hasProof());
    1393                 :          0 :   Assert(negationHasProof() == nowInConflict);
    1394                 :          0 :   Assert(a->hasProof());
    1395         [ -  - ]:          0 :   Trace("pf::arith") << "impliedByIntHole(" << this << ", " << a << ")"
    1396                 :          0 :                      << std::endl;
    1397                 :            : 
    1398                 :          0 :   d_database->d_antecedents.push_back(NullConstraint);
    1399                 :          0 :   d_database->d_antecedents.push_back(a);
    1400                 :          0 :   AntecedentId antecedentEnd = d_database->d_antecedents.size() - 1;
    1401                 :          0 :   d_database->pushConstraintRule(ConstraintRule(this, IntHoleAP, antecedentEnd));
    1402                 :            : 
    1403                 :          0 :   Assert(inConflict() == nowInConflict);
    1404                 :          0 :   if(TraceIsOn("constraint::conflictCommit") && inConflict()){
    1405         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "inConflict impliedByIntHole" << this << std::endl;
    1406                 :            :   }
    1407                 :          0 : }
    1408                 :            : 
    1409                 :          0 : void Constraint::impliedByIntHole(const ConstraintCPVec& b, bool nowInConflict){
    1410         [ -  - ]:          0 :   Trace("constraints::pf") << "impliedByIntHole(" << this;
    1411         [ -  - ]:          0 :   if (TraceIsOn("constraints::pf")) {
    1412         [ -  - ]:          0 :     for (const ConstraintCP& p : b)
    1413                 :            :     {
    1414         [ -  - ]:          0 :       Trace("constraints::pf") << ", " << p;
    1415                 :            :     }
    1416                 :            :   }
    1417         [ -  - ]:          0 :   Trace("constraints::pf") << ")" << std::endl;
    1418                 :            : 
    1419                 :          0 :   Assert(!hasProof());
    1420                 :          0 :   Assert(negationHasProof() == nowInConflict);
    1421                 :          0 :   Assert(allHaveProof(b));
    1422                 :            : 
    1423                 :          0 :   CDConstraintList& antecedents = d_database->d_antecedents;
    1424                 :          0 :   antecedents.push_back(NullConstraint);
    1425         [ -  - ]:          0 :   for(ConstraintCPVec::const_iterator i=b.begin(), i_end=b.end(); i != i_end; ++i){
    1426                 :          0 :     antecedents.push_back(*i);
    1427                 :            :   }
    1428                 :          0 :   AntecedentId antecedentEnd = antecedents.size() - 1;
    1429                 :            : 
    1430                 :          0 :   d_database->pushConstraintRule(ConstraintRule(this, IntHoleAP, antecedentEnd));
    1431                 :            : 
    1432                 :          0 :   Assert(inConflict() == nowInConflict);
    1433                 :          0 :   if(TraceIsOn("constraint::conflictCommit") && inConflict()){
    1434         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "inConflict@impliedByIntHole[vec] " << this << std::endl;
    1435                 :            :   }
    1436                 :          0 : }
    1437                 :            : 
    1438                 :            : /*
    1439                 :            :  * If proofs are off, coeffs == RationalVectorSentinal.
    1440                 :            :  * If proofs are on,
    1441                 :            :  *   coeffs != RationalVectorSentinal,
    1442                 :            :  *   coeffs->size() = a.size() + 1,
    1443                 :            :  *   for i in [0,a.size) : coeff[i] corresponds to a[i], and
    1444                 :            :  *   coeff.back() corresponds to the current constraint.
    1445                 :            :  */
    1446                 :     167140 : void Constraint::impliedByFarkas(NodeManager* nm,
    1447                 :            :                                  const ConstraintCPVec& a,
    1448                 :            :                                  RationalVectorCP coeffs,
    1449                 :            :                                  bool nowInConflict)
    1450                 :            : {
    1451         [ +  - ]:     167140 :   Trace("constraints::pf") << "impliedByFarkas(" << this;
    1452         [ -  + ]:     167140 :   if (TraceIsOn("constraints::pf")) {
    1453         [ -  - ]:          0 :     for (const ConstraintCP& p : a)
    1454                 :            :     {
    1455         [ -  - ]:          0 :       Trace("constraints::pf") << ", " << p;
    1456                 :            :     }
    1457                 :            :   }
    1458         [ +  - ]:     167140 :   Trace("constraints::pf") << ", <coeffs>";
    1459         [ +  - ]:     167140 :   Trace("constraints::pf") << ")" << std::endl;
    1460 [ -  + ][ -  + ]:     167140 :   Assert(!hasProof());
                 [ -  - ]
    1461 [ -  + ][ -  + ]:     167140 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
    1462 [ -  + ][ -  + ]:     167140 :   Assert(allHaveProof(a));
                 [ -  - ]
    1463                 :            : 
    1464 [ -  + ][ -  + ]:     167140 :   Assert(d_produceProofs == (coeffs != RationalVectorCPSentinel));
                 [ -  - ]
    1465 [ +  + ][ -  + ]:     167140 :   Assert(!d_produceProofs || coeffs->size() == a.size() + 1);
         [ -  + ][ -  - ]
    1466                 :            : 
    1467 [ -  + ][ -  + ]:     167140 :   Assert(a.size() >= 1);
                 [ -  - ]
    1468                 :            : 
    1469                 :     167140 :   d_database->d_antecedents.push_back(NullConstraint);
    1470         [ +  + ]:    2189090 :   for(ConstraintCPVec::const_iterator i = a.begin(), end = a.end(); i != end; ++i){
    1471                 :    2021950 :     ConstraintCP c_i = *i;
    1472 [ -  + ][ -  + ]:    2021950 :     Assert(c_i->hasProof());
                 [ -  - ]
    1473                 :    2021950 :     d_database->d_antecedents.push_back(c_i);
    1474                 :            :   }
    1475                 :     167140 :   AntecedentId antecedentEnd = d_database->d_antecedents.size() - 1;
    1476                 :            : 
    1477                 :            :   RationalVectorCP coeffsCopy;
    1478         [ +  + ]:     167140 :   if (d_produceProofs)
    1479                 :            :   {
    1480 [ -  + ][ -  + ]:     113085 :     Assert(coeffs != RationalVectorCPSentinel);
                 [ -  - ]
    1481                 :     113085 :     coeffsCopy = new RationalVector(*coeffs);
    1482                 :            :   }
    1483                 :            :   else
    1484                 :            :   {
    1485                 :      54055 :     coeffsCopy = RationalVectorCPSentinel;
    1486                 :            :   }
    1487                 :     167140 :   d_database->pushConstraintRule(ConstraintRule(this, FarkasAP, antecedentEnd, coeffsCopy));
    1488                 :            : 
    1489 [ -  + ][ -  + ]:     167140 :   Assert(inConflict() == nowInConflict);
                 [ -  - ]
    1490                 :     167140 :   if(TraceIsOn("constraint::conflictCommit") && inConflict()){
    1491         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "inConflict@impliedByFarkas " << this << std::endl;
    1492                 :            :   }
    1493                 :     167140 :   if (TraceIsOn("constraints::wffp") && !wellFormedFarkasProof(nm))
    1494                 :            :   {
    1495         [ -  - ]:          0 :     getConstraintRule().print(Trace("constraints::wffp"), d_produceProofs);
    1496                 :            :   }
    1497 [ -  + ][ -  + ]:     167140 :   Assert(wellFormedFarkasProof(nm));
                 [ -  - ]
    1498                 :     167140 : }
    1499                 :            : 
    1500                 :          0 : void Constraint::setInternalAssumption(bool nowInConflict){
    1501         [ -  - ]:          0 :   Trace("constraints::pf") << "setInternalAssumption(" << this;
    1502         [ -  - ]:          0 :   Trace("constraints::pf") << ")" << std::endl;
    1503                 :          0 :   Assert(!hasProof());
    1504                 :          0 :   Assert(negationHasProof() == nowInConflict);
    1505                 :          0 :   Assert(!assertedToTheTheory());
    1506                 :            : 
    1507                 :          0 :   d_database->pushConstraintRule(ConstraintRule(this, InternalAssumeAP));
    1508                 :            : 
    1509                 :          0 :   Assert(inConflict() == nowInConflict);
    1510                 :          0 :   if(TraceIsOn("constraint::conflictCommit") && inConflict()){
    1511         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "inConflict@setInternalAssumption " << this << std::endl;
    1512                 :            :   }
    1513                 :          0 : }
    1514                 :            : 
    1515                 :            : 
    1516                 :     373448 : void Constraint::setEqualityEngineProof(){
    1517         [ +  - ]:     373448 :   Trace("constraints::pf") << "setEqualityEngineProof(" << this;
    1518         [ +  - ]:     373448 :   Trace("constraints::pf") << ")" << std::endl;
    1519 [ -  + ][ -  + ]:     373448 :   Assert(truthIsUnknown());
                 [ -  - ]
    1520 [ -  + ][ -  + ]:     373448 :   Assert(hasLiteral());
                 [ -  - ]
    1521                 :     373448 :   d_database->pushConstraintRule(ConstraintRule(this, EqualityEngineAP));
    1522                 :     373448 : }
    1523                 :            : 
    1524                 :            : 
    1525                 :    8051770 : SortedConstraintMap& Constraint::constraintSet() const{
    1526 [ -  + ][ -  + ]:    8051770 :   Assert(d_database->variableDatabaseIsSetup(d_variable));
                 [ -  - ]
    1527                 :    8051770 :   return (d_database->d_varDatabases[d_variable])->d_constraints;
    1528                 :            : }
    1529                 :            : 
    1530                 :          0 : bool Constraint::antecentListIsEmpty() const{
    1531                 :          0 :   Assert(hasProof());
    1532                 :          0 :   return d_database->d_antecedents[getEndAntecedent()] == NullConstraint;
    1533                 :            : }
    1534                 :            : 
    1535                 :          0 : bool Constraint::antecedentListLengthIsOne() const {
    1536                 :          0 :   Assert(hasProof());
    1537         [ -  - ]:          0 :   return !antecentListIsEmpty() &&
    1538         [ -  - ]:          0 :     d_database->d_antecedents[getEndAntecedent()-1] == NullConstraint;
    1539                 :            : }
    1540                 :            : 
    1541                 :     173614 : Node Constraint::externalImplication(NodeManager* nm,
    1542                 :            :                                      const ConstraintCPVec& b) const
    1543                 :            : {
    1544 [ -  + ][ -  + ]:     173614 :   Assert(hasLiteral());
                 [ -  - ]
    1545                 :     347228 :   Node antecedent = externalExplainByAssertions(nm, b);
    1546                 :     347228 :   Node implied = getLiteral();
    1547                 :     347228 :   return antecedent.impNode(implied);
    1548                 :            : }
    1549                 :            : 
    1550                 :     194347 : Node Constraint::externalExplainByAssertions(NodeManager* nm,
    1551                 :            :                                              const ConstraintCPVec& b)
    1552                 :            : {
    1553                 :     194347 :   return externalExplain(nm, b, AssertionOrderSentinel);
    1554                 :            : }
    1555                 :            : 
    1556                 :      16217 : TrustNode Constraint::externalExplainForPropagation(TNode lit) const
    1557                 :            : {
    1558 [ -  + ][ -  + ]:      16217 :   Assert(hasProof());
                 [ -  - ]
    1559 [ -  + ][ -  + ]:      16217 :   Assert(!isAssumption());
                 [ -  - ]
    1560 [ -  + ][ -  + ]:      16217 :   Assert(!isInternalAssumption());
                 [ -  - ]
    1561                 :      32434 :   NodeBuilder nb(d_database->nodeManager(), Kind::AND);
    1562                 :      32434 :   auto pfFromAssumptions = externalExplain(nb, d_assertionOrder);
    1563                 :      32434 :   Node n = mkAndFromBuilder(d_database->nodeManager(), nb);
    1564         [ +  + ]:      16217 :   if (d_database->isProofEnabled())
    1565                 :            :   {
    1566                 :      14136 :     std::vector<Node> assumptions;
    1567         [ +  + ]:       7068 :     if (n.getKind() == Kind::AND)
    1568                 :            :     {
    1569                 :       3362 :       assumptions.insert(assumptions.end(), n.begin(), n.end());
    1570                 :            :     }
    1571                 :            :     else
    1572                 :            :     {
    1573                 :       3706 :       assumptions.push_back(n);
    1574                 :            :     }
    1575         [ +  + ]:       7068 :     if (getProofLiteral() != lit)
    1576                 :            :     {
    1577                 :            :       pfFromAssumptions =
    1578                 :       4079 :           ensurePredTransform(d_database->d_pnm, pfFromAssumptions, lit);
    1579                 :            :     }
    1580                 :      14136 :     auto pf = d_database->d_pnm->mkScope(pfFromAssumptions, assumptions);
    1581                 :       7068 :     return d_database->d_pfGen->mkTrustedPropagation(
    1582                 :       7068 :         lit, d_database->nodeManager()->mkAnd(assumptions), pf);
    1583                 :            :   }
    1584                 :            :   else
    1585                 :            :   {
    1586                 :       9149 :     return TrustNode::mkTrustPropExp(lit, n);
    1587                 :            :   }
    1588                 :            : }
    1589                 :            : 
    1590                 :     116470 : TrustNode Constraint::externalExplainConflict() const
    1591                 :            : {
    1592         [ +  - ]:     116470 :   Trace("pf::arith::explain") << this << std::endl;
    1593 [ -  + ][ -  + ]:     116470 :   Assert(inConflict());
                 [ -  - ]
    1594                 :     232940 :   NodeBuilder nb(d_database->nodeManager(), Kind::AND);
    1595                 :     232940 :   auto pf1 = externalExplainByAssertions(nb);
    1596                 :     232940 :   auto not2 = getNegation()->getProofLiteral().negate();
    1597                 :     232940 :   auto pf2 = getNegation()->externalExplainByAssertions(nb);
    1598                 :     232940 :   Node n = mkAndFromBuilder(d_database->nodeManager(), nb);
    1599         [ +  + ]:     116470 :   if (d_database->isProofEnabled())
    1600                 :            :   {
    1601                 :     100476 :     auto pfNot2 = ensurePredTransform(d_database->d_pnm, pf1, not2);
    1602                 :     100476 :     std::vector<Node> lits;
    1603         [ +  - ]:      50238 :     if (n.getKind() == Kind::AND)
    1604                 :            :     {
    1605                 :      50238 :       lits.insert(lits.end(), n.begin(), n.end());
    1606                 :            :     }
    1607                 :            :     else
    1608                 :            :     {
    1609                 :          0 :       lits.push_back(n);
    1610                 :            :     }
    1611         [ -  + ]:      50238 :     if (TraceIsOn("arith::pf::externalExplainConflict"))
    1612                 :            :     {
    1613         [ -  - ]:          0 :       Trace("arith::pf::externalExplainConflict") << "Lits:" << std::endl;
    1614         [ -  - ]:          0 :       for (const auto& l : lits)
    1615                 :            :       {
    1616         [ -  - ]:          0 :         Trace("arith::pf::externalExplainConflict") << "  : " << l << std::endl;
    1617                 :            :       }
    1618                 :            :     }
    1619                 :            :     std::vector<Node> contraLits = {getProofLiteral(),
    1620                 :     251190 :                                     getNegation()->getProofLiteral()};
    1621                 :            :     auto bot =
    1622                 :      50238 :         not2.getKind() == Kind::NOT
    1623                 :      95952 :             ? d_database->d_pnm->mkNode(ProofRule::CONTRA, {pf2, pfNot2}, {})
    1624                 :     308214 :             : d_database->d_pnm->mkNode(ProofRule::CONTRA, {pfNot2, pf2}, {});
    1625         [ -  + ]:      50238 :     if (TraceIsOn("arith::pf::tree"))
    1626                 :            :     {
    1627         [ -  - ]:          0 :       Trace("arith::pf::tree") << *this << std::endl;
    1628         [ -  - ]:          0 :       Trace("arith::pf::tree") << *getNegation() << std::endl;
    1629         [ -  - ]:          0 :       Trace("arith::pf::tree") << "\n\nTree:\n";
    1630         [ -  - ]:          0 :       printProofTree(Trace("arith::pf::tree"));
    1631         [ -  - ]:          0 :       getNegation()->printProofTree(Trace("arith::pf::tree"));
    1632                 :            :     }
    1633                 :     100476 :     auto confPf = d_database->d_pnm->mkScope(bot, lits);
    1634                 :      50238 :     return d_database->d_pfGen->mkTrustNode(
    1635                 :     100476 :         d_database->nodeManager()->mkAnd(lits), confPf, true);
    1636                 :            :   }
    1637                 :            :   else
    1638                 :            :   {
    1639                 :      66232 :     return TrustNode::mkTrustConflict(n);
    1640                 :            :   }
    1641                 :            : }
    1642                 :            : 
    1643                 :            : struct ConstraintCPHash {
    1644                 :            :   /* Todo replace with an id */
    1645                 :          0 :   size_t operator()(ConstraintCP c) const{
    1646                 :            :     Assert(sizeof(ConstraintCP) > 0);
    1647                 :          0 :     return ((size_t)c)/sizeof(ConstraintCP);
    1648                 :            :   }
    1649                 :            : };
    1650                 :            : 
    1651                 :          0 : void Constraint::assertionFringe(ConstraintCPVec& v){
    1652                 :          0 :   unordered_set<ConstraintCP, ConstraintCPHash> visited;
    1653                 :          0 :   size_t writePos = 0;
    1654                 :            : 
    1655         [ -  - ]:          0 :   if(!v.empty()){
    1656                 :          0 :     const ConstraintDatabase* db = v.back()->d_database;
    1657                 :          0 :     const CDConstraintList& antecedents = db->d_antecedents;
    1658         [ -  - ]:          0 :     for(size_t i = 0; i < v.size(); ++i){
    1659                 :          0 :       ConstraintCP vi = v[i];
    1660         [ -  - ]:          0 :       if(visited.find(vi) == visited.end()){
    1661                 :          0 :         Assert(vi->hasProof());
    1662                 :          0 :         visited.insert(vi);
    1663         [ -  - ]:          0 :         if(vi->onFringe()){
    1664                 :          0 :           v[writePos] = vi;
    1665                 :          0 :           writePos++;
    1666                 :            :         }else{
    1667                 :          0 :           Assert(vi->hasTrichotomyProof() || vi->hasFarkasProof()
    1668                 :            :                  || vi->hasIntHoleProof() || vi->hasIntTightenProof());
    1669                 :          0 :           AntecedentId p = vi->getEndAntecedent();
    1670                 :            : 
    1671                 :          0 :           ConstraintCP antecedent = antecedents[p];
    1672         [ -  - ]:          0 :           while(antecedent != NullConstraint){
    1673                 :          0 :             v.push_back(antecedent);
    1674                 :          0 :             --p;
    1675                 :          0 :             antecedent = antecedents[p];
    1676                 :            :           }
    1677                 :            :         }
    1678                 :            :       }
    1679                 :            :     }
    1680                 :          0 :     v.resize(writePos);
    1681                 :            :   }
    1682                 :          0 : }
    1683                 :            : 
    1684                 :          0 : void Constraint::assertionFringe(ConstraintCPVec& o, const ConstraintCPVec& i){
    1685                 :          0 :   o.insert(o.end(), i.begin(), i.end());
    1686                 :          0 :   assertionFringe(o);
    1687                 :          0 : }
    1688                 :            : 
    1689                 :     194347 : Node Constraint::externalExplain(NodeManager* nm,
    1690                 :            :                                  const ConstraintCPVec& v,
    1691                 :            :                                  AssertionOrder order)
    1692                 :            : {
    1693                 :     388694 :   NodeBuilder nb(nm, Kind::AND);
    1694                 :     194347 :   ConstraintCPVec::const_iterator i, end;
    1695         [ +  + ]:     812588 :   for(i = v.begin(), end = v.end(); i != end; ++i){
    1696                 :     618241 :     ConstraintCP v_i = *i;
    1697                 :     618241 :     v_i->externalExplain(nb, order);
    1698                 :            :   }
    1699                 :     388694 :   return mkAndFromBuilder(nm, nb);
    1700                 :            : }
    1701                 :            : 
    1702                 :    9612760 : std::shared_ptr<ProofNode> Constraint::externalExplain(
    1703                 :            :     NodeBuilder& nb, AssertionOrder order) const
    1704                 :            : {
    1705         [ -  + ]:    9612760 :   if (TraceIsOn("pf::arith::explain"))
    1706                 :            :   {
    1707         [ -  - ]:          0 :     this->printProofTree(Trace("arith::pf::tree"));
    1708         [ -  - ]:          0 :     Trace("pf::arith::explain") << "Explaining: " << this << " with rule ";
    1709         [ -  - ]:          0 :     getConstraintRule().print(Trace("pf::arith::explain"), d_produceProofs);
    1710         [ -  - ]:          0 :     Trace("pf::arith::explain") << std::endl;
    1711                 :            :   }
    1712 [ -  + ][ -  + ]:    9612760 :   Assert(hasProof());
                 [ -  - ]
    1713 [ +  + ][ -  + ]:    9612760 :   Assert(!isAssumption() || assertedToTheTheory());
         [ -  + ][ -  - ]
    1714 [ -  + ][ -  + ]:    9612760 :   Assert(!isInternalAssumption());
                 [ -  - ]
    1715                 :    9612760 :   std::shared_ptr<ProofNode> pf{};
    1716                 :            : 
    1717                 :    9612760 :   ProofNodeManager* pnm = d_database->d_pnm;
    1718                 :            : 
    1719         [ +  + ]:    9612760 :   if (assertedBefore(order))
    1720                 :            :   {
    1721         [ +  - ]:    8193110 :     Trace("pf::arith::explain") << "  already asserted" << std::endl;
    1722                 :    8193110 :     nb << getWitness();
    1723         [ +  + ]:    8193110 :     if (d_database->isProofEnabled())
    1724                 :            :     {
    1725                 :    3576480 :       pf = pnm->mkAssume(getWitness());
    1726                 :            :       // If the witness and literal differ, prove the difference through a
    1727                 :            :       // rewrite.
    1728                 :    3576480 :       pf = ensurePredTransform(pnm, pf, getProofLiteral());
    1729                 :            :     }
    1730                 :            :   }
    1731         [ +  + ]:    1419650 :   else if (hasEqualityEngineProof())
    1732                 :            :   {
    1733                 :            :     // just assume, it will be explained again
    1734                 :        499 :     Node lit = getLiteral();
    1735         [ +  + ]:        499 :     if (d_database->isProofEnabled())
    1736                 :            :     {
    1737                 :        470 :       std::shared_ptr<ProofNode> a = pnm->mkAssume(getLiteral());
    1738                 :        235 :       Node plit = getProofLiteral();
    1739                 :        235 :       pf = ensurePredTransform(pnm, a, plit);
    1740                 :            :     }
    1741 [ -  + ][ -  + ]:        499 :     Assert(lit.getKind() != Kind::AND);
                 [ -  - ]
    1742                 :        499 :     nb << lit;
    1743                 :            :   }
    1744                 :            :   else
    1745                 :            :   {
    1746         [ +  - ]:    1419160 :     Trace("pf::arith::explain") << "  recursion!" << std::endl;
    1747 [ -  + ][ -  + ]:    1419160 :     Assert(!isAssumption());
                 [ -  - ]
    1748                 :    1419160 :     AntecedentId p = getEndAntecedent();
    1749                 :    1419160 :     ConstraintCP antecedent = d_database->d_antecedents[p];
    1750                 :    2838310 :     std::vector<std::shared_ptr<ProofNode>> children;
    1751                 :            : 
    1752         [ +  + ]:    4053380 :     while (antecedent != NullConstraint)
    1753                 :            :     {
    1754         [ +  - ]:    2634220 :       Trace("pf::arith::explain") << "Explain " << antecedent << std::endl;
    1755                 :    2634220 :       auto pn = antecedent->externalExplain(nb, order);
    1756         [ +  + ]:    2634220 :       if (d_database->isProofEnabled())
    1757                 :            :       {
    1758                 :    1015730 :         children.push_back(pn);
    1759                 :            :       }
    1760                 :    2634220 :       --p;
    1761                 :    2634220 :       antecedent = d_database->d_antecedents[p];
    1762                 :            :     }
    1763                 :            : 
    1764         [ +  + ]:    1419160 :     if (d_database->isProofEnabled())
    1765                 :            :     {
    1766 [ -  + ][ +  - ]:     689804 :       switch (getProofType())
                 [ +  - ]
    1767                 :            :       {
    1768                 :          0 :         case ArithProofType::AssumeAP:
    1769                 :            :         case ArithProofType::EqualityEngineAP:
    1770                 :            :         {
    1771                 :          0 :           Unreachable() << "These should be handled above";
    1772                 :            :           break;
    1773                 :            :         }
    1774                 :      54458 :         case ArithProofType::FarkasAP:
    1775                 :            :         {
    1776                 :            :           // Per docs in constraint.h,
    1777                 :            :           // the 0th farkas coefficient is for the negation of the deduced
    1778                 :            :           // constraint the 1st corresponds to the last antecedent the nth
    1779                 :            :           // corresponds to the first antecedent Then, the farkas coefficients
    1780                 :            :           // and the antecedents are in the same order.
    1781                 :            : 
    1782                 :            :           // Enumerate child proofs (negation included) in d_farkasCoefficients
    1783                 :            :           // order
    1784                 :     108916 :           Node plit = getNegation()->getProofLiteral();
    1785                 :     108916 :           std::vector<std::shared_ptr<ProofNode>> farkasChildren;
    1786                 :      54458 :           farkasChildren.push_back(pnm->mkAssume(plit));
    1787                 :            :           farkasChildren.insert(
    1788                 :      54458 :               farkasChildren.end(), children.rbegin(), children.rend());
    1789                 :            : 
    1790                 :      54458 :           NodeManager* nm = d_database->nodeManager();
    1791                 :            : 
    1792                 :            :           // Enumerate d_farkasCoefficients as nodes.
    1793                 :     108916 :           std::vector<Node> farkasCoeffs;
    1794                 :     108916 :           TypeNode type = plit[0].getType();
    1795         [ +  + ]:     452510 :           for (Rational r : *getFarkasCoefficients())
    1796                 :            :           {
    1797                 :     398052 :             farkasCoeffs.push_back(nm->mkConstRealOrInt(Rational(r)));
    1798                 :            :           }
    1799                 :            :           std::vector<Node> farkasCoeffsUse =
    1800                 :     108916 :               getMacroSumUbCoeff(nm, farkasChildren, farkasCoeffs);
    1801                 :            : 
    1802                 :            :           // Apply the scaled-sum rule.
    1803                 :            :           std::shared_ptr<ProofNode> sumPf =
    1804                 :            :               pnm->mkNode(ProofRule::MACRO_ARITH_SCALE_SUM_UB,
    1805                 :            :                           farkasChildren,
    1806                 :     108916 :                           farkasCoeffsUse);
    1807                 :            : 
    1808                 :            :           // Provable rewrite the result
    1809                 :     108916 :           Node falsen = nm->mkConst(false);
    1810                 :     108916 :           auto botPf = ensurePredTransform(pnm, sumPf, falsen);
    1811                 :            : 
    1812                 :            :           // Scope out the negated constraint, yielding a proof of the
    1813                 :            :           // constraint.
    1814                 :     217832 :           std::vector<Node> assump{plit};
    1815                 :     163374 :           auto maybeDoubleNotPf = pnm->mkScope(botPf, assump, false);
    1816                 :            : 
    1817                 :            :           // No need to ensure that the expected node aggrees with `assump`
    1818                 :            :           // because we are not providing an expected node.
    1819                 :            :           //
    1820                 :            :           // Prove that this is the literal (may need to clean a double-not)
    1821                 :     108916 :           Node plit2 = getProofLiteral();
    1822                 :      54458 :           pf = ensurePredTransform(pnm, maybeDoubleNotPf, plit2);
    1823                 :            : 
    1824                 :      54458 :           break;
    1825                 :            :         }
    1826                 :     598554 :         case ArithProofType::IntTightenAP:
    1827                 :            :         {
    1828         [ +  + ]:     598554 :           if (isUpperBound())
    1829                 :            :           {
    1830                 :    1179410 :             pf = pnm->mkNode(
    1831                 :    1769110 :                 ProofRule::INT_TIGHT_UB, children, {}, getProofLiteral());
    1832                 :            :           }
    1833         [ +  - ]:       8850 :           else if (isLowerBound())
    1834                 :            :           {
    1835                 :      17700 :             pf = pnm->mkNode(
    1836                 :      26550 :                 ProofRule::INT_TIGHT_LB, children, {}, getProofLiteral());
    1837                 :            :           }
    1838                 :            :           else
    1839                 :            :           {
    1840                 :          0 :             Unreachable();
    1841                 :            :           }
    1842                 :     598554 :           break;
    1843                 :            :         }
    1844                 :          0 :         case ArithProofType::IntHoleAP:
    1845                 :            :         {
    1846                 :          0 :           pf = pnm->mkTrustedNode(TrustId::THEORY_INFERENCE_ARITH,
    1847                 :            :                                   children,
    1848                 :            :                                   {getProofLiteral()},
    1849                 :          0 :                                   getProofLiteral());
    1850                 :          0 :           break;
    1851                 :            :         }
    1852                 :      36792 :         case ArithProofType::TrichotomyAP:
    1853                 :            :         {
    1854                 :      73584 :           pf = pnm->mkNode(
    1855                 :     110376 :               ProofRule::ARITH_TRICHOTOMY, children, {}, getProofLiteral());
    1856                 :      36792 :           break;
    1857                 :            :         }
    1858                 :          0 :         case ArithProofType::InternalAssumeAP:
    1859                 :            :         case ArithProofType::NoAP:
    1860                 :            :         default:
    1861                 :            :         {
    1862                 :          0 :           Unreachable() << getProofType()
    1863                 :          0 :                         << " should not be visible in explanation";
    1864                 :            :           break;
    1865                 :            :         }
    1866                 :            :       }
    1867                 :            :     }
    1868                 :            :   }
    1869                 :    9612760 :   return pf;
    1870                 :            : }
    1871                 :            : 
    1872                 :       1452 : Node Constraint::externalExplainByAssertions(NodeManager* nm,
    1873                 :            :                                              ConstraintCP a,
    1874                 :            :                                              ConstraintCP b)
    1875                 :            : {
    1876                 :       2904 :   NodeBuilder nb(nm, Kind::AND);
    1877                 :       1452 :   a->externalExplainByAssertions(nb);
    1878                 :       1452 :   b->externalExplainByAssertions(nb);
    1879                 :       2904 :   return nb;
    1880                 :            : }
    1881                 :            : 
    1882                 :          0 : Node Constraint::externalExplainByAssertions(NodeManager* nm,
    1883                 :            :                                              ConstraintCP a,
    1884                 :            :                                              ConstraintCP b,
    1885                 :            :                                              ConstraintCP c)
    1886                 :            : {
    1887                 :          0 :   NodeBuilder nb(nm, Kind::AND);
    1888                 :          0 :   a->externalExplainByAssertions(nb);
    1889                 :          0 :   b->externalExplainByAssertions(nb);
    1890                 :          0 :   c->externalExplainByAssertions(nb);
    1891                 :          0 :   return nb;
    1892                 :            : }
    1893                 :            : 
    1894                 :     936590 : ConstraintP Constraint::getStrictlyWeakerLowerBound(bool hasLiteral, bool asserted) const {
    1895 [ -  + ][ -  + ]:     936590 :   Assert(initialized());
                 [ -  - ]
    1896 [ +  + ][ -  + ]:     936590 :   Assert(!asserted || hasLiteral);
         [ -  + ][ -  - ]
    1897                 :            : 
    1898                 :     936590 :   SortedConstraintMapConstIterator i = d_variablePosition;
    1899                 :     936590 :   const SortedConstraintMap& scm = constraintSet();
    1900                 :     936590 :   SortedConstraintMapConstIterator i_begin = scm.begin();
    1901         [ +  + ]:    1921250 :   while(i != i_begin){
    1902                 :    1150120 :     --i;
    1903                 :    1150120 :     const ValueCollection& vc = i->second;
    1904         [ +  + ]:    1150120 :     if(vc.hasLowerBound()){
    1905                 :     316286 :       ConstraintP weaker = vc.getLowerBound();
    1906                 :            : 
    1907                 :            :       // asserted -> hasLiteral
    1908                 :            :       // hasLiteral -> weaker->hasLiteral()
    1909                 :            :       // asserted -> weaker->assertedToTheTheory()
    1910 [ +  - ][ +  + ]:     487521 :       if((!hasLiteral || (weaker->hasLiteral())) &&
                 [ +  + ]
    1911 [ +  + ][ +  + ]:     171235 :          (!asserted || ( weaker->assertedToTheTheory()))){
    1912                 :     165457 :         return weaker;
    1913                 :            :       }
    1914                 :            :     }
    1915                 :            :   }
    1916                 :     771133 :   return NullConstraint;
    1917                 :            : }
    1918                 :            : 
    1919                 :     571961 : ConstraintP Constraint::getStrictlyWeakerUpperBound(bool hasLiteral, bool asserted) const {
    1920                 :     571961 :   SortedConstraintMapConstIterator i = d_variablePosition;
    1921                 :     571961 :   const SortedConstraintMap& scm = constraintSet();
    1922                 :     571961 :   SortedConstraintMapConstIterator i_end = scm.end();
    1923                 :            : 
    1924                 :     571961 :   ++i;
    1925         [ +  + ]:    1053990 :   for(; i != i_end; ++i){
    1926                 :     671127 :     const ValueCollection& vc = i->second;
    1927         [ +  + ]:     671127 :     if(vc.hasUpperBound()){
    1928                 :     233237 :       ConstraintP weaker = vc.getUpperBound();
    1929 [ +  - ][ +  + ]:     433256 :       if((!hasLiteral || (weaker->hasLiteral())) &&
                 [ +  + ]
    1930 [ +  + ][ +  + ]:     200019 :          (!asserted || ( weaker->assertedToTheTheory()))){
    1931                 :     189098 :         return weaker;
    1932                 :            :       }
    1933                 :            :     }
    1934                 :            :   }
    1935                 :            : 
    1936                 :     382863 :   return NullConstraint;
    1937                 :            : }
    1938                 :            : 
    1939                 :    8935440 : ConstraintP ConstraintDatabase::getBestImpliedBound(ArithVar v, ConstraintType t, const DeltaRational& r) const {
    1940 [ -  + ][ -  + ]:    8935440 :   Assert(variableDatabaseIsSetup(v));
                 [ -  - ]
    1941 [ +  + ][ -  + ]:    8935440 :   Assert(t == UpperBound || t == LowerBound);
         [ -  + ][ -  - ]
    1942                 :            : 
    1943                 :    8935440 :   SortedConstraintMap& scm = getVariableSCM(v);
    1944         [ +  + ]:    8935440 :   if(t == UpperBound){
    1945                 :    4325340 :     SortedConstraintMapConstIterator i = scm.lower_bound(r);
    1946                 :    4325340 :     SortedConstraintMapConstIterator i_end = scm.end();
    1947 [ +  + ][ -  + ]:    4325340 :     Assert(i == i_end || r <= i->first);
         [ -  + ][ -  - ]
    1948         [ +  + ]:    6480270 :     for(; i != i_end; i++){
    1949 [ -  + ][ -  + ]:    3775620 :       Assert(r <= i->first);
                 [ -  - ]
    1950                 :    3775620 :       const ValueCollection& vc = i->second;
    1951         [ +  + ]:    3775620 :       if(vc.hasUpperBound()){
    1952                 :    1620700 :         return vc.getUpperBound();
    1953                 :            :       }
    1954                 :            :     }
    1955                 :    2704650 :     return NullConstraint;
    1956                 :            :   }else{
    1957 [ -  + ][ -  + ]:    4610090 :     Assert(t == LowerBound);
                 [ -  - ]
    1958         [ +  + ]:    4610090 :     if(scm.empty()){
    1959                 :     357768 :       return NullConstraint;
    1960                 :            :     }else{
    1961                 :    4252320 :       SortedConstraintMapConstIterator i = scm.lower_bound(r);
    1962                 :    4252320 :       SortedConstraintMapConstIterator i_begin = scm.begin();
    1963                 :    4252320 :       SortedConstraintMapConstIterator i_end = scm.end();
    1964 [ +  + ][ -  + ]:    4252320 :       Assert(i == i_end || r <= i->first);
         [ -  + ][ -  - ]
    1965                 :            : 
    1966                 :    4252320 :       int fdj = 0;
    1967                 :            : 
    1968         [ +  + ]:    4252320 :       if(i == i_end){
    1969                 :    1647380 :         --i;
    1970         [ +  - ]:    1647380 :         Trace("getBestImpliedBound") << fdj++ << " " << r << " " << i->first << endl;
    1971         [ +  + ]:    2604940 :       }else if( (i->first) > r){
    1972         [ +  + ]:     764343 :         if(i == i_begin){
    1973                 :     679994 :           return NullConstraint;
    1974                 :            :         }else{
    1975                 :      84349 :           --i;
    1976         [ +  - ]:      84349 :           Trace("getBestImpliedBound") << fdj++ << " " << r << " " << i->first << endl;
    1977                 :            :         }
    1978                 :            :       }
    1979                 :            : 
    1980                 :            :       do{
    1981         [ +  - ]:    3892940 :         Trace("getBestImpliedBound") << fdj++ << " " << r << " " << i->first << endl;
    1982 [ -  + ][ -  + ]:    3892940 :         Assert(r >= i->first);
                 [ -  - ]
    1983                 :    3892940 :         const ValueCollection& vc = i->second;
    1984                 :            : 
    1985         [ +  + ]:    3892940 :         if(vc.hasLowerBound()){
    1986                 :    1940320 :           return vc.getLowerBound();
    1987                 :            :         }
    1988                 :            : 
    1989         [ +  + ]:    1952620 :         if(i == i_begin){
    1990                 :    1632010 :           break;
    1991                 :            :         }else{
    1992                 :     320612 :           --i;
    1993                 :     320612 :         }
    1994                 :            :       }while(true);
    1995                 :    1632010 :       return NullConstraint;
    1996                 :            :     }
    1997                 :            :   }
    1998                 :            : }
    1999                 :            : 
    2000                 :   31336100 : bool ConstraintDatabase::variableDatabaseIsSetup(ArithVar v) const {
    2001                 :   31336100 :   return v < d_varDatabases.size();
    2002                 :            : }
    2003                 :            : 
    2004                 :      50287 : ConstraintDatabase::Watches::Watches(context::Context* satContext,
    2005                 :      50287 :                                      context::Context* userContext)
    2006                 :            :     : d_constraintProofs(satContext),
    2007                 :            :       d_canBePropagatedWatches(satContext),
    2008                 :            :       d_assertionOrderWatches(satContext),
    2009                 :      50287 :       d_splitWatches(userContext)
    2010                 :      50287 : {}
    2011                 :            : 
    2012                 :            : 
    2013                 :    1169780 : void Constraint::setLiteral(Node n) {
    2014         [ +  - ]:    1169780 :   Trace("arith::constraint") << "Mapping " << *this << " to " << n << std::endl;
    2015 [ -  + ][ -  + ]:    1169780 :   Assert(Comparison::isNormalAtom(n));
                 [ -  - ]
    2016 [ -  + ][ -  + ]:    1169780 :   Assert(!hasLiteral());
                 [ -  - ]
    2017 [ -  + ][ -  + ]:    1169780 :   Assert(sanityChecking(n));
                 [ -  - ]
    2018                 :    1169780 :   d_literal = n;
    2019                 :    1169780 :   NodetoConstraintMap& map = d_database->d_nodetoConstraintMap;
    2020 [ -  + ][ -  + ]:    1169780 :   Assert(map.find(n) == map.end());
                 [ -  - ]
    2021                 :    1169780 :   map.insert(make_pair(d_literal, this));
    2022                 :    1169780 : }
    2023                 :            : 
    2024                 :    5128840 : Node Constraint::getProofLiteral() const
    2025                 :            : {
    2026 [ -  + ][ -  + ]:    5128840 :   Assert(d_database != nullptr);
                 [ -  - ]
    2027 [ -  + ][ -  + ]:    5128840 :   Assert(d_database->d_avariables.hasNode(d_variable));
                 [ -  - ]
    2028                 :   10257700 :   Node varPart = d_database->d_avariables.asNode(d_variable);
    2029                 :            :   Kind cmp;
    2030                 :    5128840 :   bool neg = false;
    2031 [ +  + ][ +  + ]:    5128840 :   switch (d_type)
                    [ - ]
    2032                 :            :   {
    2033                 :    2006520 :     case ConstraintType::UpperBound:
    2034                 :            :     {
    2035         [ +  + ]:    2006520 :       if (d_value.infinitesimalIsZero())
    2036                 :            :       {
    2037                 :    1083670 :         cmp = Kind::LEQ;
    2038                 :            :       }
    2039                 :            :       else
    2040                 :            :       {
    2041                 :     922854 :         cmp = Kind::LT;
    2042                 :            :       }
    2043                 :    2006520 :       break;
    2044                 :            :     }
    2045                 :    1287280 :     case ConstraintType::LowerBound:
    2046                 :            :     {
    2047         [ +  + ]:    1287280 :       if (d_value.infinitesimalIsZero())
    2048                 :            :       {
    2049                 :    1129460 :         cmp = Kind::GEQ;
    2050                 :            :       }
    2051                 :            :       else
    2052                 :            :       {
    2053                 :     157821 :         cmp = Kind::GT;
    2054                 :            :       }
    2055                 :    1287280 :       break;
    2056                 :            :     }
    2057                 :    1587840 :     case ConstraintType::Equality:
    2058                 :            :     {
    2059                 :    1587840 :       cmp = Kind::EQUAL;
    2060                 :    1587840 :       break;
    2061                 :            :     }
    2062                 :     247200 :     case ConstraintType::Disequality:
    2063                 :            :     {
    2064                 :     247200 :       cmp = Kind::EQUAL;
    2065                 :     247200 :       neg = true;
    2066                 :     247200 :       break;
    2067                 :            :     }
    2068                 :          0 :     default: Unreachable() << d_type;
    2069                 :            :   }
    2070                 :    5128840 :   NodeManager* nm = d_database->nodeManager();
    2071                 :            :   Node constPart = nm->mkConstRealOrInt(
    2072                 :   15386500 :       varPart.getType(), Rational(d_value.getNoninfinitesimalPart()));
    2073                 :   15386500 :   Node posLit = nm->mkNode(cmp, varPart, constPart);
    2074         [ +  + ]:   10257700 :   return neg ? posLit.negate() : posLit;
    2075                 :            : }
    2076                 :            : 
    2077                 :      74981 : void ConstraintDatabase::proveOr(std::vector<TrustNode>& out,
    2078                 :            :                                  ConstraintP a,
    2079                 :            :                                  ConstraintP b,
    2080                 :            :                                  bool negateSecond) const
    2081                 :            : {
    2082                 :     149962 :   Node la = a->getLiteral();
    2083                 :     149962 :   Node lb = b->getLiteral();
    2084         [ +  + ]:     149962 :   Node orN = (la < lb) ? la.orNode(lb) : lb.orNode(la);
    2085         [ +  + ]:      74981 :   if (isProofEnabled())
    2086                 :            :   {
    2087 [ -  + ][ -  + ]:      33764 :     Assert(b->getNegation()->getType() != ConstraintType::Disequality);
                 [ -  - ]
    2088                 :      33764 :     auto nm = nodeManager();
    2089                 :      67528 :     Node alit = a->getNegation()->getProofLiteral();
    2090                 :      67528 :     TypeNode type = alit[0].getType();
    2091                 :      67528 :     auto pf_neg_la = d_pnm->mkAssume(la.negate());
    2092                 :      33764 :     pf_neg_la = ensurePredTransform(d_pnm, pf_neg_la, alit);
    2093                 :      67528 :     Node blit = b->getNegation()->getProofLiteral();
    2094                 :      67528 :     auto pf_neg_lb = d_pnm->mkAssume(lb.negate());
    2095                 :      33764 :     pf_neg_lb = ensurePredTransform(d_pnm, pf_neg_lb, blit);
    2096         [ +  + ]:      33764 :     int sndSign = negateSecond ? -1 : 1;
    2097                 :     168820 :     std::vector<Pf> args{pf_neg_la, pf_neg_lb};
    2098                 :      33764 :     std::vector<Node> coeffs{nm->mkConstReal(Rational(-1 * sndSign)),
    2099                 :     202584 :                              nm->mkConstReal(Rational(sndSign))};
    2100                 :      67528 :     std::vector<Node> coeffsUse = getMacroSumUbCoeff(nm, args, coeffs);
    2101                 :            :     auto sumubpf =
    2102                 :      67528 :         d_pnm->mkNode(ProofRule::MACRO_ARITH_SCALE_SUM_UB, args, coeffsUse);
    2103                 :      67528 :     auto bot_pf = ensurePredTransform(d_pnm, sumubpf, nm->mkConst(false));
    2104                 :      67528 :     std::vector<Node> as;
    2105                 :      67528 :     std::transform(orN.begin(), orN.end(), std::back_inserter(as), [](Node n) {
    2106                 :      67528 :       return n.negate();
    2107                 :      33764 :     });
    2108                 :            :     // No need to ensure that the expected node aggrees with `as` because we
    2109                 :            :     // are not providing an expected node.
    2110                 :            :     auto pf =
    2111                 :     135056 :         d_pnm->mkNode(ProofRule::NOT_AND, {d_pnm->mkScope(bot_pf, as)}, {});
    2112                 :      33764 :     pf = ensurePredTransform(d_pnm, pf, orN);
    2113                 :      33764 :     out.push_back(d_pfGen->mkTrustNode(orN, pf));
    2114                 :            :   }
    2115                 :            :   else
    2116                 :            :   {
    2117                 :      41217 :     out.push_back(TrustNode::mkTrustLemma(orN));
    2118                 :            :   }
    2119                 :      74981 : }
    2120                 :            : 
    2121                 :      70229 : void ConstraintDatabase::implies(std::vector<TrustNode>& out,
    2122                 :            :                                  ConstraintP a,
    2123                 :            :                                  ConstraintP b) const
    2124                 :            : {
    2125                 :     140458 :   Node la = a->getLiteral();
    2126                 :     140458 :   Node lb = b->getLiteral();
    2127                 :            : 
    2128         [ +  + ]:     140458 :   Node neg_la = (la.getKind() == Kind::NOT) ? la[0] : la.notNode();
    2129                 :            : 
    2130 [ -  + ][ -  + ]:      70229 :   Assert(lb != neg_la);
                 [ -  - ]
    2131 [ +  + ][ -  + ]:      70229 :   Assert(b->getNegation()->getType() == ConstraintType::LowerBound
         [ -  + ][ -  - ]
    2132                 :            :          || b->getNegation()->getType() == ConstraintType::UpperBound);
    2133                 :      70229 :   proveOr(out,
    2134                 :            :           a->getNegation(),
    2135                 :            :           b,
    2136                 :      70229 :           b->getNegation()->getType() == ConstraintType::LowerBound);
    2137                 :      70229 : }
    2138                 :            : 
    2139                 :       4752 : void ConstraintDatabase::mutuallyExclusive(std::vector<TrustNode>& out,
    2140                 :            :                                            ConstraintP a,
    2141                 :            :                                            ConstraintP b) const
    2142                 :            : {
    2143                 :       9504 :   Node la = a->getLiteral();
    2144                 :       9504 :   Node lb = b->getLiteral();
    2145                 :            : 
    2146                 :       9504 :   Node neg_la = la.negate();
    2147                 :       9504 :   Node neg_lb = lb.negate();
    2148                 :       4752 :   proveOr(out, a->getNegation(), b->getNegation(), true);
    2149                 :       4752 : }
    2150                 :            : 
    2151                 :     119003 : void ConstraintDatabase::outputUnateInequalityLemmas(
    2152                 :            :     std::vector<TrustNode>& out, ArithVar v) const
    2153                 :            : {
    2154                 :     119003 :   SortedConstraintMap& scm = getVariableSCM(v);
    2155                 :     119003 :   SortedConstraintMapConstIterator scm_iter = scm.begin();
    2156                 :     119003 :   SortedConstraintMapConstIterator scm_end = scm.end();
    2157                 :     119003 :   ConstraintP prev = NullConstraint;
    2158                 :            :   //get transitive unates
    2159                 :            :   //Only lower bounds or upperbounds should be done.
    2160         [ +  + ]:     380292 :   for(; scm_iter != scm_end; ++scm_iter){
    2161                 :     261289 :     const ValueCollection& vc = scm_iter->second;
    2162         [ +  + ]:     261289 :     if(vc.hasUpperBound()){
    2163                 :     123543 :       ConstraintP ub = vc.getUpperBound();
    2164         [ +  + ]:     123543 :       if(ub->hasLiteral()){
    2165         [ +  + ]:     123541 :         if(prev != NullConstraint){
    2166                 :      53089 :           implies(out, prev, ub);
    2167                 :            :         }
    2168                 :     123541 :         prev = ub;
    2169                 :            :       }
    2170                 :            :     }
    2171                 :            :   }
    2172                 :     119003 : }
    2173                 :            : 
    2174                 :     119003 : void ConstraintDatabase::outputUnateEqualityLemmas(std::vector<TrustNode>& out,
    2175                 :            :                                                    ArithVar v) const
    2176                 :            : {
    2177                 :     238006 :   vector<ConstraintP> equalities;
    2178                 :            : 
    2179                 :     119003 :   SortedConstraintMap& scm = getVariableSCM(v);
    2180                 :     119003 :   SortedConstraintMapConstIterator scm_iter = scm.begin();
    2181                 :     119003 :   SortedConstraintMapConstIterator scm_end = scm.end();
    2182                 :            : 
    2183         [ +  + ]:     380292 :   for(; scm_iter != scm_end; ++scm_iter){
    2184                 :     261289 :     const ValueCollection& vc = scm_iter->second;
    2185         [ +  + ]:     261289 :     if(vc.hasEquality()){
    2186                 :      37086 :       ConstraintP eq = vc.getEquality();
    2187         [ +  - ]:      37086 :       if(eq->hasLiteral()){
    2188                 :      37086 :         equalities.push_back(eq);
    2189                 :            :       }
    2190                 :            :     }
    2191                 :            :   }
    2192                 :            : 
    2193                 :     119003 :   vector<ConstraintP>::const_iterator i, j, eq_end = equalities.end();
    2194         [ +  + ]:     156089 :   for(i = equalities.begin(); i != eq_end; ++i){
    2195                 :      37086 :     ConstraintP at_i = *i;
    2196         [ +  + ]:      41838 :     for(j= i + 1; j != eq_end; ++j){
    2197                 :       4752 :       ConstraintP at_j = *j;
    2198                 :            : 
    2199                 :       4752 :       mutuallyExclusive(out, at_i, at_j);
    2200                 :            :     }
    2201                 :            :   }
    2202                 :            : 
    2203         [ +  + ]:     156089 :   for(i = equalities.begin(); i != eq_end; ++i){
    2204                 :      37086 :     ConstraintP eq = *i;
    2205                 :      37086 :     const ValueCollection& vc = eq->getValueCollection();
    2206 [ +  - ][ +  - ]:      74172 :     Assert(vc.hasEquality() && vc.getEquality()->hasLiteral());
         [ -  + ][ -  - ]
    2207                 :            : 
    2208 [ +  + ][ +  - ]:      37086 :     bool hasLB = vc.hasLowerBound() && vc.getLowerBound()->hasLiteral();
    2209 [ +  + ][ +  + ]:      37086 :     bool hasUB = vc.hasUpperBound() && vc.getUpperBound()->hasLiteral();
    2210                 :            : 
    2211         [ +  + ]:      37086 :     ConstraintP lb = hasLB ?
    2212                 :      37086 :       vc.getLowerBound() : eq->getStrictlyWeakerLowerBound(true, false);
    2213         [ +  + ]:      37086 :     ConstraintP ub = hasUB ?
    2214                 :      37086 :       vc.getUpperBound() : eq->getStrictlyWeakerUpperBound(true, false);
    2215                 :            : 
    2216 [ +  + ][ +  + ]:      37086 :     if(hasUB && hasLB && !eq->isSplit()){
         [ +  - ][ +  + ]
    2217                 :        550 :       out.push_back(eq->split());
    2218                 :            :     }
    2219         [ +  + ]:      37086 :     if(lb != NullConstraint){
    2220                 :       5742 :       implies(out, eq, lb);
    2221                 :            :     }
    2222         [ +  + ]:      37086 :     if(ub != NullConstraint){
    2223                 :      11398 :       implies(out, eq, ub);
    2224                 :            :     }
    2225                 :            :   }
    2226                 :     119003 : }
    2227                 :            : 
    2228                 :      27832 : void ConstraintDatabase::outputUnateEqualityLemmas(
    2229                 :            :     std::vector<TrustNode>& lemmas) const
    2230                 :            : {
    2231         [ +  + ]:     146835 :   for(ArithVar v = 0, N = d_varDatabases.size(); v < N; ++v){
    2232                 :     119003 :     outputUnateEqualityLemmas(lemmas, v);
    2233                 :            :   }
    2234                 :      27832 : }
    2235                 :            : 
    2236                 :      27832 : void ConstraintDatabase::outputUnateInequalityLemmas(
    2237                 :            :     std::vector<TrustNode>& lemmas) const
    2238                 :            : {
    2239         [ +  + ]:     146835 :   for(ArithVar v = 0, N = d_varDatabases.size(); v < N; ++v){
    2240                 :     119003 :     outputUnateInequalityLemmas(lemmas, v);
    2241                 :            :   }
    2242                 :      27832 : }
    2243                 :            : 
    2244                 :    8245720 : bool ConstraintDatabase::handleUnateProp(ConstraintP ant, ConstraintP cons){
    2245         [ +  + ]:    8245720 :   if(cons->negationHasProof()){
    2246         [ +  - ]:          2 :     Trace("arith::unate") << "handleUnate: " << ant << " implies " << cons << endl;
    2247                 :          2 :     cons->impliedByUnate(nodeManager(), ant, true);
    2248                 :          2 :     d_raiseConflict.raiseConflict(cons, InferenceId::ARITH_CONF_UNATE_PROP);
    2249                 :          2 :     return true;
    2250         [ +  + ]:    8245720 :   }else if(!cons->isTrue()){
    2251                 :    3783110 :     ++d_statistics.d_unatePropagateImplications;
    2252         [ +  - ]:    3783110 :     Trace("arith::unate") << "handleUnate: " << ant << " implies " << cons << endl;
    2253                 :    3783110 :     cons->impliedByUnate(nodeManager(), ant, false);
    2254                 :    3783110 :     cons->tryToPropagate();
    2255                 :    3783110 :     return false;
    2256                 :            :   } else {
    2257                 :    4462620 :     return false;
    2258                 :            :   }
    2259                 :            : }
    2260                 :            : 
    2261                 :    2507500 : void ConstraintDatabase::unatePropLowerBound(ConstraintP curr, ConstraintP prev){
    2262         [ +  - ]:    2507500 :   Trace("arith::unate") << "unatePropLowerBound " << curr << " " << prev << endl;
    2263 [ -  + ][ -  + ]:    2507500 :   Assert(curr != prev);
                 [ -  - ]
    2264 [ -  + ][ -  + ]:    2507500 :   Assert(curr != NullConstraint);
                 [ -  - ]
    2265                 :    2507500 :   bool hasPrev = ! (prev == NullConstraint);
    2266 [ +  + ][ -  + ]:    2507500 :   Assert(!hasPrev || curr->getValue() > prev->getValue());
         [ -  + ][ -  - ]
    2267                 :            : 
    2268                 :    2507500 :   ++d_statistics.d_unatePropagateCalls;
    2269                 :            : 
    2270                 :    2507500 :   const SortedConstraintMap& scm = curr->constraintSet();
    2271                 :    2507500 :   const SortedConstraintMapConstIterator scm_begin = scm.begin();
    2272                 :    2507500 :   SortedConstraintMapConstIterator scm_i = curr->d_variablePosition;
    2273                 :            : 
    2274                 :            :   //Ignore the first ValueCollection
    2275                 :            :   // NOPE: (>= p c) then (= p c) NOPE
    2276                 :            :   // NOPE: (>= p c) then (not (= p c)) NOPE
    2277                 :            : 
    2278         [ +  + ]:    9003900 :   while(scm_i != scm_begin){
    2279                 :    6984630 :     --scm_i; // move the iterator back
    2280                 :            : 
    2281                 :    6984630 :     const ValueCollection& vc = scm_i->second;
    2282                 :            : 
    2283                 :            :     //If it has the previous element, do nothing and stop!
    2284                 :    8906070 :     if(hasPrev &&
    2285         [ +  + ]:    1921440 :        vc.hasConstraintOfType(prev->getType())
    2286 [ +  + ][ +  + ]:    8906070 :        && vc.getConstraintOfType(prev->getType()) == prev){
                 [ +  + ]
    2287                 :     488224 :       break;
    2288                 :            :     }
    2289                 :            : 
    2290                 :            :     //Don't worry about implying the negation of upperbound.
    2291                 :            :     //These should all be handled by propagating the LowerBounds!
    2292         [ +  + ]:    6496400 :     if(vc.hasLowerBound()){
    2293                 :    2474190 :       ConstraintP lb = vc.getLowerBound();
    2294         [ -  + ]:    2474200 :       if(handleUnateProp(curr, lb)){ return; }
    2295                 :            :     }
    2296         [ +  + ]:    6496400 :     if(vc.hasDisequality()){
    2297                 :     545398 :       ConstraintP dis = vc.getDisequality();
    2298         [ +  + ]:     545398 :       if(handleUnateProp(curr, dis)){ return; }
    2299                 :            :     }
    2300                 :            :   }
    2301                 :            : }
    2302                 :            : 
    2303                 :    2272440 : void ConstraintDatabase::unatePropUpperBound(ConstraintP curr, ConstraintP prev){
    2304         [ +  - ]:    2272440 :   Trace("arith::unate") << "unatePropUpperBound " << curr << " " << prev << endl;
    2305 [ -  + ][ -  + ]:    2272440 :   Assert(curr != prev);
                 [ -  - ]
    2306 [ -  + ][ -  + ]:    2272440 :   Assert(curr != NullConstraint);
                 [ -  - ]
    2307                 :    2272440 :   bool hasPrev = ! (prev == NullConstraint);
    2308 [ +  + ][ -  + ]:    2272440 :   Assert(!hasPrev || curr->getValue() < prev->getValue());
         [ -  + ][ -  - ]
    2309                 :            : 
    2310                 :    2272440 :   ++d_statistics.d_unatePropagateCalls;
    2311                 :            : 
    2312                 :    2272440 :   const SortedConstraintMap& scm = curr->constraintSet();
    2313                 :    2272440 :   const SortedConstraintMapConstIterator scm_end = scm.end();
    2314                 :    2272440 :   SortedConstraintMapConstIterator scm_i = curr->d_variablePosition;
    2315                 :    2272440 :   ++scm_i;
    2316         [ +  + ]:    8853730 :   for(; scm_i != scm_end; ++scm_i){
    2317                 :    6964490 :     const ValueCollection& vc = scm_i->second;
    2318                 :            : 
    2319                 :            :     //If it has the previous element, do nothing and stop!
    2320                 :    8226390 :     if(hasPrev &&
    2321 [ +  + ][ +  + ]:    7757000 :        vc.hasConstraintOfType(prev->getType()) &&
                 [ +  + ]
    2322         [ +  + ]:     792510 :        vc.getConstraintOfType(prev->getType()) == prev){
    2323                 :     383203 :       break;
    2324                 :            :     }
    2325                 :            :     //Don't worry about implying the negation of upperbound.
    2326                 :            :     //These should all be handled by propagating the UpperBounds!
    2327         [ +  + ]:    6581280 :     if(vc.hasUpperBound()){
    2328                 :    2563470 :       ConstraintP ub = vc.getUpperBound();
    2329         [ -  + ]:    2563470 :       if(handleUnateProp(curr, ub)){ return; }
    2330                 :            :     }
    2331         [ +  + ]:    6581280 :     if(vc.hasDisequality()){
    2332                 :     413917 :       ConstraintP dis = vc.getDisequality();
    2333         [ -  + ]:     413917 :       if(handleUnateProp(curr, dis)){ return; }
    2334                 :            :     }
    2335                 :            :   }
    2336                 :            : }
    2337                 :            : 
    2338                 :    1763270 : void ConstraintDatabase::unatePropEquality(ConstraintP curr, ConstraintP prevLB, ConstraintP prevUB){
    2339         [ +  - ]:    1763270 :   Trace("arith::unate") << "unatePropEquality " << curr << " " << prevLB << " " << prevUB << endl;
    2340 [ -  + ][ -  + ]:    1763270 :   Assert(curr != prevLB);
                 [ -  - ]
    2341 [ -  + ][ -  + ]:    1763270 :   Assert(curr != prevUB);
                 [ -  - ]
    2342 [ -  + ][ -  + ]:    1763270 :   Assert(curr != NullConstraint);
                 [ -  - ]
    2343                 :    1763270 :   bool hasPrevLB = ! (prevLB == NullConstraint);
    2344                 :    1763270 :   bool hasPrevUB = ! (prevUB == NullConstraint);
    2345 [ +  + ][ -  + ]:    1763270 :   Assert(!hasPrevLB || curr->getValue() >= prevLB->getValue());
         [ -  + ][ -  - ]
    2346 [ +  + ][ -  + ]:    1763270 :   Assert(!hasPrevUB || curr->getValue() <= prevUB->getValue());
         [ -  + ][ -  - ]
    2347                 :            : 
    2348                 :    1763270 :   ++d_statistics.d_unatePropagateCalls;
    2349                 :            : 
    2350                 :    1763270 :   const SortedConstraintMap& scm = curr->constraintSet();
    2351                 :    1763270 :   SortedConstraintMapConstIterator scm_curr = curr->d_variablePosition;
    2352         [ +  + ]:    1763270 :   SortedConstraintMapConstIterator scm_last = hasPrevUB ? prevUB->d_variablePosition : scm.end();
    2353                 :    1763270 :   SortedConstraintMapConstIterator scm_i;
    2354         [ +  + ]:    1763270 :   if(hasPrevLB){
    2355                 :     220215 :     scm_i = prevLB->d_variablePosition;
    2356         [ +  + ]:     220215 :     if(scm_i != scm_curr){ // If this does not move this past scm_curr, move it one forward
    2357                 :      55502 :       ++scm_i;
    2358                 :            :     }
    2359                 :            :   }else{
    2360                 :    1543060 :     scm_i = scm.begin();
    2361                 :            :   }
    2362                 :            : 
    2363         [ +  + ]:    2947200 :   for(; scm_i != scm_curr; ++scm_i){
    2364                 :            :     // between the previous LB and the curr
    2365                 :    1183930 :     const ValueCollection& vc = scm_i->second;
    2366                 :            : 
    2367                 :            :     //Don't worry about implying the negation of upperbound.
    2368                 :            :     //These should all be handled by propagating the LowerBounds!
    2369         [ +  + ]:    1183930 :     if(vc.hasLowerBound()){
    2370                 :     368227 :       ConstraintP lb = vc.getLowerBound();
    2371         [ -  + ]:     368227 :       if(handleUnateProp(curr, lb)){ return; }
    2372                 :            :     }
    2373         [ +  + ]:    1183930 :     if(vc.hasDisequality()){
    2374                 :     325984 :       ConstraintP dis = vc.getDisequality();
    2375         [ -  + ]:     325984 :       if(handleUnateProp(curr, dis)){ return; }
    2376                 :            :     }
    2377                 :            :   }
    2378 [ -  + ][ -  + ]:    1763270 :   Assert(scm_i == scm_curr);
                 [ -  - ]
    2379 [ +  + ][ +  + ]:    1763270 :   if(!hasPrevUB || scm_i != scm_last){
                 [ +  + ]
    2380                 :    1715990 :     ++scm_i;
    2381                 :            :   } // hasPrevUB implies scm_i != scm_last
    2382                 :            : 
    2383         [ +  + ]:    4409920 :   for(; scm_i != scm_last; ++scm_i){
    2384                 :            :     // between the curr and the previous UB imply the upperbounds and disequalities.
    2385                 :    2646650 :     const ValueCollection& vc = scm_i->second;
    2386                 :            : 
    2387                 :            :     //Don't worry about implying the negation of upperbound.
    2388                 :            :     //These should all be handled by propagating the UpperBounds!
    2389         [ +  + ]:    2646650 :     if(vc.hasUpperBound()){
    2390                 :     902098 :       ConstraintP ub = vc.getUpperBound();
    2391         [ -  + ]:     902098 :       if(handleUnateProp(curr, ub)){ return; }
    2392                 :            :     }
    2393         [ +  + ]:    2646650 :     if(vc.hasDisequality()){
    2394                 :     652435 :       ConstraintP dis = vc.getDisequality();
    2395         [ -  + ]:     652435 :       if(handleUnateProp(curr, dis)){ return; }
    2396                 :            :     }
    2397                 :            :   }
    2398                 :            : }
    2399                 :            : 
    2400                 :    2674510 : std::pair<int, int> Constraint::unateFarkasSigns(ConstraintCP ca, ConstraintCP cb){
    2401                 :    2674510 :   ConstraintType a = ca->getType();
    2402                 :    2674510 :   ConstraintType b = cb->getType();
    2403                 :            : 
    2404 [ -  + ][ -  + ]:    2674510 :   Assert(a != Disequality);
                 [ -  - ]
    2405 [ -  + ][ -  + ]:    2674510 :   Assert(b != Disequality);
                 [ -  - ]
    2406                 :            : 
    2407 [ +  + ][ +  + ]:    2674510 :   int a_sgn = (a == LowerBound) ? -1 : ((a == UpperBound) ? 1 : 0);
    2408 [ +  + ][ +  + ]:    2674510 :   int b_sgn = (b == LowerBound) ? -1 : ((b == UpperBound) ? 1 : 0);
    2409                 :            : 
    2410 [ +  + ][ +  + ]:    2674510 :   if(a_sgn == 0 && b_sgn == 0){
    2411 [ -  + ][ -  + ]:     550955 :     Assert(a == Equality);
                 [ -  - ]
    2412 [ -  + ][ -  + ]:     550955 :     Assert(b == Equality);
                 [ -  - ]
    2413 [ -  + ][ -  + ]:     550955 :     Assert(ca->getValue() != cb->getValue());
                 [ -  - ]
    2414         [ +  + ]:     550955 :     if(ca->getValue() < cb->getValue()){
    2415                 :     175404 :       a_sgn = 1;
    2416                 :     175404 :       b_sgn = -1;
    2417                 :            :     }else{
    2418                 :     375551 :       a_sgn = -1;
    2419                 :     375551 :       b_sgn = 1;
    2420                 :            :     }
    2421         [ +  + ]:    2123560 :   }else if(a_sgn == 0){
    2422 [ -  + ][ -  + ]:     421777 :     Assert(b_sgn != 0);
                 [ -  - ]
    2423 [ -  + ][ -  + ]:     421777 :     Assert(a == Equality);
                 [ -  - ]
    2424                 :     421777 :     a_sgn = -b_sgn;
    2425         [ +  + ]:    1701780 :   }else if(b_sgn == 0){
    2426 [ -  + ][ -  + ]:     639119 :     Assert(a_sgn != 0);
                 [ -  - ]
    2427 [ -  + ][ -  + ]:     639119 :     Assert(b == Equality);
                 [ -  - ]
    2428                 :     639119 :     b_sgn = -a_sgn;
    2429                 :            :   }
    2430 [ -  + ][ -  + ]:    2674510 :   Assert(a_sgn != 0);
                 [ -  - ]
    2431 [ -  + ][ -  + ]:    2674510 :   Assert(b_sgn != 0);
                 [ -  - ]
    2432                 :            : 
    2433         [ +  - ]:    5349030 :   Trace("arith::unateFarkasSigns") << "Constraint::unateFarkasSigns("<<a <<", " << b << ") -> "
    2434                 :    2674510 :                                    << "("<<a_sgn<<", "<< b_sgn <<")"<< endl;
    2435                 :    5349030 :   return make_pair(a_sgn, b_sgn);
    2436                 :            : }
    2437                 :            : 
    2438                 :            : }  // namespace arith
    2439                 :            : }  // namespace theory
    2440                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14