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: 1156 1559 74.2 %
Date: 2026-05-02 10:46:03 Functions: 92 126 73.0 %
Branches: 794 1759 45.1 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * This file is part of the cvc5 project.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
       5                 :            :  * in the top-level source directory and their institutional affiliations.
       6                 :            :  * All rights reserved.  See the file COPYING in the top-level source
       7                 :            :  * directory for licensing information.
       8                 :            :  * ****************************************************************************
       9                 :            :  *
      10                 :            :  * [[ Add one-line brief description here ]]
      11                 :            :  *
      12                 :            :  * [[ Add lengthier description here ]]
      13                 :            :  * \todo document this file
      14                 :            :  */
      15                 :            : #include "theory/arith/linear/constraint.h"
      16                 :            : 
      17                 :            : #include <algorithm>
      18                 :            : #include <ostream>
      19                 :            : #include <unordered_set>
      20                 :            : 
      21                 :            : #include "base/output.h"
      22                 :            : #include "options/smt_options.h"
      23                 :            : #include "proof/eager_proof_generator.h"
      24                 :            : #include "proof/proof_node_manager.h"
      25                 :            : #include "smt/env.h"
      26                 :            : #include "theory/arith/arith_proof_utilities.h"
      27                 :            : #include "theory/arith/arith_utilities.h"
      28                 :            : #include "theory/arith/linear/congruence_manager.h"
      29                 :            : #include "theory/arith/linear/normal_form.h"
      30                 :            : #include "theory/arith/linear/partial_model.h"
      31                 :            : #include "theory/builtin/proof_checker.h"
      32                 :            : #include "theory/rewriter.h"
      33                 :            : 
      34                 :            : using namespace std;
      35                 :            : using namespace cvc5::internal::kind;
      36                 :            : 
      37                 :            : namespace cvc5::internal {
      38                 :            : namespace theory {
      39                 :            : namespace arith::linear {
      40                 :            : 
      41                 :          0 : ConstraintRule::ConstraintRule()
      42                 :          0 :     : d_constraint(NullConstraint),
      43                 :          0 :       d_proofType(NoAP),
      44                 :          0 :       d_antecedentEnd(AntecedentIdSentinel)
      45                 :            : {
      46                 :          0 :   d_farkasCoefficients = RationalVectorCPSentinel;
      47                 :          0 : }
      48                 :            : 
      49                 :    9510349 : ConstraintRule::ConstraintRule(ConstraintP con, ArithProofType pt)
      50                 :    9510349 :     : d_constraint(con), d_proofType(pt), d_antecedentEnd(AntecedentIdSentinel)
      51                 :            : {
      52                 :    9510349 :   d_farkasCoefficients = RationalVectorCPSentinel;
      53                 :    9510349 : }
      54                 :    3261871 : ConstraintRule::ConstraintRule(ConstraintP con,
      55                 :            :                                ArithProofType pt,
      56                 :    3261871 :                                AntecedentId antecedentEnd)
      57                 :    3261871 :     : d_constraint(con), d_proofType(pt), d_antecedentEnd(antecedentEnd)
      58                 :            : {
      59                 :    3261871 :   d_farkasCoefficients = RationalVectorCPSentinel;
      60                 :    3261871 : }
      61                 :            : 
      62                 :    3787921 : ConstraintRule::ConstraintRule(ConstraintP con,
      63                 :            :                                ArithProofType pt,
      64                 :            :                                AntecedentId antecedentEnd,
      65                 :    3787921 :                                RationalVectorCP coeffs)
      66                 :    3787921 :     : d_constraint(con), d_proofType(pt), d_antecedentEnd(antecedentEnd)
      67                 :            : {
      68 [ +  + ][ +  - ]:    3787921 :   Assert(con->isProofProducing() || coeffs == RationalVectorCPSentinel);
         [ -  + ][ -  + ]
                 [ -  - ]
      69                 :    3787921 :   d_farkasCoefficients = coeffs;
      70                 :    3787921 : }
      71                 :            : 
      72                 :            : /** Given a simplifiedKind this returns the corresponding ConstraintType. */
      73                 :            : // ConstraintType constraintTypeOfLiteral(Kind k);
      74                 :    1190136 : ConstraintType Constraint::constraintTypeOfComparison(const Comparison& cmp)
      75                 :            : {
      76                 :    1190136 :   Kind k = cmp.comparisonKind();
      77 [ +  + ][ +  + ]:    1190136 :   switch (k)
                    [ - ]
      78                 :            :   {
      79                 :     321163 :     case Kind::LT:
      80                 :            :     case Kind::LEQ:
      81                 :            :     {
      82                 :     321163 :       Polynomial l = cmp.getLeft();
      83         [ +  + ]:     321163 :       if (l.leadingCoefficientIsPositive())
      84                 :            :       {  // (< x c)
      85                 :     278436 :         return UpperBound;
      86                 :            :       }
      87                 :            :       else
      88                 :            :       {
      89                 :      42727 :         return LowerBound;  // (< (-x) c)
      90                 :            :       }
      91                 :     321163 :     }
      92                 :     323946 :     case Kind::GT:
      93                 :            :     case Kind::GEQ:
      94                 :            :     {
      95                 :     323946 :       Polynomial l = cmp.getLeft();
      96         [ +  + ]:     323946 :       if (l.leadingCoefficientIsPositive())
      97                 :            :       {
      98                 :     280839 :         return LowerBound;  // (> x c)
      99                 :            :       }
     100                 :            :       else
     101                 :            :       {
     102                 :      43107 :         return UpperBound;  // (> (-x) c)
     103                 :            :       }
     104                 :     323946 :     }
     105                 :     272759 :     case Kind::EQUAL: return Equality;
     106                 :     272268 :     case Kind::DISTINCT: return Disequality;
     107                 :          0 :     default: Unhandled() << k;
     108                 :            :   }
     109                 :            : }
     110                 :            : 
     111                 :    1501464 : Constraint::Constraint(ArithVar x,
     112                 :            :                        ConstraintType t,
     113                 :            :                        const DeltaRational& v,
     114                 :    1501464 :                        bool produceProofs)
     115                 :    1501464 :     : d_variable(x),
     116                 :    1501464 :       d_type(t),
     117                 :    1501464 :       d_value(v),
     118                 :    1501464 :       d_database(nullptr),
     119                 :    1501464 :       d_literal(Node::null()),
     120                 :    1501464 :       d_negation(NullConstraint),
     121                 :    1501464 :       d_canBePropagated(false),
     122                 :    1501464 :       d_assertionOrder(AssertionOrderSentinel),
     123                 :    1501464 :       d_witness(TNode::null()),
     124                 :    1501464 :       d_crid(ConstraintRuleIdSentinel),
     125                 :    1501464 :       d_split(false),
     126                 :    1501464 :       d_variablePosition(),
     127                 :    1501464 :       d_produceProofs(produceProofs)
     128                 :            : {
     129 [ -  + ][ -  + ]:    1501464 :   Assert(!initialized());
                 [ -  - ]
     130                 :    1501464 : }
     131                 :            : 
     132                 :          0 : std::ostream& operator<<(std::ostream& o, const ArithProofType apt)
     133                 :            : {
     134 [ -  - ][ -  - ]:          0 :   switch (apt)
         [ -  - ][ -  - ]
                    [ - ]
     135                 :            :   {
     136                 :          0 :     case NoAP: o << "NoAP"; break;
     137                 :          0 :     case AssumeAP: o << "AssumeAP"; break;
     138                 :          0 :     case InternalAssumeAP: o << "InternalAssumeAP"; break;
     139                 :          0 :     case FarkasAP: o << "FarkasAP"; break;
     140                 :          0 :     case TrichotomyAP: o << "TrichotomyAP"; break;
     141                 :          0 :     case EqualityEngineAP: o << "EqualityEngineAP"; break;
     142                 :          0 :     case IntTightenAP: o << "IntTightenAP"; break;
     143                 :          0 :     case IntHoleAP: o << "IntHoleAP"; break;
     144                 :          0 :     default: break;
     145                 :            :   }
     146                 :          0 :   return o;
     147                 :            : }
     148                 :            : 
     149                 :          0 : std::ostream& operator<<(std::ostream& o, const ConstraintCP c)
     150                 :            : {
     151         [ -  - ]:          0 :   if (c == NullConstraint)
     152                 :            :   {
     153                 :          0 :     return o << "NullConstraint";
     154                 :            :   }
     155                 :            :   else
     156                 :            :   {
     157                 :          0 :     return o << *c;
     158                 :            :   }
     159                 :            : }
     160                 :            : 
     161                 :          0 : std::ostream& operator<<(std::ostream& o, const ConstraintP c)
     162                 :            : {
     163         [ -  - ]:          0 :   if (c == NullConstraint)
     164                 :            :   {
     165                 :          0 :     return o << "NullConstraint";
     166                 :            :   }
     167                 :            :   else
     168                 :            :   {
     169                 :          0 :     return o << *c;
     170                 :            :   }
     171                 :            : }
     172                 :            : 
     173                 :          0 : std::ostream& operator<<(std::ostream& o, const ConstraintType t)
     174                 :            : {
     175 [ -  - ][ -  - ]:          0 :   switch (t)
                    [ - ]
     176                 :            :   {
     177                 :          0 :     case LowerBound: return o << ">=";
     178                 :          0 :     case UpperBound: return o << "<=";
     179                 :          0 :     case Equality: return o << "=";
     180                 :          0 :     case Disequality: return o << "!=";
     181                 :          0 :     default: Unreachable();
     182                 :            :   }
     183                 :            : }
     184                 :            : 
     185                 :          0 : std::ostream& operator<<(std::ostream& o, const Constraint& c)
     186                 :            : {
     187                 :          0 :   o << c.getVariable() << ' ' << c.getType() << ' ' << c.getValue();
     188         [ -  - ]:          0 :   if (c.hasLiteral())
     189                 :            :   {
     190                 :          0 :     o << "(node " << c.getLiteral() << ')';
     191                 :            :   }
     192                 :          0 :   return o;
     193                 :            : }
     194                 :            : 
     195                 :          0 : std::ostream& operator<<(std::ostream& o, const ValueCollection& vc)
     196                 :            : {
     197                 :          0 :   o << "{";
     198                 :          0 :   bool pending = false;
     199         [ -  - ]:          0 :   if (vc.hasEquality())
     200                 :            :   {
     201                 :          0 :     o << "eq: " << vc.getEquality();
     202                 :          0 :     pending = true;
     203                 :            :   }
     204         [ -  - ]:          0 :   if (vc.hasLowerBound())
     205                 :            :   {
     206         [ -  - ]:          0 :     if (pending)
     207                 :            :     {
     208                 :          0 :       o << ", ";
     209                 :            :     }
     210                 :          0 :     o << "lb: " << vc.getLowerBound();
     211                 :          0 :     pending = true;
     212                 :            :   }
     213         [ -  - ]:          0 :   if (vc.hasUpperBound())
     214                 :            :   {
     215         [ -  - ]:          0 :     if (pending)
     216                 :            :     {
     217                 :          0 :       o << ", ";
     218                 :            :     }
     219                 :          0 :     o << "ub: " << vc.getUpperBound();
     220                 :          0 :     pending = true;
     221                 :            :   }
     222         [ -  - ]:          0 :   if (vc.hasDisequality())
     223                 :            :   {
     224         [ -  - ]:          0 :     if (pending)
     225                 :            :     {
     226                 :          0 :       o << ", ";
     227                 :            :     }
     228                 :          0 :     o << "de: " << vc.getDisequality();
     229                 :            :   }
     230                 :          0 :   return o << "}";
     231                 :            : }
     232                 :            : 
     233                 :          0 : std::ostream& operator<<(std::ostream& o, const ConstraintCPVec& v)
     234                 :            : {
     235                 :          0 :   o << "[" << v.size() << "x";
     236                 :          0 :   ConstraintCPVec::const_iterator i, end;
     237         [ -  - ]:          0 :   for (i = v.begin(), end = v.end(); i != end; ++i)
     238                 :            :   {
     239                 :          0 :     ConstraintCP c = *i;
     240                 :          0 :     o << ", " << (*c);
     241                 :            :   }
     242                 :          0 :   o << "]";
     243                 :          0 :   return o;
     244                 :            : }
     245                 :            : 
     246                 :    4399662 : ValueCollection::ValueCollection()
     247                 :    4399662 :     : d_lowerBound(NullConstraint),
     248                 :    4399662 :       d_upperBound(NullConstraint),
     249                 :    4399662 :       d_equality(NullConstraint),
     250                 :    4399662 :       d_disequality(NullConstraint)
     251                 :            : {
     252                 :    4399662 : }
     253                 :            : 
     254                 :   33215362 : bool ValueCollection::hasLowerBound() const
     255                 :            : {
     256                 :   33215362 :   return d_lowerBound != NullConstraint;
     257                 :            : }
     258                 :            : 
     259                 :   36590249 : bool ValueCollection::hasUpperBound() const
     260                 :            : {
     261                 :   36590249 :   return d_upperBound != NullConstraint;
     262                 :            : }
     263                 :            : 
     264                 :   10115575 : bool ValueCollection::hasEquality() const
     265                 :            : {
     266                 :   10115575 :   return d_equality != NullConstraint;
     267                 :            : }
     268                 :            : 
     269                 :   28533293 : bool ValueCollection::hasDisequality() const
     270                 :            : {
     271                 :   28533293 :   return d_disequality != NullConstraint;
     272                 :            : }
     273                 :            : 
     274                 :    6125370 : ConstraintP ValueCollection::getLowerBound() const
     275                 :            : {
     276 [ -  + ][ -  + ]:    6125370 :   Assert(hasLowerBound());
                 [ -  - ]
     277                 :    6125370 :   return d_lowerBound;
     278                 :            : }
     279                 :            : 
     280                 :    6560790 : ConstraintP ValueCollection::getUpperBound() const
     281                 :            : {
     282 [ -  + ][ -  + ]:    6560790 :   Assert(hasUpperBound());
                 [ -  - ]
     283                 :    6560790 :   return d_upperBound;
     284                 :            : }
     285                 :            : 
     286                 :     844541 : ConstraintP ValueCollection::getEquality() const
     287                 :            : {
     288 [ -  + ][ -  + ]:     844541 :   Assert(hasEquality());
                 [ -  - ]
     289                 :     844541 :   return d_equality;
     290                 :            : }
     291                 :            : 
     292                 :    3846875 : ConstraintP ValueCollection::getDisequality() const
     293                 :            : {
     294 [ -  + ][ -  + ]:    3846875 :   Assert(hasDisequality());
                 [ -  - ]
     295                 :    3846875 :   return d_disequality;
     296                 :            : }
     297                 :            : 
     298                 :    1021085 : void ValueCollection::push_into(std::vector<ConstraintP>& vec) const
     299                 :            : {
     300         [ +  - ]:    1021085 :   Trace("arith::constraint") << "push_into " << *this << endl;
     301         [ +  + ]:    1021085 :   if (hasEquality())
     302                 :            :   {
     303                 :     280393 :     vec.push_back(d_equality);
     304                 :            :   }
     305         [ +  + ]:    1021085 :   if (hasLowerBound())
     306                 :            :   {
     307                 :     468248 :     vec.push_back(d_lowerBound);
     308                 :            :   }
     309         [ +  + ]:    1021085 :   if (hasUpperBound())
     310                 :            :   {
     311                 :     468248 :     vec.push_back(d_upperBound);
     312                 :            :   }
     313         [ +  + ]:    1021085 :   if (hasDisequality())
     314                 :            :   {
     315                 :     280393 :     vec.push_back(d_disequality);
     316                 :            :   }
     317                 :    1021085 : }
     318                 :            : 
     319                 :          0 : ValueCollection ValueCollection::mkFromConstraint(ConstraintP c)
     320                 :            : {
     321                 :          0 :   ValueCollection ret;
     322                 :          0 :   Assert(ret.empty());
     323 [ -  - ][ -  - ]:          0 :   switch (c->getType())
                    [ - ]
     324                 :            :   {
     325                 :          0 :     case LowerBound: ret.d_lowerBound = c; break;
     326                 :          0 :     case UpperBound: ret.d_upperBound = c; break;
     327                 :          0 :     case Equality: ret.d_equality = c; break;
     328                 :          0 :     case Disequality: ret.d_disequality = c; break;
     329                 :          0 :     default: Unreachable();
     330                 :            :   }
     331                 :          0 :   return ret;
     332                 :            : }
     333                 :            : 
     334                 :    7313453 : bool ValueCollection::hasConstraintOfType(ConstraintType t) const
     335                 :            : {
     336 [ +  + ][ +  - ]:    7313453 :   switch (t)
                    [ - ]
     337                 :            :   {
     338                 :    2424656 :     case LowerBound: return hasLowerBound();
     339                 :    3943402 :     case UpperBound: return hasUpperBound();
     340                 :     945395 :     case Equality: return hasEquality();
     341                 :          0 :     case Disequality: return hasDisequality();
     342                 :          0 :     default: Unreachable();
     343                 :            :   }
     344                 :            : }
     345                 :            : 
     346                 :     492237 : ArithVar ValueCollection::getVariable() const
     347                 :            : {
     348 [ -  + ][ -  + ]:     492237 :   Assert(!empty());
                 [ -  - ]
     349                 :     492237 :   return nonNull()->getVariable();
     350                 :            : }
     351                 :            : 
     352                 :     492237 : const DeltaRational& ValueCollection::getValue() const
     353                 :            : {
     354 [ -  + ][ -  + ]:     492237 :   Assert(!empty());
                 [ -  - ]
     355                 :     492237 :   return nonNull()->getValue();
     356                 :            : }
     357                 :            : 
     358                 :    1498190 : void ValueCollection::add(ConstraintP c)
     359                 :            : {
     360 [ -  + ][ -  + ]:    1498190 :   Assert(c != NullConstraint);
                 [ -  - ]
     361                 :            : 
     362 [ +  + ][ +  - ]:    1498190 :   Assert(empty() || getVariable() == c->getVariable());
         [ -  + ][ -  + ]
                 [ -  - ]
     363 [ +  + ][ +  - ]:    1498190 :   Assert(empty() || getValue() == c->getValue());
         [ -  + ][ -  + ]
                 [ -  - ]
     364                 :            : 
     365 [ +  + ][ +  + ]:    1498190 :   switch (c->getType())
                    [ - ]
     366                 :            :   {
     367                 :     468590 :     case LowerBound:
     368 [ -  + ][ -  + ]:     468590 :       Assert(!hasLowerBound());
                 [ -  - ]
     369                 :     468590 :       d_lowerBound = c;
     370                 :     468590 :       break;
     371                 :     280505 :     case Equality:
     372 [ -  + ][ -  + ]:     280505 :       Assert(!hasEquality());
                 [ -  - ]
     373                 :     280505 :       d_equality = c;
     374                 :     280505 :       break;
     375                 :     468590 :     case UpperBound:
     376 [ -  + ][ -  + ]:     468590 :       Assert(!hasUpperBound());
                 [ -  - ]
     377                 :     468590 :       d_upperBound = c;
     378                 :     468590 :       break;
     379                 :     280505 :     case Disequality:
     380 [ -  + ][ -  + ]:     280505 :       Assert(!hasDisequality());
                 [ -  - ]
     381                 :     280505 :       d_disequality = c;
     382                 :     280505 :       break;
     383                 :          0 :     default: Unreachable();
     384                 :            :   }
     385                 :    1498190 : }
     386                 :            : 
     387                 :    5436604 : ConstraintP ValueCollection::getConstraintOfType(ConstraintType t) const
     388                 :            : {
     389 [ +  + ][ +  - ]:    5436604 :   switch (t)
                    [ - ]
     390                 :            :   {
     391 [ -  + ][ -  + ]:    1458334 :     case LowerBound: Assert(hasLowerBound()); return d_lowerBound;
                 [ -  - ]
     392 [ -  + ][ -  + ]:     664890 :     case Equality: Assert(hasEquality()); return d_equality;
                 [ -  - ]
     393 [ -  + ][ -  + ]:    3313380 :     case UpperBound: Assert(hasUpperBound()); return d_upperBound;
                 [ -  - ]
     394                 :          0 :     case Disequality: Assert(hasDisequality()); return d_disequality;
     395                 :          0 :     default: Unreachable();
     396                 :            :   }
     397                 :            : }
     398                 :            : 
     399                 :    1497282 : void ValueCollection::remove(ConstraintType t)
     400                 :            : {
     401 [ +  + ][ +  + ]:    1497282 :   switch (t)
                    [ - ]
     402                 :            :   {
     403                 :     468248 :     case LowerBound:
     404 [ -  + ][ -  + ]:     468248 :       Assert(hasLowerBound());
                 [ -  - ]
     405                 :     468248 :       d_lowerBound = NullConstraint;
     406                 :     468248 :       break;
     407                 :     280393 :     case Equality:
     408 [ -  + ][ -  + ]:     280393 :       Assert(hasEquality());
                 [ -  - ]
     409                 :     280393 :       d_equality = NullConstraint;
     410                 :     280393 :       break;
     411                 :     468248 :     case UpperBound:
     412 [ -  + ][ -  + ]:     468248 :       Assert(hasUpperBound());
                 [ -  - ]
     413                 :     468248 :       d_upperBound = NullConstraint;
     414                 :     468248 :       break;
     415                 :     280393 :     case Disequality:
     416 [ -  + ][ -  + ]:     280393 :       Assert(hasDisequality());
                 [ -  - ]
     417                 :     280393 :       d_disequality = NullConstraint;
     418                 :     280393 :       break;
     419                 :          0 :     default: Unreachable();
     420                 :            :   }
     421                 :    1497282 : }
     422                 :            : 
     423                 :    5478136 : bool ValueCollection::empty() const
     424                 :            : {
     425 [ +  + ][ +  + ]:    8542697 :   return !(hasLowerBound() || hasUpperBound() || hasEquality()
                 [ +  + ]
     426         [ +  - ]:    8542697 :            || hasDisequality());
     427                 :            : }
     428                 :            : 
     429                 :     984474 : ConstraintP ValueCollection::nonNull() const
     430                 :            : {
     431                 :            :   // This can be optimized by caching, but this is not necessary yet!
     432                 :            :   /* "Premature optimization is the root of all evil." */
     433         [ +  + ]:     984474 :   if (hasLowerBound())
     434                 :            :   {
     435                 :     312320 :     return d_lowerBound;
     436                 :            :   }
     437         [ +  + ]:     672154 :   else if (hasUpperBound())
     438                 :            :   {
     439                 :      90054 :     return d_upperBound;
     440                 :            :   }
     441         [ +  - ]:     582100 :   else if (hasEquality())
     442                 :            :   {
     443                 :     582100 :     return d_equality;
     444                 :            :   }
     445         [ -  - ]:          0 :   else if (hasDisequality())
     446                 :            :   {
     447                 :          0 :     return d_disequality;
     448                 :            :   }
     449                 :            :   else
     450                 :            :   {
     451                 :          0 :     return NullConstraint;
     452                 :            :   }
     453                 :            : }
     454                 :            : 
     455                 :    5327615 : bool Constraint::initialized() const { return d_database != nullptr; }
     456                 :            : 
     457                 :          0 : const ConstraintDatabase& Constraint::getDatabase() const
     458                 :            : {
     459                 :          0 :   Assert(initialized());
     460                 :          0 :   return *d_database;
     461                 :            : }
     462                 :            : 
     463                 :    1498190 : void Constraint::initialize(ConstraintDatabase* db,
     464                 :            :                             SortedConstraintMapIterator v,
     465                 :            :                             ConstraintP negation)
     466                 :            : {
     467 [ -  + ][ -  + ]:    1498190 :   Assert(!initialized());
                 [ -  - ]
     468                 :    1498190 :   d_database = db;
     469                 :    1498190 :   d_variablePosition = v;
     470                 :    1498190 :   d_negation = negation;
     471                 :    1498190 : }
     472                 :            : 
     473                 :    3001112 : Constraint::~Constraint()
     474                 :            : {
     475                 :            :   // Call this instead of safeToGarbageCollect()
     476 [ -  + ][ -  + ]:    1500556 :   Assert(!contextDependentDataIsSet());
     477                 :            : 
     478         [ +  + ]:    1500556 :   if (initialized())
     479                 :            :   {
     480                 :    1497282 :     ValueCollection& vc = d_variablePosition->second;
     481         [ +  - ]:    1497282 :     Trace("arith::constraint") << "removing" << vc << endl;
     482                 :            : 
     483                 :    1497282 :     vc.remove(getType());
     484                 :            : 
     485         [ +  + ]:    1497282 :     if (vc.empty())
     486                 :            :     {
     487         [ +  - ]:    1021085 :       Trace("arith::constraint") << "erasing" << vc << endl;
     488                 :            :       SortedConstraintMap& perVariable =
     489                 :    1021085 :           d_database->getVariableSCM(getVariable());
     490                 :    1021085 :       perVariable.erase(d_variablePosition);
     491                 :            :     }
     492                 :            : 
     493         [ +  + ]:    1497282 :     if (hasLiteral())
     494                 :            :     {
     495                 :    1192672 :       d_database->d_nodetoConstraintMap.erase(getLiteral());
     496                 :            :     }
     497                 :            :   }
     498                 :    1500556 : }
     499                 :            : 
     500                 :   45677827 : const ConstraintRule& Constraint::getConstraintRule() const
     501                 :            : {
     502 [ -  + ][ -  + ]:   45677827 :   Assert(hasProof());
                 [ -  - ]
     503                 :   45677827 :   return d_database->d_watches->d_constraintProofs[d_crid];
     504                 :            : }
     505                 :            : 
     506                 :    5908766 : const ValueCollection& Constraint::getValueCollection() const
     507                 :            : {
     508                 :    5908766 :   return d_variablePosition->second;
     509                 :            : }
     510                 :            : 
     511                 :     146831 : ConstraintP Constraint::getCeiling()
     512                 :            : {
     513         [ +  - ]:     146831 :   Trace("getCeiling") << "Constraint_::getCeiling on " << *this << endl;
     514 [ -  + ][ -  + ]:     146831 :   Assert(getValue().getInfinitesimalPart().sgn() > 0);
                 [ -  - ]
     515                 :            : 
     516                 :     293662 :   const DeltaRational ceiling(getValue().ceiling());
     517                 :     293662 :   return d_database->getConstraint(getVariable(), getType(), ceiling);
     518                 :     146831 : }
     519                 :            : 
     520                 :    2499115 : ConstraintP Constraint::getFloor()
     521                 :            : {
     522 [ -  + ][ -  + ]:    2499115 :   Assert(getValue().getInfinitesimalPart().sgn() < 0);
                 [ -  - ]
     523                 :            : 
     524                 :    4998230 :   const DeltaRational floor(Rational(getValue().floor()));
     525                 :    4998230 :   return d_database->getConstraint(getVariable(), getType(), floor);
     526                 :    2499115 : }
     527                 :            : 
     528                 :    1835830 : void Constraint::setCanBePropagated()
     529                 :            : {
     530 [ -  + ][ -  + ]:    1835830 :   Assert(!canBePropagated());
                 [ -  - ]
     531                 :    1835830 :   d_database->pushCanBePropagatedWatch(this);
     532                 :    1835830 : }
     533                 :            : 
     534                 :   10799775 : void Constraint::setAssertedToTheTheory(TNode witness, bool nowInConflict)
     535                 :            : {
     536 [ -  + ][ -  + ]:   10799775 :   Assert(hasLiteral());
                 [ -  - ]
     537 [ -  + ][ -  + ]:   10799775 :   Assert(!assertedToTheTheory());
                 [ -  - ]
     538 [ -  + ][ -  + ]:   10799775 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
     539                 :   10799775 :   d_database->pushAssertionOrderWatch(this, witness);
     540                 :            : 
     541                 :   10799775 :   if (TraceIsOn("constraint::conflictCommit") && nowInConflict)
     542                 :            :   {
     543         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "inConflict@setAssertedToTheTheory";
     544         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "\t" << this << std::endl;
     545         [ -  - ]:          0 :     Trace("constraint::conflictCommit") << "\t" << getNegation() << std::endl;
     546         [ -  - ]:          0 :     Trace("constraint::conflictCommit")
     547                 :          0 :         << "\t" << getNegation()->externalExplainByAssertions() << std::endl;
     548                 :            :   }
     549                 :   10799775 : }
     550                 :            : 
     551                 :          0 : bool Constraint::satisfiedBy(const DeltaRational& dr) const
     552                 :            : {
     553 [ -  - ][ -  - ]:          0 :   switch (getType())
                    [ - ]
     554                 :            :   {
     555                 :          0 :     case LowerBound: return getValue() <= dr;
     556                 :          0 :     case Equality: return getValue() == dr;
     557                 :          0 :     case UpperBound: return getValue() >= dr;
     558                 :          0 :     case Disequality: return getValue() != dr;
     559                 :            :   }
     560                 :          0 :   Unreachable();
     561                 :            : }
     562                 :            : 
     563                 :   18542838 : bool Constraint::isInternalAssumption() const
     564                 :            : {
     565                 :   18542838 :   return getProofType() == InternalAssumeAP;
     566                 :            : }
     567                 :            : 
     568                 :          0 : TrustNode Constraint::externalExplainByAssertions() const
     569                 :            : {
     570                 :          0 :   NodeBuilder nb(d_database->nodeManager(), Kind::AND);
     571                 :          0 :   auto pfFromAssumptions = externalExplain(nb, AssertionOrderSentinel);
     572                 :          0 :   Node exp = mkAndFromBuilder(d_database->nodeManager(), nb);
     573         [ -  - ]:          0 :   if (d_database->isProofEnabled())
     574                 :            :   {
     575                 :          0 :     std::vector<Node> assumptions;
     576         [ -  - ]:          0 :     if (exp.getKind() == Kind::AND)
     577                 :            :     {
     578                 :          0 :       assumptions.insert(assumptions.end(), exp.begin(), exp.end());
     579                 :            :     }
     580                 :            :     else
     581                 :            :     {
     582                 :          0 :       assumptions.push_back(exp);
     583                 :            :     }
     584                 :          0 :     auto pf = d_database->d_pnm->mkScope(pfFromAssumptions, assumptions);
     585                 :          0 :     return d_database->d_pfGen->mkTrustedPropagation(
     586                 :          0 :         getLiteral(), d_database->nodeManager()->mkAnd(assumptions), pf);
     587                 :          0 :   }
     588                 :          0 :   return TrustNode::mkTrustPropExp(getLiteral(), exp);
     589                 :          0 : }
     590                 :            : 
     591                 :   19882535 : bool Constraint::isAssumption() const { return getProofType() == AssumeAP; }
     592                 :            : 
     593                 :    1323046 : bool Constraint::hasEqualityEngineProof() const
     594                 :            : {
     595                 :    1323046 :   return getProofType() == EqualityEngineAP;
     596                 :            : }
     597                 :            : 
     598                 :          0 : bool Constraint::hasFarkasProof() const { return getProofType() == FarkasAP; }
     599                 :            : 
     600                 :          0 : bool Constraint::hasSimpleFarkasProof() const
     601                 :            : {
     602         [ -  - ]:          0 :   Trace("constraints::hsfp") << "hasSimpleFarkasProof " << this << std::endl;
     603         [ -  - ]:          0 :   if (!hasFarkasProof())
     604                 :            :   {
     605         [ -  - ]:          0 :     Trace("constraints::hsfp") << "There is no simple Farkas proof because "
     606                 :          0 :                                   "there is no farkas proof."
     607                 :          0 :                                << std::endl;
     608                 :          0 :     return false;
     609                 :            :   }
     610                 :            : 
     611                 :            :   // For each antecdent ...
     612                 :          0 :   AntecedentId i = getConstraintRule().d_antecedentEnd;
     613         [ -  - ]:          0 :   for (ConstraintCP a = d_database->getAntecedent(i); a != NullConstraint;
     614                 :          0 :        a = d_database->getAntecedent(--i))
     615                 :            :   {
     616                 :            :     // ... that antecdent must be an assumption OR a tightened assumption ...
     617         [ -  - ]:          0 :     if (a->isPossiblyTightenedAssumption())
     618                 :            :     {
     619                 :          0 :       continue;
     620                 :            :     }
     621                 :            : 
     622                 :            :     // ... otherwise, we do not have a simple Farkas proof.
     623         [ -  - ]:          0 :     if (TraceIsOn("constraints::hsfp"))
     624                 :            :     {
     625         [ -  - ]:          0 :       Trace("constraints::hsfp") << "There is no simple Farkas proof b/c there "
     626                 :          0 :                                     "is an antecdent w/ rule ";
     627         [ -  - ]:          0 :       a->getConstraintRule().print(Trace("constraints::hsfp"), d_produceProofs);
     628         [ -  - ]:          0 :       Trace("constraints::hsfp") << std::endl;
     629                 :            :     }
     630                 :            : 
     631                 :          0 :     return false;
     632                 :            :   }
     633                 :          0 :   return true;
     634                 :            : }
     635                 :            : 
     636                 :          0 : bool Constraint::isPossiblyTightenedAssumption() const
     637                 :            : {
     638                 :            :   // ... that antecdent must be an assumption ...
     639                 :            : 
     640         [ -  - ]:          0 :   if (isAssumption()) return true;
     641         [ -  - ]:          0 :   if (!hasIntTightenProof()) return false;
     642         [ -  - ]:          0 :   if (getConstraintRule().d_antecedentEnd == AntecedentIdSentinel) return false;
     643                 :          0 :   return d_database->getAntecedent(getConstraintRule().d_antecedentEnd)
     644                 :          0 :       ->isAssumption();
     645                 :            : }
     646                 :            : 
     647                 :          0 : bool Constraint::hasIntTightenProof() const
     648                 :            : {
     649                 :          0 :   return getProofType() == IntTightenAP;
     650                 :            : }
     651                 :            : 
     652                 :          0 : bool Constraint::hasIntHoleProof() const { return getProofType() == IntHoleAP; }
     653                 :            : 
     654                 :          0 : bool Constraint::hasTrichotomyProof() const
     655                 :            : {
     656                 :          0 :   return getProofType() == TrichotomyAP;
     657                 :            : }
     658                 :            : 
     659                 :          0 : void Constraint::printProofTree(std::ostream& out, size_t depth) const
     660                 :            : {
     661         [ -  - ]:          0 :   if (d_produceProofs)
     662                 :            :   {
     663                 :          0 :     const ConstraintRule& rule = getConstraintRule();
     664                 :          0 :     out << std::string(2 * depth, ' ') << "* " << getVariable() << " [";
     665                 :          0 :     out << getProofLiteral();
     666         [ -  - ]:          0 :     if (assertedToTheTheory())
     667                 :            :     {
     668                 :          0 :       out << " | wit: " << getWitness();
     669                 :            :     }
     670                 :          0 :     out << "]" << ' ' << getType() << ' ' << getValue() << " ("
     671                 :          0 :         << getProofType() << ")";
     672         [ -  - ]:          0 :     if (getProofType() == FarkasAP)
     673                 :            :     {
     674                 :          0 :       out << " [";
     675                 :          0 :       bool first = true;
     676         [ -  - ]:          0 :       for (const auto& coeff : *rule.d_farkasCoefficients)
     677                 :            :       {
     678         [ -  - ]:          0 :         if (!first)
     679                 :            :         {
     680                 :          0 :           out << ", ";
     681                 :            :         }
     682                 :          0 :         first = false;
     683                 :          0 :         out << coeff;
     684                 :            :       }
     685                 :          0 :       out << "]";
     686                 :            :     }
     687                 :          0 :     out << endl;
     688                 :            : 
     689         [ -  - ]:          0 :     for (AntecedentId i = rule.d_antecedentEnd; i != AntecedentIdSentinel; --i)
     690                 :            :     {
     691                 :          0 :       ConstraintCP antecdent = d_database->getAntecedent(i);
     692         [ -  - ]:          0 :       if (antecdent == NullConstraint)
     693                 :            :       {
     694                 :          0 :         break;
     695                 :            :       }
     696                 :          0 :       antecdent->printProofTree(out, depth + 1);
     697                 :            :     }
     698                 :          0 :     return;
     699                 :            :   }
     700                 :          0 :   out << "Cannot print proof. This is not a proof build." << endl;
     701                 :            : }
     702                 :            : 
     703                 :    1193410 : bool Constraint::sanityChecking(Node n) const
     704                 :            : {
     705                 :    1193410 :   Comparison cmp = Comparison::parseNormalForm(n);
     706                 :    1193410 :   Kind k = cmp.comparisonKind();
     707                 :    1193410 :   Polynomial pleft = cmp.normalizedVariablePart();
     708 [ +  + ][ +  + ]:    1193410 :   Assert(k == Kind::EQUAL || k == Kind::DISTINCT
         [ +  + ][ +  - ]
         [ -  + ][ -  + ]
                 [ -  - ]
     709                 :            :          || pleft.leadingCoefficientIsPositive());
     710                 :    1193410 :   Assert(
     711                 :            :       k != Kind::EQUAL
     712                 :            :       || Monomial::isMember(n[0].getKind() == Kind::TO_REAL ? n[0][0] : n[0]));
     713                 :    1193410 :   Assert(k != Kind::DISTINCT
     714                 :            :          || Monomial::isMember(n[0][0].getKind() == Kind::TO_REAL ? n[0][0][0]
     715                 :            :                                                                   : n[0][0]));
     716                 :            : 
     717                 :    1193410 :   TNode left = pleft.getNode();
     718                 :    1193410 :   DeltaRational right = cmp.normalizedDeltaRational();
     719                 :            : 
     720                 :    1193410 :   const ArithVariables& avariables = d_database->getArithVariables();
     721                 :            : 
     722         [ +  - ]:    1193410 :   Trace("Constraint::sanityChecking") << cmp.getNode() << endl;
     723         [ +  - ]:    1193410 :   Trace("Constraint::sanityChecking") << k << endl;
     724         [ +  - ]:    1193410 :   Trace("Constraint::sanityChecking") << pleft.getNode() << endl;
     725         [ +  - ]:    1193410 :   Trace("Constraint::sanityChecking") << left << endl;
     726         [ +  - ]:    1193410 :   Trace("Constraint::sanityChecking") << right << endl;
     727         [ +  - ]:    1193410 :   Trace("Constraint::sanityChecking") << getValue() << endl;
     728 [ +  - ][ -  + ]:    1193410 :   Trace("Constraint::sanityChecking") << avariables.hasArithVar(left) << endl;
                 [ -  - ]
     729 [ +  - ][ -  + ]:    1193410 :   Trace("Constraint::sanityChecking") << avariables.asArithVar(left) << endl;
                 [ -  - ]
     730         [ +  - ]:    1193410 :   Trace("Constraint::sanityChecking") << getVariable() << endl;
     731                 :            : 
     732 [ +  - ][ -  - ]:    1193410 :   if (avariables.hasArithVar(left)
     733 [ +  - ][ +  - ]:    1193410 :       && avariables.asArithVar(left) == getVariable() && getValue() == right)
         [ +  - ][ +  - ]
         [ +  - ][ -  - ]
     734                 :            :   {
     735 [ +  + ][ +  - ]:    1193410 :     switch (getType())
     736                 :            :     {
     737                 :     647892 :       case LowerBound:
     738                 :            :       case UpperBound:
     739                 :            :         // Be overapproximate
     740 [ +  + ][ -  + ]:     647892 :         return k == Kind::GT || k == Kind::GEQ || k == Kind::LT
     741 [ +  - ][ -  - ]:    1295784 :                || k == Kind::LEQ;
     742                 :     272759 :       case Equality: return k == Kind::EQUAL;
     743                 :     272759 :       case Disequality: return k == Kind::DISTINCT;
     744                 :          0 :       default: Unreachable();
     745                 :            :     }
     746                 :            :   }
     747                 :            :   else
     748                 :            :   {
     749                 :          0 :     return false;
     750                 :            :   }
     751                 :    1193410 : }
     752                 :            : 
     753                 :          0 : ConstraintCP ConstraintDatabase::getAntecedent(AntecedentId p) const
     754                 :            : {
     755                 :          0 :   Assert(p < d_antecedents.size());
     756                 :          0 :   return d_antecedents[p];
     757                 :            : }
     758                 :            : 
     759                 :          0 : void ConstraintRule::print(std::ostream& out, bool produceProofs) const
     760                 :            : {
     761         [ -  - ]:          0 :   RationalVectorCP coeffs = produceProofs ? d_farkasCoefficients : nullptr;
     762                 :          0 :   out << "{ConstraintRule, ";
     763                 :          0 :   out << d_constraint << std::endl;
     764                 :          0 :   out << "d_proofType= " << d_proofType << ", " << std::endl;
     765                 :          0 :   out << "d_antecedentEnd= " << d_antecedentEnd << std::endl;
     766                 :            : 
     767 [ -  - ][ -  - ]:          0 :   if (d_constraint != NullConstraint && d_antecedentEnd != AntecedentIdSentinel)
     768                 :            :   {
     769                 :          0 :     const ConstraintDatabase& database = d_constraint->getDatabase();
     770                 :            : 
     771                 :            :     size_t coeffIterator =
     772         [ -  - ]:          0 :         (coeffs != RationalVectorCPSentinel) ? coeffs->size() - 1 : 0;
     773                 :          0 :     AntecedentId p = d_antecedentEnd;
     774                 :            :     // must have at least one antecedent
     775                 :          0 :     ConstraintCP antecedent = database.getAntecedent(p);
     776         [ -  - ]:          0 :     while (antecedent != NullConstraint)
     777                 :            :     {
     778         [ -  - ]:          0 :       if (coeffs != RationalVectorCPSentinel)
     779                 :            :       {
     780                 :          0 :         out << coeffs->at(coeffIterator);
     781                 :            :       }
     782                 :            :       else
     783                 :            :       {
     784                 :          0 :         out << "_";
     785                 :            :       }
     786                 :          0 :       out << " * (" << *antecedent << ")" << std::endl;
     787                 :            : 
     788                 :          0 :       Assert((coeffs == RationalVectorCPSentinel) || coeffIterator > 0);
     789                 :          0 :       --p;
     790                 :          0 :       coeffIterator =
     791         [ -  - ]:          0 :           (coeffs != RationalVectorCPSentinel) ? coeffIterator - 1 : 0;
     792                 :          0 :       antecedent = database.getAntecedent(p);
     793                 :            :     }
     794         [ -  - ]:          0 :     if (coeffs != RationalVectorCPSentinel)
     795                 :            :     {
     796                 :          0 :       out << coeffs->front();
     797                 :            :     }
     798                 :            :     else
     799                 :            :     {
     800                 :          0 :       out << "_";
     801                 :            :     }
     802                 :          0 :     out << " * (" << *(d_constraint->getNegation()) << ")";
     803                 :          0 :     out << " [not d_constraint] " << endl;
     804                 :            :   }
     805                 :          0 :   out << "}";
     806                 :          0 : }
     807                 :            : 
     808                 :    3787921 : bool Constraint::wellFormedFarkasProof(NodeManager* nm) const
     809                 :            : {
     810 [ -  + ][ -  + ]:    3787921 :   Assert(hasProof());
                 [ -  - ]
     811                 :            : 
     812                 :    3787921 :   const ConstraintRule& cr = getConstraintRule();
     813         [ -  + ]:    3787921 :   if (cr.d_constraint != this)
     814                 :            :   {
     815                 :          0 :     return false;
     816                 :            :   }
     817         [ -  + ]:    3787921 :   if (cr.d_proofType != FarkasAP)
     818                 :            :   {
     819                 :          0 :     return false;
     820                 :            :   }
     821                 :            : 
     822                 :    3787921 :   AntecedentId p = cr.d_antecedentEnd;
     823                 :            : 
     824                 :            :   // must have at least one antecedent
     825                 :    3787921 :   ConstraintCP antecedent = d_database->d_antecedents[p];
     826         [ -  + ]:    3787921 :   if (antecedent == NullConstraint)
     827                 :            :   {
     828                 :          0 :     return false;
     829                 :            :   }
     830                 :            : 
     831         [ +  + ]:    3787921 :   if (!d_produceProofs)
     832                 :            :   {
     833                 :    1180937 :     return cr.d_farkasCoefficients == RationalVectorCPSentinel;
     834                 :            :   }
     835 [ -  + ][ -  + ]:    2606984 :   Assert(d_produceProofs);
                 [ -  - ]
     836                 :            : 
     837         [ -  + ]:    2606984 :   if (cr.d_farkasCoefficients == RationalVectorCPSentinel)
     838                 :            :   {
     839                 :          0 :     return false;
     840                 :            :   }
     841         [ -  + ]:    2606984 :   if (cr.d_farkasCoefficients->size() < 2)
     842                 :            :   {
     843                 :          0 :     return false;
     844                 :            :   }
     845                 :            : 
     846                 :    2606984 :   const ArithVariables& vars = d_database->getArithVariables();
     847                 :            : 
     848                 :    2606984 :   DeltaRational rhs(0);
     849                 :    2606984 :   Node lhs = Polynomial::mkZero(nm).getNode();
     850                 :            : 
     851                 :            :   RationalVector::const_iterator coeffIterator =
     852                 :    2606984 :       cr.d_farkasCoefficients->end() - 1;
     853                 :    2606984 :   RationalVector::const_iterator coeffBegin = cr.d_farkasCoefficients->begin();
     854                 :            : 
     855         [ +  + ]:    6123222 :   while (antecedent != NullConstraint)
     856                 :            :   {
     857                 :    3516238 :     Assert(lhs.isNull() || Polynomial::isMember(lhs));
     858                 :            : 
     859                 :    3516238 :     const Rational& coeff = *coeffIterator;
     860                 :    3516238 :     int coeffSgn = coeff.sgn();
     861                 :            : 
     862                 :    3516238 :     rhs += antecedent->getValue() * coeff;
     863                 :            : 
     864                 :    3516238 :     ArithVar antVar = antecedent->getVariable();
     865 [ +  - ][ +  - ]:    3516238 :     if (!lhs.isNull() && vars.hasNode(antVar))
                 [ +  - ]
     866                 :            :     {
     867                 :    3516238 :       Node antAsNode = vars.asNode(antVar);
     868         [ +  - ]:    3516238 :       if (Polynomial::isMember(antAsNode))
     869                 :            :       {
     870                 :    3516238 :         Polynomial lhsPoly = Polynomial::parsePolynomial(lhs);
     871                 :    3516238 :         Polynomial antPoly = Polynomial::parsePolynomial(antAsNode);
     872                 :    3516238 :         Polynomial sum = lhsPoly + (antPoly * coeff);
     873                 :    3516238 :         lhs = sum.getNode();
     874                 :    3516238 :       }
     875                 :            :       else
     876                 :            :       {
     877                 :          0 :         lhs = Node::null();
     878                 :            :       }
     879                 :    3516238 :     }
     880                 :            :     else
     881                 :            :     {
     882                 :          0 :       lhs = Node::null();
     883                 :            :     }
     884         [ +  - ]:    7032476 :     Trace("constraints::wffp")
     885                 :    3516238 :         << "running sum: " << lhs << " <= " << rhs << endl;
     886                 :            : 
     887 [ +  + ][ +  - ]:    3516238 :     switch (antecedent->getType())
     888                 :            :     {
     889                 :    1335036 :       case LowerBound:
     890                 :            :         // fc[l] < 0, therefore return false if coeffSgn >= 0
     891         [ -  + ]:    1335036 :         if (coeffSgn >= 0)
     892                 :            :         {
     893                 :          0 :           return false;
     894                 :            :         }
     895                 :    1335036 :         break;
     896                 :     535869 :       case UpperBound:
     897                 :            :         // fc[u] > 0, therefore return false if coeffSgn <= 0
     898         [ -  + ]:     535869 :         if (coeffSgn <= 0)
     899                 :            :         {
     900                 :          0 :           return false;
     901                 :            :         }
     902                 :     535869 :         break;
     903                 :    1645333 :       case Equality:
     904         [ -  + ]:    1645333 :         if (coeffSgn == 0)
     905                 :            :         {
     906                 :          0 :           return false;
     907                 :            :         }
     908                 :    1645333 :         break;
     909                 :          0 :       case Disequality:
     910                 :          0 :       default: return false;
     911                 :            :     }
     912                 :            : 
     913         [ -  + ]:    3516238 :     if (coeffIterator == coeffBegin)
     914                 :            :     {
     915                 :          0 :       return false;
     916                 :            :     }
     917                 :    3516238 :     --coeffIterator;
     918                 :    3516238 :     --p;
     919                 :    3516238 :     antecedent = d_database->d_antecedents[p];
     920                 :            :   }
     921         [ -  + ]:    2606984 :   if (coeffIterator != coeffBegin)
     922                 :            :   {
     923                 :          0 :     return false;
     924                 :            :   }
     925                 :            : 
     926                 :    2606984 :   const Rational& firstCoeff = (*coeffBegin);
     927                 :    2606984 :   int firstCoeffSgn = firstCoeff.sgn();
     928                 :    2606984 :   rhs += (getNegation()->getValue()) * firstCoeff;
     929 [ +  - ][ +  - ]:    2606984 :   if (!lhs.isNull() && vars.hasNode(getVariable()))
                 [ +  - ]
     930                 :            :   {
     931                 :    2606984 :     Node firstAsNode = vars.asNode(getVariable());
     932         [ +  - ]:    2606984 :     if (Polynomial::isMember(firstAsNode))
     933                 :            :     {
     934                 :    2606984 :       Polynomial lhsPoly = Polynomial::parsePolynomial(lhs);
     935                 :    2606984 :       Polynomial firstPoly = Polynomial::parsePolynomial(firstAsNode);
     936                 :    2606984 :       Polynomial sum = lhsPoly + (firstPoly * firstCoeff);
     937                 :    2606984 :       lhs = sum.getNode();
     938                 :    2606984 :     }
     939                 :            :     else
     940                 :            :     {
     941                 :          0 :       lhs = Node::null();
     942                 :            :     }
     943                 :    2606984 :   }
     944                 :            :   else
     945                 :            :   {
     946                 :          0 :     lhs = Node::null();
     947                 :            :   }
     948                 :            : 
     949 [ +  + ][ +  - ]:    2606984 :   switch (getNegation()->getType())
     950                 :            :   {
     951                 :     603076 :     case LowerBound:
     952                 :            :       // fc[l] < 0, therefore return false if coeffSgn >= 0
     953         [ -  + ]:     603076 :       if (firstCoeffSgn >= 0)
     954                 :            :       {
     955                 :          0 :         return false;
     956                 :            :       }
     957                 :     603076 :       break;
     958                 :    1050878 :     case UpperBound:
     959                 :            :       // fc[u] > 0, therefore return false if coeffSgn <= 0
     960         [ -  + ]:    1050878 :       if (firstCoeffSgn <= 0)
     961                 :            :       {
     962                 :          0 :         return false;
     963                 :            :       }
     964                 :    1050878 :       break;
     965                 :     953030 :     case Equality:
     966         [ -  + ]:     953030 :       if (firstCoeffSgn == 0)
     967                 :            :       {
     968                 :          0 :         return false;
     969                 :            :       }
     970                 :     953030 :       break;
     971                 :          0 :     case Disequality:
     972                 :          0 :     default: return false;
     973                 :            :   }
     974         [ +  - ]:    2606984 :   Trace("constraints::wffp") << "final sum: " << lhs << " <= " << rhs << endl;
     975                 :            :   // 0 = lhs <= rhs < 0
     976                 :    5213968 :   return (lhs.isNull() || (Constant::isMember(lhs) && Constant(lhs).isZero()))
     977 [ +  - ][ +  - ]:    5213968 :          && rhs.sgn() < 0;
                 [ +  - ]
     978                 :    2606984 : }
     979                 :            : 
     980                 :     155664 : ConstraintP Constraint::makeNegation(ArithVar v,
     981                 :            :                                      ConstraintType t,
     982                 :            :                                      const DeltaRational& r,
     983                 :            :                                      bool produceProofs)
     984                 :            : {
     985 [ +  + ][ +  - ]:     155664 :   switch (t)
                    [ - ]
     986                 :            :   {
     987                 :       6518 :     case LowerBound:
     988                 :            :     {
     989 [ -  + ][ -  + ]:       6518 :       Assert(r.infinitesimalSgn() >= 0);
                 [ -  - ]
     990         [ -  + ]:       6518 :       if (r.infinitesimalSgn() > 0)
     991                 :            :       {
     992                 :          0 :         Assert(r.getInfinitesimalPart() == 1);
     993                 :            :         // make (not (v > r)), which is (v <= r)
     994                 :          0 :         DeltaRational dropInf(r.getNoninfinitesimalPart(), 0);
     995                 :          0 :         return new Constraint(v, UpperBound, dropInf, produceProofs);
     996                 :          0 :       }
     997                 :            :       else
     998                 :            :       {
     999 [ -  + ][ -  + ]:       6518 :         Assert(r.infinitesimalSgn() == 0);
                 [ -  - ]
    1000                 :            :         // make (not (v >= r)), which is (v < r)
    1001                 :       6518 :         DeltaRational addInf(r.getNoninfinitesimalPart(), -1);
    1002                 :       6518 :         return new Constraint(v, UpperBound, addInf, produceProofs);
    1003                 :       6518 :       }
    1004                 :            :     }
    1005                 :     140909 :     case UpperBound:
    1006                 :            :     {
    1007 [ -  + ][ -  + ]:     140909 :       Assert(r.infinitesimalSgn() <= 0);
                 [ -  - ]
    1008         [ -  + ]:     140909 :       if (r.infinitesimalSgn() < 0)
    1009                 :            :       {
    1010                 :          0 :         Assert(r.getInfinitesimalPart() == -1);
    1011                 :            :         // make (not (v < r)), which is (v >= r)
    1012                 :          0 :         DeltaRational dropInf(r.getNoninfinitesimalPart(), 0);
    1013                 :          0 :         return new Constraint(v, LowerBound, dropInf, produceProofs);
    1014                 :          0 :       }
    1015                 :            :       else
    1016                 :            :       {
    1017 [ -  + ][ -  + ]:     140909 :         Assert(r.infinitesimalSgn() == 0);
                 [ -  - ]
    1018                 :            :         // make (not (v <= r)), which is (v > r)
    1019                 :     140909 :         DeltaRational addInf(r.getNoninfinitesimalPart(), 1);
    1020                 :     140909 :         return new Constraint(v, LowerBound, addInf, produceProofs);
    1021                 :     140909 :       }
    1022                 :            :     }
    1023                 :       8237 :     case Equality: return new Constraint(v, Disequality, r, produceProofs);
    1024                 :          0 :     case Disequality: return new Constraint(v, Equality, r, produceProofs);
    1025                 :          0 :     default: Unreachable(); return NullConstraint;
    1026                 :            :   }
    1027                 :            : }
    1028                 :            : 
    1029                 :      51016 : ConstraintDatabase::ConstraintDatabase(Env& env,
    1030                 :            :                                        const ArithVariables& avars,
    1031                 :            :                                        ArithCongruenceManager& cm,
    1032                 :            :                                        RaiseConflict raiseConflict,
    1033                 :      51016 :                                        EagerProofGenerator* pfGen)
    1034                 :            :     : EnvObj(env),
    1035                 :      51016 :       d_varDatabases(),
    1036                 :      51016 :       d_toPropagate(context()),
    1037                 :      51016 :       d_antecedents(context(), false),
    1038                 :      51016 :       d_watches(new Watches(context(), userContext())),
    1039                 :      51016 :       d_avariables(avars),
    1040                 :      51016 :       d_congruenceManager(cm),
    1041                 :      51016 :       d_pfGen(pfGen),
    1042         [ +  + ]:      51016 :       d_pnm(d_env.isTheoryProofProducing() ? d_env.getProofNodeManager()
    1043                 :            :                                            : nullptr),
    1044                 :      51016 :       d_raiseConflict(raiseConflict),
    1045                 :      51016 :       d_one(1),
    1046                 :      51016 :       d_negOne(-1),
    1047                 :     102032 :       d_statistics(statisticsRegistry())
    1048                 :            : {
    1049                 :      51016 : }
    1050                 :            : 
    1051                 :   14061474 : SortedConstraintMap& ConstraintDatabase::getVariableSCM(ArithVar v) const
    1052                 :            : {
    1053 [ -  + ][ -  + ]:   14061474 :   Assert(variableDatabaseIsSetup(v));
                 [ -  - ]
    1054                 :   14061474 :   return d_varDatabases[v]->d_constraints;
    1055                 :            : }
    1056                 :            : 
    1057                 :      73824 : void ConstraintDatabase::pushSplitWatch(ConstraintP c)
    1058                 :            : {
    1059 [ -  + ][ -  + ]:      73824 :   Assert(!c->d_split);
                 [ -  - ]
    1060                 :      73824 :   c->d_split = true;
    1061                 :      73824 :   d_watches->d_splitWatches.push_back(c);
    1062                 :      73824 : }
    1063                 :            : 
    1064                 :    1835830 : void ConstraintDatabase::pushCanBePropagatedWatch(ConstraintP c)
    1065                 :            : {
    1066 [ -  + ][ -  + ]:    1835830 :   Assert(!c->d_canBePropagated);
                 [ -  - ]
    1067                 :    1835830 :   c->d_canBePropagated = true;
    1068                 :    1835830 :   d_watches->d_canBePropagatedWatches.push_back(c);
    1069                 :    1835830 : }
    1070                 :            : 
    1071                 :   10799775 : void ConstraintDatabase::pushAssertionOrderWatch(ConstraintP c, TNode witness)
    1072                 :            : {
    1073 [ -  + ][ -  + ]:   10799775 :   Assert(!c->assertedToTheTheory());
                 [ -  - ]
    1074                 :   10799775 :   c->d_assertionOrder = d_watches->d_assertionOrderWatches.size();
    1075                 :   10799775 :   c->d_witness = witness;
    1076                 :   10799775 :   d_watches->d_assertionOrderWatches.push_back(c);
    1077                 :   10799775 : }
    1078                 :            : 
    1079                 :   16560141 : void ConstraintDatabase::pushConstraintRule(const ConstraintRule& crp)
    1080                 :            : {
    1081                 :   16560141 :   ConstraintP c = crp.d_constraint;
    1082 [ -  + ][ -  + ]:   16560141 :   Assert(c->d_crid == ConstraintRuleIdSentinel);
                 [ -  - ]
    1083 [ -  + ][ -  + ]:   16560141 :   Assert(!c->hasProof());
                 [ -  - ]
    1084                 :   16560141 :   c->d_crid = d_watches->d_constraintProofs.size();
    1085                 :   16560141 :   d_watches->d_constraintProofs.push_back(crp);
    1086                 :   16560141 : }
    1087                 :            : 
    1088                 :    3334367 : ConstraintP ConstraintDatabase::getConstraint(ArithVar v,
    1089                 :            :                                               ConstraintType t,
    1090                 :            :                                               const DeltaRational& r)
    1091                 :            : {
    1092                 :            :   // This must always return a constraint.
    1093                 :            : 
    1094                 :    3334367 :   SortedConstraintMap& scm = getVariableSCM(v);
    1095                 :    3334367 :   pair<SortedConstraintMapIterator, bool> insertAttempt;
    1096                 :    3334367 :   insertAttempt = scm.insert(make_pair(r, ValueCollection()));
    1097                 :            : 
    1098                 :    3334367 :   SortedConstraintMapIterator pos = insertAttempt.first;
    1099                 :    3334367 :   ValueCollection& vc = pos->second;
    1100         [ +  + ]:    3334367 :   if (vc.hasConstraintOfType(t))
    1101                 :            :   {
    1102                 :    3178703 :     return vc.getConstraintOfType(t);
    1103                 :            :   }
    1104                 :            :   else
    1105                 :            :   {
    1106                 :     155664 :     ConstraintP c = new Constraint(v, t, r, options().smt.produceProofs);
    1107                 :            :     ConstraintP negC =
    1108                 :     155664 :         Constraint::makeNegation(v, t, r, options().smt.produceProofs);
    1109                 :            : 
    1110                 :     155664 :     SortedConstraintMapIterator negPos;
    1111 [ +  + ][ -  + ]:     155664 :     if (t == Equality || t == Disequality)
    1112                 :            :     {
    1113                 :       8237 :       negPos = pos;
    1114                 :            :     }
    1115                 :            :     else
    1116                 :            :     {
    1117                 :     147427 :       pair<SortedConstraintMapIterator, bool> negInsertAttempt;
    1118                 :            :       negInsertAttempt =
    1119                 :     147427 :           scm.insert(make_pair(negC->getValue(), ValueCollection()));
    1120 [ -  + ][ -  - ]:     147427 :       Assert(negInsertAttempt.second
         [ -  + ][ -  + ]
                 [ -  - ]
    1121                 :            :              || !negInsertAttempt.first->second.hasConstraintOfType(
    1122                 :            :                  negC->getType()));
    1123                 :     147427 :       negPos = negInsertAttempt.first;
    1124                 :            :     }
    1125                 :            : 
    1126                 :     155664 :     c->initialize(this, pos, negC);
    1127                 :     155664 :     negC->initialize(this, negPos, c);
    1128                 :            : 
    1129                 :     155664 :     vc.add(c);
    1130                 :     155664 :     negPos->second.add(negC);
    1131                 :            : 
    1132                 :     155664 :     return c;
    1133                 :            :   }
    1134                 :            : }
    1135                 :            : 
    1136                 :     434292 : ConstraintP ConstraintDatabase::ensureConstraint(ValueCollection& vc,
    1137                 :            :                                                  ConstraintType t)
    1138                 :            : {
    1139         [ +  + ]:     434292 :   if (vc.hasConstraintOfType(t))
    1140                 :            :   {
    1141                 :     418507 :     return vc.getConstraintOfType(t);
    1142                 :            :   }
    1143                 :            :   else
    1144                 :            :   {
    1145                 :      15785 :     return getConstraint(vc.getVariable(), t, vc.getValue());
    1146                 :            :   }
    1147                 :            : }
    1148                 :            : 
    1149                 :          0 : bool ConstraintDatabase::emptyDatabase(
    1150                 :            :     const std::vector<PerVariableDatabase>& vec)
    1151                 :            : {
    1152                 :          0 :   std::vector<PerVariableDatabase>::const_iterator first = vec.begin();
    1153                 :          0 :   std::vector<PerVariableDatabase>::const_iterator last = vec.end();
    1154                 :          0 :   return std::find_if(first, last, PerVariableDatabase::IsEmpty) == last;
    1155                 :            : }
    1156                 :            : 
    1157                 :     152004 : ConstraintDatabase::~ConstraintDatabase()
    1158                 :            : {
    1159         [ +  - ]:      50668 :   delete d_watches;
    1160                 :            : 
    1161                 :      50668 :   std::vector<ConstraintP> constraintList;
    1162                 :            : 
    1163         [ +  + ]:     414937 :   while (!d_varDatabases.empty())
    1164                 :            :   {
    1165                 :     364269 :     PerVariableDatabase* back = d_varDatabases.back();
    1166                 :            : 
    1167                 :     364269 :     SortedConstraintMap& scm = back->d_constraints;
    1168                 :     364269 :     SortedConstraintMapIterator i = scm.begin(), i_end = scm.end();
    1169         [ +  + ]:    1385354 :     for (; i != i_end; ++i)
    1170                 :            :     {
    1171                 :    1021085 :       (i->second).push_into(constraintList);
    1172                 :            :     }
    1173         [ +  + ]:    1861551 :     while (!constraintList.empty())
    1174                 :            :     {
    1175                 :    1497282 :       ConstraintP c = constraintList.back();
    1176                 :    1497282 :       constraintList.pop_back();
    1177         [ +  - ]:    1497282 :       delete c;
    1178                 :            :     }
    1179 [ -  + ][ -  + ]:     364269 :     Assert(scm.empty());
    1180                 :     364269 :     d_varDatabases.pop_back();
    1181         [ +  - ]:     364269 :     delete back;
    1182                 :            :   }
    1183                 :            : 
    1184 [ -  + ][ -  + ]:      50668 :   Assert(d_nodetoConstraintMap.empty());
    1185                 :      50668 : }
    1186                 :            : 
    1187                 :      51016 : ConstraintDatabase::Statistics::Statistics(StatisticsRegistry& sr)
    1188                 :            :     : d_unatePropagateCalls(
    1189                 :      51016 :           sr.registerInt("theory::arith::cd::unatePropagateCalls")),
    1190                 :            :       d_unatePropagateImplications(
    1191                 :      51016 :           sr.registerInt("theory::arith::cd::unatePropagateImplications"))
    1192                 :            : {
    1193                 :      51016 : }
    1194                 :            : 
    1195                 :          0 : void ConstraintDatabase::deleteConstraintAndNegation(ConstraintP c)
    1196                 :            : {
    1197                 :          0 :   Assert(c->safeToGarbageCollect());
    1198                 :          0 :   ConstraintP neg = c->getNegation();
    1199                 :          0 :   Assert(neg->safeToGarbageCollect());
    1200         [ -  - ]:          0 :   delete c;
    1201         [ -  - ]:          0 :   delete neg;
    1202                 :          0 : }
    1203                 :            : 
    1204                 :     368575 : void ConstraintDatabase::addVariable(ArithVar v)
    1205                 :            : {
    1206         [ +  + ]:     368575 :   if (d_reclaimable.isMember(v))
    1207                 :            :   {
    1208                 :       4078 :     SortedConstraintMap& scm = getVariableSCM(v);
    1209                 :            : 
    1210                 :       4078 :     std::vector<ConstraintP> constraintList;
    1211                 :            : 
    1212         [ -  + ]:       4078 :     for (SortedConstraintMapIterator i = scm.begin(), end = scm.end(); i != end;
    1213                 :          0 :          ++i)
    1214                 :            :     {
    1215                 :          0 :       (i->second).push_into(constraintList);
    1216                 :            :     }
    1217         [ -  + ]:       4078 :     while (!constraintList.empty())
    1218                 :            :     {
    1219                 :          0 :       ConstraintP c = constraintList.back();
    1220                 :          0 :       constraintList.pop_back();
    1221                 :          0 :       Assert(c->safeToGarbageCollect());
    1222         [ -  - ]:          0 :       delete c;
    1223                 :            :     }
    1224 [ -  + ][ -  + ]:       4078 :     Assert(scm.empty());
                 [ -  - ]
    1225                 :            : 
    1226                 :       4078 :     d_reclaimable.remove(v);
    1227                 :       4078 :   }
    1228                 :            :   else
    1229                 :            :   {
    1230         [ +  - ]:     728994 :     Trace("arith::constraint")
    1231                 :     364497 :         << "about to fail" << v << " " << d_varDatabases.size() << endl;
    1232 [ -  + ][ -  + ]:     364497 :     Assert(v == d_varDatabases.size());
                 [ -  - ]
    1233                 :     364497 :     d_varDatabases.push_back(new PerVariableDatabase(v));
    1234                 :            :   }
    1235                 :     368575 : }
    1236                 :            : 
    1237                 :       4096 : void ConstraintDatabase::removeVariable(ArithVar v)
    1238                 :            : {
    1239 [ -  + ][ -  + ]:       4096 :   Assert(!d_reclaimable.isMember(v));
                 [ -  - ]
    1240                 :       4096 :   d_reclaimable.add(v);
    1241                 :       4096 : }
    1242                 :            : 
    1243                 :          0 : bool Constraint::safeToGarbageCollect() const
    1244                 :            : {
    1245                 :            :   // Do not call during destructor as getNegation() may be Null by this point
    1246                 :          0 :   Assert(getNegation() != NullConstraint);
    1247                 :          0 :   return !contextDependentDataIsSet()
    1248 [ -  - ][ -  - ]:          0 :          && !getNegation()->contextDependentDataIsSet();
    1249                 :            : }
    1250                 :            : 
    1251                 :    1500556 : bool Constraint::contextDependentDataIsSet() const
    1252                 :            : {
    1253 [ +  - ][ +  - ]:    1500556 :   return hasProof() || isSplit() || canBePropagated() || assertedToTheTheory();
         [ +  - ][ -  + ]
    1254                 :            : }
    1255                 :            : 
    1256                 :      36912 : TrustNode Constraint::split()
    1257                 :            : {
    1258 [ +  + ][ +  - ]:      36912 :   Assert(isEquality() || isDisequality());
         [ -  + ][ -  + ]
                 [ -  - ]
    1259                 :            : 
    1260                 :      36912 :   bool isEq = isEquality();
    1261                 :            : 
    1262         [ +  + ]:      36912 :   ConstraintP eq = isEq ? this : d_negation;
    1263         [ +  + ]:      36912 :   ConstraintP diseq = isEq ? d_negation : this;
    1264                 :            : 
    1265                 :      36912 :   TNode eqNode = eq->getLiteral();
    1266 [ -  + ][ -  + ]:      36912 :   Assert(eqNode.getKind() == Kind::EQUAL);
                 [ -  - ]
    1267                 :      36912 :   TNode lhs = eqNode[0];
    1268                 :      36912 :   TNode rhs = eqNode[1];
    1269                 :            : 
    1270                 :      36912 :   NodeManager* nm = d_database->nodeManager();
    1271                 :      73824 :   Node leqNode = NodeBuilder(nm, Kind::LEQ) << lhs << rhs;
    1272                 :      73824 :   Node ltNode = NodeBuilder(nm, Kind::LT) << lhs << rhs;
    1273                 :      73824 :   Node gtNode = NodeBuilder(nm, Kind::GT) << lhs << rhs;
    1274                 :      73824 :   Node geqNode = NodeBuilder(nm, Kind::GEQ) << lhs << rhs;
    1275                 :            : 
    1276                 :      73824 :   Node lemma = NodeBuilder(nm, Kind::OR) << leqNode << geqNode;
    1277                 :            : 
    1278                 :      36912 :   TrustNode trustedLemma;
    1279         [ +  + ]:      36912 :   if (d_database->isProofEnabled())
    1280                 :            :   {
    1281                 :      13415 :     TypeNode type = lhs.getType();
    1282                 :            :     // Farkas proof that this works.
    1283                 :      13415 :     auto nLeqPf = d_database->d_pnm->mkAssume(leqNode.negate());
    1284                 :      13415 :     auto gtPf = ensurePredTransform(d_database->d_pnm, nLeqPf, gtNode);
    1285                 :      13415 :     auto nGeqPf = d_database->d_pnm->mkAssume(geqNode.negate());
    1286                 :      13415 :     auto ltPf = ensurePredTransform(d_database->d_pnm, nGeqPf, ltNode);
    1287                 :      53660 :     std::vector<Pf> args{gtPf, ltPf};
    1288                 :      67075 :     std::vector<Node> coeffs{nm->mkConstReal(-1), nm->mkConstReal(1)};
    1289                 :      13415 :     std::vector<Node> coeffsUse = getMacroSumUbCoeff(nm, args, coeffs);
    1290                 :      13415 :     auto sumPf = d_database->d_pnm->mkNode(
    1291                 :      13415 :         ProofRule::MACRO_ARITH_SCALE_SUM_UB, args, coeffsUse);
    1292                 :            :     auto botPf =
    1293                 :      13415 :         ensurePredTransform(d_database->d_pnm, sumPf, nm->mkConst(false));
    1294                 :      53660 :     std::vector<Node> a = {leqNode.negate(), geqNode.negate()};
    1295                 :      26830 :     auto notAndNotPf = d_database->d_pnm->mkScope(botPf, a);
    1296                 :            :     // No need to ensure that the expected node aggrees with `a` because we are
    1297                 :            :     // not providing an expected node.
    1298                 :            :     auto orNotNotPf =
    1299                 :      53660 :         d_database->d_pnm->mkNode(ProofRule::NOT_AND, {notAndNotPf}, {});
    1300                 :      13415 :     auto orPf = ensurePredTransform(d_database->d_pnm, orNotNotPf, lemma);
    1301                 :      13415 :     trustedLemma = d_database->d_pfGen->mkTrustNode(lemma, orPf);
    1302                 :      13415 :   }
    1303                 :            :   else
    1304                 :            :   {
    1305                 :      23497 :     trustedLemma = TrustNode::mkTrustLemma(lemma);
    1306                 :            :   }
    1307                 :            : 
    1308                 :      36912 :   eq->d_database->pushSplitWatch(eq);
    1309                 :      36912 :   diseq->d_database->pushSplitWatch(diseq);
    1310                 :            : 
    1311                 :      73824 :   return trustedLemma;
    1312                 :      36912 : }
    1313                 :            : 
    1314                 :    2386820 : bool ConstraintDatabase::hasLiteral(TNode literal) const
    1315                 :            : {
    1316                 :    2386820 :   return lookup(literal) != NullConstraint;
    1317                 :            : }
    1318                 :            : 
    1319                 :     596705 : ConstraintP ConstraintDatabase::addLiteral(TNode literal)
    1320                 :            : {
    1321 [ -  + ][ -  + ]:     596705 :   Assert(!hasLiteral(literal));
                 [ -  - ]
    1322                 :     596705 :   bool isNot = (literal.getKind() == Kind::NOT);
    1323         [ -  + ]:     596705 :   Node atomNode = (isNot ? literal[0] : literal);
    1324                 :     596705 :   Node negationNode = atomNode.notNode();
    1325                 :            : 
    1326 [ -  + ][ -  + ]:     596705 :   Assert(!hasLiteral(atomNode));
                 [ -  - ]
    1327 [ -  + ][ -  + ]:     596705 :   Assert(!hasLiteral(negationNode));
                 [ -  - ]
    1328                 :     596705 :   Comparison posCmp = Comparison::parseNormalForm(atomNode);
    1329                 :            : 
    1330                 :     596705 :   ConstraintType posType = Constraint::constraintTypeOfComparison(posCmp);
    1331                 :            : 
    1332                 :     596705 :   Polynomial nvp = posCmp.normalizedVariablePart();
    1333                 :     596705 :   ArithVar v = d_avariables.asArithVar(nvp.getNode());
    1334                 :            : 
    1335                 :     596705 :   DeltaRational posDR = posCmp.normalizedDeltaRational();
    1336                 :            : 
    1337                 :            :   ConstraintP posC =
    1338                 :     596705 :       new Constraint(v, posType, posDR, options().smt.produceProofs);
    1339                 :            : 
    1340         [ +  - ]:    1193410 :   Trace("arith::constraint")
    1341                 :     596705 :       << "addliteral( literal ->" << literal << ")" << endl;
    1342         [ +  - ]:     596705 :   Trace("arith::constraint") << "addliteral( posC ->" << posC << ")" << endl;
    1343                 :            : 
    1344                 :     596705 :   SortedConstraintMap& scm = getVariableSCM(posC->getVariable());
    1345                 :     596705 :   pair<SortedConstraintMapIterator, bool> insertAttempt;
    1346                 :     596705 :   insertAttempt = scm.insert(make_pair(posC->getValue(), ValueCollection()));
    1347                 :            : 
    1348                 :     596705 :   SortedConstraintMapIterator posI = insertAttempt.first;
    1349                 :            :   // If the attempt succeeds, i points to a new empty ValueCollection
    1350                 :            :   // If the attempt fails, i points to a pre-existing ValueCollection
    1351                 :            : 
    1352         [ +  + ]:     596705 :   if (posI->second.hasConstraintOfType(posC->getType()))
    1353                 :            :   {
    1354                 :            :     // This is the situation where the ConstraintP exists, but
    1355                 :            :     // the literal has not been  associated with it.
    1356                 :       3274 :     ConstraintP hit = posI->second.getConstraintOfType(posC->getType());
    1357         [ +  - ]:       3274 :     Trace("arith::constraint") << "hit " << hit << endl;
    1358         [ +  - ]:       3274 :     Trace("arith::constraint") << "posC " << posC << endl;
    1359                 :            : 
    1360         [ +  - ]:       3274 :     delete posC;
    1361                 :            : 
    1362                 :       3274 :     hit->setLiteral(atomNode);
    1363                 :       3274 :     hit->getNegation()->setLiteral(negationNode);
    1364         [ -  + ]:       3274 :     return isNot ? hit->getNegation() : hit;
    1365                 :            :   }
    1366                 :            :   else
    1367                 :            :   {
    1368                 :     593431 :     Comparison negCmp = Comparison::parseNormalForm(negationNode);
    1369                 :            : 
    1370                 :     593431 :     ConstraintType negType = Constraint::constraintTypeOfComparison(negCmp);
    1371                 :     593431 :     DeltaRational negDR = negCmp.normalizedDeltaRational();
    1372                 :            : 
    1373                 :            :     ConstraintP negC =
    1374                 :     593431 :         new Constraint(v, negType, negDR, options().smt.produceProofs);
    1375                 :            : 
    1376                 :     593431 :     SortedConstraintMapIterator negI;
    1377                 :            : 
    1378         [ +  + ]:     593431 :     if (posC->isEquality())
    1379                 :            :     {
    1380                 :     272268 :       negI = posI;
    1381                 :            :     }
    1382                 :            :     else
    1383                 :            :     {
    1384 [ +  + ][ +  - ]:     321163 :       Assert(posC->isLowerBound() || posC->isUpperBound());
         [ -  + ][ -  + ]
                 [ -  - ]
    1385                 :            : 
    1386                 :     321163 :       pair<SortedConstraintMapIterator, bool> negInsertAttempt;
    1387                 :            :       negInsertAttempt =
    1388                 :     321163 :           scm.insert(make_pair(negC->getValue(), ValueCollection()));
    1389                 :            : 
    1390         [ +  - ]:     321163 :       Trace("nf::tmp") << "sdhjfgdhjkldfgljkhdfg" << endl;
    1391         [ +  - ]:     321163 :       Trace("nf::tmp") << negC << endl;
    1392         [ +  - ]:     321163 :       Trace("nf::tmp") << negC->getValue() << endl;
    1393                 :            : 
    1394                 :            :       // This should always succeed as the DeltaRational for the negation is
    1395                 :            :       // unique!
    1396 [ -  + ][ -  + ]:     321163 :       Assert(negInsertAttempt.second);
                 [ -  - ]
    1397                 :            : 
    1398                 :     321163 :       negI = negInsertAttempt.first;
    1399                 :            :     }
    1400                 :            : 
    1401                 :     593431 :     (posI->second).add(posC);
    1402                 :     593431 :     (negI->second).add(negC);
    1403                 :            : 
    1404                 :     593431 :     posC->initialize(this, posI, negC);
    1405                 :     593431 :     negC->initialize(this, negI, posC);
    1406                 :            : 
    1407                 :     593431 :     posC->setLiteral(atomNode);
    1408                 :     593431 :     negC->setLiteral(negationNode);
    1409                 :            : 
    1410         [ -  + ]:     593431 :     return isNot ? negC : posC;
    1411                 :     593431 :   }
    1412                 :     596705 : }
    1413                 :            : 
    1414                 :   19588080 : ConstraintP ConstraintDatabase::lookup(TNode literal) const
    1415                 :            : {
    1416                 :            :   NodetoConstraintMap::const_iterator iter =
    1417                 :   19588080 :       d_nodetoConstraintMap.find(literal);
    1418         [ +  + ]:   19588080 :   if (iter == d_nodetoConstraintMap.end())
    1419                 :            :   {
    1420                 :    4187979 :     return NullConstraint;
    1421                 :            :   }
    1422                 :            :   else
    1423                 :            :   {
    1424                 :   15400101 :     return iter->second;
    1425                 :            :   }
    1426                 :            : }
    1427                 :            : 
    1428                 :    9137585 : void Constraint::setAssumption(CVC5_UNUSED bool nowInConflict)
    1429                 :            : {
    1430         [ +  - ]:    9137585 :   Trace("constraints::pf") << "setAssumption(" << this << ")" << std::endl;
    1431 [ -  + ][ -  + ]:    9137585 :   Assert(!hasProof());
                 [ -  - ]
    1432 [ -  + ][ -  + ]:    9137585 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
    1433 [ -  + ][ -  + ]:    9137585 :   Assert(hasLiteral());
                 [ -  - ]
    1434 [ -  + ][ -  + ]:    9137585 :   Assert(assertedToTheTheory());
                 [ -  - ]
    1435                 :            : 
    1436                 :    9137585 :   d_database->pushConstraintRule(ConstraintRule(this, AssumeAP));
    1437                 :            : 
    1438 [ -  + ][ -  + ]:    9137585 :   Assert(inConflict() == nowInConflict);
                 [ -  - ]
    1439                 :    9137585 :   if (TraceIsOn("constraint::conflictCommit") && inConflict())
    1440                 :            :   {
    1441         [ -  - ]:          0 :     Trace("constraint::conflictCommit")
    1442                 :          0 :         << "inConflict@setAssumption " << this << std::endl;
    1443                 :            :   }
    1444                 :    9137585 : }
    1445                 :            : 
    1446                 :    6935679 : void Constraint::tryToPropagate()
    1447                 :            : {
    1448 [ -  + ][ -  + ]:    6935679 :   Assert(hasProof());
                 [ -  - ]
    1449 [ -  + ][ -  + ]:    6935679 :   Assert(!isAssumption());
                 [ -  - ]
    1450 [ -  + ][ -  + ]:    6935679 :   Assert(!isInternalAssumption());
                 [ -  - ]
    1451                 :            : 
    1452 [ +  - ][ +  - ]:    8291850 :   if (canBePropagated() && !assertedToTheTheory() && !isAssumption()
    1453 [ +  + ][ +  - ]:    8291850 :       && !isInternalAssumption())
                 [ +  + ]
    1454                 :            :   {
    1455                 :    1356171 :     propagate();
    1456                 :            :   }
    1457                 :    6935679 : }
    1458                 :            : 
    1459                 :    1389153 : void Constraint::propagate()
    1460                 :            : {
    1461 [ -  + ][ -  + ]:    1389153 :   Assert(hasProof());
                 [ -  - ]
    1462 [ -  + ][ -  + ]:    1389153 :   Assert(canBePropagated());
                 [ -  - ]
    1463 [ -  + ][ -  + ]:    1389153 :   Assert(!assertedToTheTheory());
                 [ -  - ]
    1464 [ -  + ][ -  + ]:    1389153 :   Assert(!isAssumption());
                 [ -  - ]
    1465 [ -  + ][ -  + ]:    1389153 :   Assert(!isInternalAssumption());
                 [ -  - ]
    1466                 :            : 
    1467                 :    1389153 :   d_database->d_toPropagate.push(this);
    1468                 :    1389153 : }
    1469                 :            : 
    1470                 :            : /*
    1471                 :            :  * Example:
    1472                 :            :  *    x <= a and a < b
    1473                 :            :  * |= x <= b
    1474                 :            :  * ---
    1475                 :            :  *  1*(x <= a) + (-1)*(x > b) => (0 <= a-b)
    1476                 :            :  */
    1477                 :    3620125 : void Constraint::impliedByUnate(NodeManager* nm,
    1478                 :            :                                 ConstraintCP imp,
    1479                 :            :                                 CVC5_UNUSED bool nowInConflict)
    1480                 :            : {
    1481         [ +  - ]:    7240250 :   Trace("constraints::pf") << "impliedByUnate(" << this << ", " << *imp << ")"
    1482                 :    3620125 :                            << std::endl;
    1483 [ -  + ][ -  + ]:    3620125 :   Assert(!hasProof());
                 [ -  - ]
    1484 [ -  + ][ -  + ]:    3620125 :   Assert(imp->hasProof());
                 [ -  - ]
    1485 [ -  + ][ -  + ]:    3620125 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
    1486                 :            : 
    1487                 :    3620125 :   d_database->d_antecedents.push_back(NullConstraint);
    1488                 :    3620125 :   d_database->d_antecedents.push_back(imp);
    1489                 :            : 
    1490                 :    3620125 :   AntecedentId antecedentEnd = d_database->d_antecedents.size() - 1;
    1491                 :            : 
    1492                 :            :   RationalVectorP coeffs;
    1493         [ +  + ]:    3620125 :   if (d_produceProofs)
    1494                 :            :   {
    1495                 :    2490847 :     std::pair<int, int> sgns = unateFarkasSigns(getNegation(), imp);
    1496                 :            : 
    1497                 :    2490847 :     Rational first(sgns.first);
    1498                 :    2490847 :     Rational second(sgns.second);
    1499                 :            : 
    1500                 :    2490847 :     coeffs = new RationalVector();
    1501                 :    2490847 :     coeffs->push_back(first);
    1502                 :    2490847 :     coeffs->push_back(second);
    1503                 :    2490847 :   }
    1504                 :            :   else
    1505                 :            :   {
    1506                 :    1129278 :     coeffs = RationalVectorPSentinel;
    1507                 :            :   }
    1508                 :            :   // no need to delete coeffs the memory is owned by ConstraintRule
    1509                 :    3620125 :   d_database->pushConstraintRule(
    1510                 :    3620125 :       ConstraintRule(this, FarkasAP, antecedentEnd, coeffs));
    1511                 :            : 
    1512 [ -  + ][ -  + ]:    3620125 :   Assert(inConflict() == nowInConflict);
                 [ -  - ]
    1513                 :    3620125 :   if (TraceIsOn("constraint::conflictCommit") && inConflict())
    1514                 :            :   {
    1515         [ -  - ]:          0 :     Trace("constraint::conflictCommit")
    1516                 :          0 :         << "inConflict@impliedByUnate " << this << std::endl;
    1517                 :            :   }
    1518                 :            : 
    1519                 :    3620125 :   if (TraceIsOn("constraints::wffp") && !wellFormedFarkasProof(nm))
    1520                 :            :   {
    1521         [ -  - ]:          0 :     getConstraintRule().print(Trace("constraints::wffp"), d_produceProofs);
    1522                 :            :   }
    1523 [ -  + ][ -  + ]:    3620125 :   Assert(wellFormedFarkasProof(nm));
                 [ -  - ]
    1524                 :    3620125 : }
    1525                 :            : 
    1526                 :     982702 : void Constraint::impliedByTrichotomy(ConstraintCP a,
    1527                 :            :                                      ConstraintCP b,
    1528                 :            :                                      CVC5_UNUSED bool nowInConflict)
    1529                 :            : {
    1530         [ +  - ]:    1965404 :   Trace("constraints::pf") << "impliedByTrichotomy(" << this << ", " << *a
    1531                 :     982702 :                            << ", ";
    1532         [ +  - ]:     982702 :   Trace("constraints::pf") << *b << ")" << std::endl;
    1533 [ -  + ][ -  + ]:     982702 :   Assert(!hasProof());
                 [ -  - ]
    1534 [ -  + ][ -  + ]:     982702 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
    1535 [ -  + ][ -  + ]:     982702 :   Assert(a->hasProof());
                 [ -  - ]
    1536 [ -  + ][ -  + ]:     982702 :   Assert(b->hasProof());
                 [ -  - ]
    1537                 :            : 
    1538                 :     982702 :   d_database->d_antecedents.push_back(NullConstraint);
    1539                 :     982702 :   d_database->d_antecedents.push_back(a);
    1540                 :     982702 :   d_database->d_antecedents.push_back(b);
    1541                 :            : 
    1542                 :     982702 :   AntecedentId antecedentEnd = d_database->d_antecedents.size() - 1;
    1543                 :     982702 :   d_database->pushConstraintRule(
    1544                 :     982702 :       ConstraintRule(this, TrichotomyAP, antecedentEnd));
    1545                 :            : 
    1546 [ -  + ][ -  + ]:     982702 :   Assert(inConflict() == nowInConflict);
                 [ -  - ]
    1547                 :     982702 :   if (TraceIsOn("constraint::conflictCommit") && inConflict())
    1548                 :            :   {
    1549         [ -  - ]:          0 :     Trace("constraint::conflictCommit")
    1550                 :          0 :         << "inConflict@impliedByTrichotomy " << this << std::endl;
    1551                 :            :   }
    1552                 :     982702 : }
    1553                 :            : 
    1554                 :     167796 : bool Constraint::allHaveProof(const ConstraintCPVec& b)
    1555                 :            : {
    1556                 :     167796 :   for (ConstraintCPVec::const_iterator i = b.begin(), i_end = b.end();
    1557         [ +  + ]:    2016934 :        i != i_end;
    1558                 :    1849138 :        ++i)
    1559                 :            :   {
    1560                 :    1849138 :     ConstraintCP cp = *i;
    1561         [ -  + ]:    1849138 :     if (!(cp->hasProof()))
    1562                 :            :     {
    1563                 :          0 :       return false;
    1564                 :            :     }
    1565                 :            :   }
    1566                 :     167796 :   return true;
    1567                 :            : }
    1568                 :            : 
    1569                 :    2279169 : void Constraint::impliedByIntTighten(ConstraintCP a,
    1570                 :            :                                      CVC5_UNUSED bool nowInConflict)
    1571                 :            : {
    1572         [ +  - ]:    4558338 :   Trace("constraints::pf") << "impliedByIntTighten(" << this << ", " << *a
    1573                 :    2279169 :                            << ")" << std::endl;
    1574 [ -  + ][ -  + ]:    2279169 :   Assert(!hasProof());
                 [ -  - ]
    1575 [ -  + ][ -  + ]:    2279169 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
    1576 [ -  + ][ -  + ]:    2279169 :   Assert(a->hasProof());
                 [ -  - ]
    1577         [ +  - ]:    4558338 :   Trace("pf::arith") << "impliedByIntTighten(" << this << ", " << a << ")"
    1578                 :    2279169 :                      << std::endl;
    1579                 :            : 
    1580                 :    2279169 :   d_database->d_antecedents.push_back(NullConstraint);
    1581                 :    2279169 :   d_database->d_antecedents.push_back(a);
    1582                 :    2279169 :   AntecedentId antecedentEnd = d_database->d_antecedents.size() - 1;
    1583                 :    2279169 :   d_database->pushConstraintRule(
    1584                 :    2279169 :       ConstraintRule(this, IntTightenAP, antecedentEnd));
    1585                 :            : 
    1586 [ -  + ][ -  + ]:    2279169 :   Assert(inConflict() == nowInConflict);
                 [ -  - ]
    1587         [ +  + ]:    2279169 :   if (inConflict())
    1588                 :            :   {
    1589         [ +  - ]:       7188 :     Trace("constraint::conflictCommit")
    1590                 :       3594 :         << "inConflict impliedByIntTighten" << this << std::endl;
    1591                 :            :   }
    1592                 :    2279169 : }
    1593                 :            : 
    1594                 :          0 : void Constraint::impliedByIntHole(ConstraintCP a,
    1595                 :            :                                   CVC5_UNUSED bool nowInConflict)
    1596                 :            : {
    1597         [ -  - ]:          0 :   Trace("constraints::pf") << "impliedByIntHole(" << this << ", " << *a << ")"
    1598                 :          0 :                            << std::endl;
    1599                 :          0 :   Assert(!hasProof());
    1600                 :          0 :   Assert(negationHasProof() == nowInConflict);
    1601                 :          0 :   Assert(a->hasProof());
    1602         [ -  - ]:          0 :   Trace("pf::arith") << "impliedByIntHole(" << this << ", " << a << ")"
    1603                 :          0 :                      << std::endl;
    1604                 :            : 
    1605                 :          0 :   d_database->d_antecedents.push_back(NullConstraint);
    1606                 :          0 :   d_database->d_antecedents.push_back(a);
    1607                 :          0 :   AntecedentId antecedentEnd = d_database->d_antecedents.size() - 1;
    1608                 :          0 :   d_database->pushConstraintRule(
    1609                 :          0 :       ConstraintRule(this, IntHoleAP, antecedentEnd));
    1610                 :            : 
    1611                 :          0 :   Assert(inConflict() == nowInConflict);
    1612                 :          0 :   if (TraceIsOn("constraint::conflictCommit") && inConflict())
    1613                 :            :   {
    1614         [ -  - ]:          0 :     Trace("constraint::conflictCommit")
    1615                 :          0 :         << "inConflict impliedByIntHole" << this << std::endl;
    1616                 :            :   }
    1617                 :          0 : }
    1618                 :            : 
    1619                 :          0 : void Constraint::impliedByIntHole(const ConstraintCPVec& b,
    1620                 :            :                                   CVC5_UNUSED bool nowInConflict)
    1621                 :            : {
    1622         [ -  - ]:          0 :   Trace("constraints::pf") << "impliedByIntHole(" << this;
    1623         [ -  - ]:          0 :   if (TraceIsOn("constraints::pf"))
    1624                 :            :   {
    1625         [ -  - ]:          0 :     for (const ConstraintCP& p : b)
    1626                 :            :     {
    1627         [ -  - ]:          0 :       Trace("constraints::pf") << ", " << p;
    1628                 :            :     }
    1629                 :            :   }
    1630         [ -  - ]:          0 :   Trace("constraints::pf") << ")" << std::endl;
    1631                 :            : 
    1632                 :          0 :   Assert(!hasProof());
    1633                 :          0 :   Assert(negationHasProof() == nowInConflict);
    1634                 :          0 :   Assert(allHaveProof(b));
    1635                 :            : 
    1636                 :          0 :   CDConstraintList& antecedents = d_database->d_antecedents;
    1637                 :          0 :   antecedents.push_back(NullConstraint);
    1638                 :          0 :   for (ConstraintCPVec::const_iterator i = b.begin(), i_end = b.end();
    1639         [ -  - ]:          0 :        i != i_end;
    1640                 :          0 :        ++i)
    1641                 :            :   {
    1642                 :          0 :     antecedents.push_back(*i);
    1643                 :            :   }
    1644                 :          0 :   AntecedentId antecedentEnd = antecedents.size() - 1;
    1645                 :            : 
    1646                 :          0 :   d_database->pushConstraintRule(
    1647                 :          0 :       ConstraintRule(this, IntHoleAP, antecedentEnd));
    1648                 :            : 
    1649                 :          0 :   Assert(inConflict() == nowInConflict);
    1650                 :          0 :   if (TraceIsOn("constraint::conflictCommit") && inConflict())
    1651                 :            :   {
    1652         [ -  - ]:          0 :     Trace("constraint::conflictCommit")
    1653                 :          0 :         << "inConflict@impliedByIntHole[vec] " << this << std::endl;
    1654                 :            :   }
    1655                 :          0 : }
    1656                 :            : 
    1657                 :            : /*
    1658                 :            :  * If proofs are off, coeffs == RationalVectorSentinal.
    1659                 :            :  * If proofs are on,
    1660                 :            :  *   coeffs != RationalVectorSentinal,
    1661                 :            :  *   coeffs->size() = a.size() + 1,
    1662                 :            :  *   for i in [0,a.size) : coeff[i] corresponds to a[i], and
    1663                 :            :  *   coeff.back() corresponds to the current constraint.
    1664                 :            :  */
    1665                 :     167796 : void Constraint::impliedByFarkas(NodeManager* nm,
    1666                 :            :                                  const ConstraintCPVec& a,
    1667                 :            :                                  RationalVectorCP coeffs,
    1668                 :            :                                  CVC5_UNUSED bool nowInConflict)
    1669                 :            : {
    1670         [ +  - ]:     167796 :   Trace("constraints::pf") << "impliedByFarkas(" << this;
    1671         [ -  + ]:     167796 :   if (TraceIsOn("constraints::pf"))
    1672                 :            :   {
    1673         [ -  - ]:          0 :     for (const ConstraintCP& p : a)
    1674                 :            :     {
    1675         [ -  - ]:          0 :       Trace("constraints::pf") << ", " << p;
    1676                 :            :     }
    1677                 :            :   }
    1678         [ +  - ]:     167796 :   Trace("constraints::pf") << ", <coeffs>";
    1679         [ +  - ]:     167796 :   Trace("constraints::pf") << ")" << std::endl;
    1680 [ -  + ][ -  + ]:     167796 :   Assert(!hasProof());
                 [ -  - ]
    1681 [ -  + ][ -  + ]:     167796 :   Assert(negationHasProof() == nowInConflict);
                 [ -  - ]
    1682 [ -  + ][ -  + ]:     167796 :   Assert(allHaveProof(a));
                 [ -  - ]
    1683                 :            : 
    1684 [ -  + ][ -  + ]:     167796 :   Assert(d_produceProofs == (coeffs != RationalVectorCPSentinel));
                 [ -  - ]
    1685 [ +  + ][ +  - ]:     167796 :   Assert(!d_produceProofs || coeffs->size() == a.size() + 1);
         [ -  + ][ -  + ]
                 [ -  - ]
    1686                 :            : 
    1687 [ -  + ][ -  + ]:     167796 :   Assert(a.size() >= 1);
                 [ -  - ]
    1688                 :            : 
    1689                 :     167796 :   d_database->d_antecedents.push_back(NullConstraint);
    1690         [ +  + ]:    2016934 :   for (ConstraintCPVec::const_iterator i = a.begin(), end = a.end(); i != end;
    1691                 :    1849138 :        ++i)
    1692                 :            :   {
    1693                 :    1849138 :     ConstraintCP c_i = *i;
    1694 [ -  + ][ -  + ]:    1849138 :     Assert(c_i->hasProof());
                 [ -  - ]
    1695                 :    1849138 :     d_database->d_antecedents.push_back(c_i);
    1696                 :            :   }
    1697                 :     167796 :   AntecedentId antecedentEnd = d_database->d_antecedents.size() - 1;
    1698                 :            : 
    1699                 :            :   RationalVectorCP coeffsCopy;
    1700         [ +  + ]:     167796 :   if (d_produceProofs)
    1701                 :            :   {
    1702 [ -  + ][ -  + ]:     116137 :     Assert(coeffs != RationalVectorCPSentinel);
                 [ -  - ]
    1703                 :     116137 :     coeffsCopy = new RationalVector(*coeffs);
    1704                 :            :   }
    1705                 :            :   else
    1706                 :            :   {
    1707                 :      51659 :     coeffsCopy = RationalVectorCPSentinel;
    1708                 :            :   }
    1709                 :     167796 :   d_database->pushConstraintRule(
    1710                 :     167796 :       ConstraintRule(this, FarkasAP, antecedentEnd, coeffsCopy));
    1711                 :            : 
    1712 [ -  + ][ -  + ]:     167796 :   Assert(inConflict() == nowInConflict);
                 [ -  - ]
    1713                 :     167796 :   if (TraceIsOn("constraint::conflictCommit") && inConflict())
    1714                 :            :   {
    1715         [ -  - ]:          0 :     Trace("constraint::conflictCommit")
    1716                 :          0 :         << "inConflict@impliedByFarkas " << this << std::endl;
    1717                 :            :   }
    1718                 :     167796 :   if (TraceIsOn("constraints::wffp") && !wellFormedFarkasProof(nm))
    1719                 :            :   {
    1720         [ -  - ]:          0 :     getConstraintRule().print(Trace("constraints::wffp"), d_produceProofs);
    1721                 :            :   }
    1722 [ -  + ][ -  + ]:     167796 :   Assert(wellFormedFarkasProof(nm));
                 [ -  - ]
    1723                 :     167796 : }
    1724                 :            : 
    1725                 :          0 : void Constraint::setInternalAssumption(CVC5_UNUSED bool nowInConflict)
    1726                 :            : {
    1727         [ -  - ]:          0 :   Trace("constraints::pf") << "setInternalAssumption(" << this;
    1728         [ -  - ]:          0 :   Trace("constraints::pf") << ")" << std::endl;
    1729                 :          0 :   Assert(!hasProof());
    1730                 :          0 :   Assert(negationHasProof() == nowInConflict);
    1731                 :          0 :   Assert(!assertedToTheTheory());
    1732                 :            : 
    1733                 :          0 :   d_database->pushConstraintRule(ConstraintRule(this, InternalAssumeAP));
    1734                 :            : 
    1735                 :          0 :   Assert(inConflict() == nowInConflict);
    1736                 :          0 :   if (TraceIsOn("constraint::conflictCommit") && inConflict())
    1737                 :            :   {
    1738         [ -  - ]:          0 :     Trace("constraint::conflictCommit")
    1739                 :          0 :         << "inConflict@setInternalAssumption " << this << std::endl;
    1740                 :            :   }
    1741                 :          0 : }
    1742                 :            : 
    1743                 :     372764 : void Constraint::setEqualityEngineProof()
    1744                 :            : {
    1745         [ +  - ]:     372764 :   Trace("constraints::pf") << "setEqualityEngineProof(" << this;
    1746         [ +  - ]:     372764 :   Trace("constraints::pf") << ")" << std::endl;
    1747 [ -  + ][ -  + ]:     372764 :   Assert(truthIsUnknown());
                 [ -  - ]
    1748 [ -  + ][ -  + ]:     372764 :   Assert(hasLiteral());
                 [ -  - ]
    1749                 :     372764 :   d_database->pushConstraintRule(ConstraintRule(this, EqualityEngineAP));
    1750                 :     372764 : }
    1751                 :            : 
    1752                 :    7450463 : SortedConstraintMap& Constraint::constraintSet() const
    1753                 :            : {
    1754 [ -  + ][ -  + ]:    7450463 :   Assert(d_database->variableDatabaseIsSetup(d_variable));
                 [ -  - ]
    1755                 :    7450463 :   return (d_database->d_varDatabases[d_variable])->d_constraints;
    1756                 :            : }
    1757                 :            : 
    1758                 :          0 : bool Constraint::antecentListIsEmpty() const
    1759                 :            : {
    1760                 :          0 :   Assert(hasProof());
    1761                 :          0 :   return d_database->d_antecedents[getEndAntecedent()] == NullConstraint;
    1762                 :            : }
    1763                 :            : 
    1764                 :          0 : bool Constraint::antecedentListLengthIsOne() const
    1765                 :            : {
    1766                 :          0 :   Assert(hasProof());
    1767                 :          0 :   return !antecentListIsEmpty()
    1768 [ -  - ][ -  - ]:          0 :          && d_database->d_antecedents[getEndAntecedent() - 1] == NullConstraint;
    1769                 :            : }
    1770                 :            : 
    1771                 :     169273 : Node Constraint::externalImplication(NodeManager* nm,
    1772                 :            :                                      const ConstraintCPVec& b) const
    1773                 :            : {
    1774 [ -  + ][ -  + ]:     169273 :   Assert(hasLiteral());
                 [ -  - ]
    1775                 :     169273 :   Node antecedent = externalExplainByAssertions(nm, b);
    1776                 :     169273 :   Node implied = getLiteral();
    1777                 :     338546 :   return antecedent.impNode(implied);
    1778                 :     169273 : }
    1779                 :            : 
    1780                 :     192865 : Node Constraint::externalExplainByAssertions(NodeManager* nm,
    1781                 :            :                                              const ConstraintCPVec& b)
    1782                 :            : {
    1783                 :     192865 :   return externalExplain(nm, b, AssertionOrderSentinel);
    1784                 :            : }
    1785                 :            : 
    1786                 :      17135 : TrustNode Constraint::externalExplainForPropagation(TNode lit) const
    1787                 :            : {
    1788 [ -  + ][ -  + ]:      17135 :   Assert(hasProof());
                 [ -  - ]
    1789 [ -  + ][ -  + ]:      17135 :   Assert(!isAssumption());
                 [ -  - ]
    1790 [ -  + ][ -  + ]:      17135 :   Assert(!isInternalAssumption());
                 [ -  - ]
    1791                 :      17135 :   NodeBuilder nb(d_database->nodeManager(), Kind::AND);
    1792                 :      17135 :   auto pfFromAssumptions = externalExplain(nb, d_assertionOrder);
    1793                 :      17135 :   Node n = mkAndFromBuilder(d_database->nodeManager(), nb);
    1794         [ +  + ]:      17135 :   if (d_database->isProofEnabled())
    1795                 :            :   {
    1796                 :       7717 :     std::vector<Node> assumptions;
    1797         [ +  + ]:       7717 :     if (n.getKind() == Kind::AND)
    1798                 :            :     {
    1799                 :       3596 :       assumptions.insert(assumptions.end(), n.begin(), n.end());
    1800                 :            :     }
    1801                 :            :     else
    1802                 :            :     {
    1803                 :       4121 :       assumptions.push_back(n);
    1804                 :            :     }
    1805         [ +  + ]:       7717 :     if (getProofLiteral() != lit)
    1806                 :            :     {
    1807                 :            :       pfFromAssumptions =
    1808                 :       4454 :           ensurePredTransform(d_database->d_pnm, pfFromAssumptions, lit);
    1809                 :            :     }
    1810                 :      15434 :     auto pf = d_database->d_pnm->mkScope(pfFromAssumptions, assumptions);
    1811                 :       7717 :     return d_database->d_pfGen->mkTrustedPropagation(
    1812                 :       7717 :         lit, d_database->nodeManager()->mkAnd(assumptions), pf);
    1813                 :       7717 :   }
    1814                 :            :   else
    1815                 :            :   {
    1816                 :       9418 :     return TrustNode::mkTrustPropExp(lit, n);
    1817                 :            :   }
    1818                 :      17135 : }
    1819                 :            : 
    1820                 :     121023 : TrustNode Constraint::externalExplainConflict() const
    1821                 :            : {
    1822         [ +  - ]:     121023 :   Trace("pf::arith::explain") << this << std::endl;
    1823 [ -  + ][ -  + ]:     121023 :   Assert(inConflict());
                 [ -  - ]
    1824                 :     121023 :   NodeBuilder nb(d_database->nodeManager(), Kind::AND);
    1825                 :     121023 :   auto pf1 = externalExplainByAssertions(nb);
    1826                 :     121023 :   auto not2 = getNegation()->getProofLiteral().negate();
    1827                 :     121023 :   auto pf2 = getNegation()->externalExplainByAssertions(nb);
    1828                 :     121023 :   Node n = mkAndFromBuilder(d_database->nodeManager(), nb);
    1829         [ +  + ]:     121023 :   if (d_database->isProofEnabled())
    1830                 :            :   {
    1831                 :      54910 :     auto pfNot2 = ensurePredTransform(d_database->d_pnm, pf1, not2);
    1832                 :      54910 :     std::vector<Node> lits;
    1833         [ +  - ]:      54910 :     if (n.getKind() == Kind::AND)
    1834                 :            :     {
    1835                 :      54910 :       lits.insert(lits.end(), n.begin(), n.end());
    1836                 :            :     }
    1837                 :            :     else
    1838                 :            :     {
    1839                 :          0 :       lits.push_back(n);
    1840                 :            :     }
    1841         [ -  + ]:      54910 :     if (TraceIsOn("arith::pf::externalExplainConflict"))
    1842                 :            :     {
    1843         [ -  - ]:          0 :       Trace("arith::pf::externalExplainConflict") << "Lits:" << std::endl;
    1844         [ -  - ]:          0 :       for (const auto& l : lits)
    1845                 :            :       {
    1846         [ -  - ]:          0 :         Trace("arith::pf::externalExplainConflict") << "  : " << l << std::endl;
    1847                 :            :       }
    1848                 :            :     }
    1849                 :            :     std::vector<Node> contraLits = {getProofLiteral(),
    1850                 :     219640 :                                     getNegation()->getProofLiteral()};
    1851                 :            :     auto bot =
    1852                 :      54910 :         not2.getKind() == Kind::NOT
    1853                 :     157329 :             ? d_database->d_pnm->mkNode(ProofRule::CONTRA, {pf2, pfNot2}, {})
    1854                 :     281951 :             : d_database->d_pnm->mkNode(ProofRule::CONTRA, {pfNot2, pf2}, {});
    1855         [ -  + ]:      54910 :     if (TraceIsOn("arith::pf::tree"))
    1856                 :            :     {
    1857         [ -  - ]:          0 :       Trace("arith::pf::tree") << *this << std::endl;
    1858         [ -  - ]:          0 :       Trace("arith::pf::tree") << *getNegation() << std::endl;
    1859         [ -  - ]:          0 :       Trace("arith::pf::tree") << "\n\nTree:\n";
    1860         [ -  - ]:          0 :       printProofTree(Trace("arith::pf::tree"));
    1861         [ -  - ]:          0 :       getNegation()->printProofTree(Trace("arith::pf::tree"));
    1862                 :            :     }
    1863                 :     109820 :     auto confPf = d_database->d_pnm->mkScope(bot, lits);
    1864                 :      54910 :     return d_database->d_pfGen->mkTrustNode(
    1865                 :     109820 :         d_database->nodeManager()->mkAnd(lits), confPf, true);
    1866                 :      54910 :   }
    1867                 :            :   else
    1868                 :            :   {
    1869                 :      66113 :     return TrustNode::mkTrustConflict(n);
    1870                 :            :   }
    1871                 :     121023 : }
    1872                 :            : 
    1873                 :            : struct ConstraintCPHash
    1874                 :            : {
    1875                 :            :   /* Todo replace with an id */
    1876                 :          0 :   size_t operator()(ConstraintCP c) const
    1877                 :            :   {
    1878                 :            :     Assert(sizeof(ConstraintCP) > 0);
    1879                 :          0 :     return ((size_t)c) / sizeof(ConstraintCP);
    1880                 :            :   }
    1881                 :            : };
    1882                 :            : 
    1883                 :          0 : void Constraint::assertionFringe(ConstraintCPVec& v)
    1884                 :            : {
    1885                 :          0 :   unordered_set<ConstraintCP, ConstraintCPHash> visited;
    1886                 :          0 :   size_t writePos = 0;
    1887                 :            : 
    1888         [ -  - ]:          0 :   if (!v.empty())
    1889                 :            :   {
    1890                 :          0 :     const ConstraintDatabase* db = v.back()->d_database;
    1891                 :          0 :     const CDConstraintList& antecedents = db->d_antecedents;
    1892         [ -  - ]:          0 :     for (size_t i = 0; i < v.size(); ++i)
    1893                 :            :     {
    1894                 :          0 :       ConstraintCP vi = v[i];
    1895         [ -  - ]:          0 :       if (visited.find(vi) == visited.end())
    1896                 :            :       {
    1897                 :          0 :         Assert(vi->hasProof());
    1898                 :          0 :         visited.insert(vi);
    1899         [ -  - ]:          0 :         if (vi->onFringe())
    1900                 :            :         {
    1901                 :          0 :           v[writePos] = vi;
    1902                 :          0 :           writePos++;
    1903                 :            :         }
    1904                 :            :         else
    1905                 :            :         {
    1906                 :          0 :           Assert(vi->hasTrichotomyProof() || vi->hasFarkasProof()
    1907                 :            :                  || vi->hasIntHoleProof() || vi->hasIntTightenProof());
    1908                 :          0 :           AntecedentId p = vi->getEndAntecedent();
    1909                 :            : 
    1910                 :          0 :           ConstraintCP antecedent = antecedents[p];
    1911         [ -  - ]:          0 :           while (antecedent != NullConstraint)
    1912                 :            :           {
    1913                 :          0 :             v.push_back(antecedent);
    1914                 :          0 :             --p;
    1915                 :          0 :             antecedent = antecedents[p];
    1916                 :            :           }
    1917                 :            :         }
    1918                 :            :       }
    1919                 :            :     }
    1920                 :          0 :     v.resize(writePos);
    1921                 :            :   }
    1922                 :          0 : }
    1923                 :            : 
    1924                 :          0 : void Constraint::assertionFringe(ConstraintCPVec& o, const ConstraintCPVec& i)
    1925                 :            : {
    1926                 :          0 :   o.insert(o.end(), i.begin(), i.end());
    1927                 :          0 :   assertionFringe(o);
    1928                 :          0 : }
    1929                 :            : 
    1930                 :     192865 : Node Constraint::externalExplain(NodeManager* nm,
    1931                 :            :                                  const ConstraintCPVec& v,
    1932                 :            :                                  AssertionOrder order)
    1933                 :            : {
    1934                 :     192865 :   NodeBuilder nb(nm, Kind::AND);
    1935                 :     192865 :   ConstraintCPVec::const_iterator i, end;
    1936         [ +  + ]:     800985 :   for (i = v.begin(), end = v.end(); i != end; ++i)
    1937                 :            :   {
    1938                 :     608120 :     ConstraintCP v_i = *i;
    1939                 :     608120 :     v_i->externalExplain(nb, order);
    1940                 :            :   }
    1941                 :     385730 :   return mkAndFromBuilder(nm, nb);
    1942                 :     192865 : }
    1943                 :            : 
    1944                 :    8844700 : std::shared_ptr<ProofNode> Constraint::externalExplain(
    1945                 :            :     NodeBuilder& nb, AssertionOrder order) const
    1946                 :            : {
    1947         [ -  + ]:    8844700 :   if (TraceIsOn("pf::arith::explain"))
    1948                 :            :   {
    1949         [ -  - ]:          0 :     this->printProofTree(Trace("arith::pf::tree"));
    1950         [ -  - ]:          0 :     Trace("pf::arith::explain") << "Explaining: " << this << " with rule ";
    1951         [ -  - ]:          0 :     getConstraintRule().print(Trace("pf::arith::explain"), d_produceProofs);
    1952         [ -  - ]:          0 :     Trace("pf::arith::explain") << std::endl;
    1953                 :            :   }
    1954 [ -  + ][ -  + ]:    8844700 :   Assert(hasProof());
                 [ -  - ]
    1955 [ +  + ][ +  - ]:    8844700 :   Assert(!isAssumption() || assertedToTheTheory());
         [ -  + ][ -  + ]
                 [ -  - ]
    1956 [ -  + ][ -  + ]:    8844700 :   Assert(!isInternalAssumption());
                 [ -  - ]
    1957                 :    8844700 :   std::shared_ptr<ProofNode> pf{};
    1958                 :            : 
    1959                 :    8844700 :   ProofNodeManager* pnm = d_database->d_pnm;
    1960                 :            : 
    1961         [ +  + ]:    8844700 :   if (assertedBefore(order))
    1962                 :            :   {
    1963         [ +  - ]:    7521654 :     Trace("pf::arith::explain") << "  already asserted" << std::endl;
    1964                 :    7521654 :     nb << getWitness();
    1965         [ +  + ]:    7521654 :     if (d_database->isProofEnabled())
    1966                 :            :     {
    1967                 :    3232906 :       pf = pnm->mkAssume(getWitness());
    1968                 :            :       // If the witness and literal differ, prove the difference through a
    1969                 :            :       // rewrite.
    1970                 :    3232906 :       pf = ensurePredTransform(pnm, pf, getProofLiteral());
    1971                 :            :     }
    1972                 :            :   }
    1973         [ +  + ]:    1323046 :   else if (hasEqualityEngineProof())
    1974                 :            :   {
    1975                 :            :     // just assume, it will be explained again
    1976                 :        484 :     Node lit = getLiteral();
    1977         [ +  + ]:        484 :     if (d_database->isProofEnabled())
    1978                 :            :     {
    1979                 :        227 :       std::shared_ptr<ProofNode> a = pnm->mkAssume(getLiteral());
    1980                 :        227 :       Node plit = getProofLiteral();
    1981                 :        227 :       pf = ensurePredTransform(pnm, a, plit);
    1982                 :        227 :     }
    1983 [ -  + ][ -  + ]:        484 :     Assert(lit.getKind() != Kind::AND);
                 [ -  - ]
    1984                 :        484 :     nb << lit;
    1985                 :        484 :   }
    1986                 :            :   else
    1987                 :            :   {
    1988         [ +  - ]:    1322562 :     Trace("pf::arith::explain") << "  recursion!" << std::endl;
    1989 [ -  + ][ -  + ]:    1322562 :     Assert(!isAssumption());
                 [ -  - ]
    1990                 :    1322562 :     AntecedentId p = getEndAntecedent();
    1991                 :    1322562 :     ConstraintCP antecedent = d_database->d_antecedents[p];
    1992                 :    1322562 :     std::vector<std::shared_ptr<ProofNode>> children;
    1993                 :            : 
    1994         [ +  + ]:    3739589 :     while (antecedent != NullConstraint)
    1995                 :            :     {
    1996         [ +  - ]:    2417027 :       Trace("pf::arith::explain") << "Explain " << antecedent << std::endl;
    1997                 :    2417027 :       auto pn = antecedent->externalExplain(nb, order);
    1998         [ +  + ]:    2417027 :       if (d_database->isProofEnabled())
    1999                 :            :       {
    2000                 :     989040 :         children.push_back(pn);
    2001                 :            :       }
    2002                 :    2417027 :       --p;
    2003                 :    2417027 :       antecedent = d_database->d_antecedents[p];
    2004                 :    2417027 :     }
    2005                 :            : 
    2006         [ +  + ]:    1322562 :     if (d_database->isProofEnabled())
    2007                 :            :     {
    2008 [ -  + ][ +  - ]:     638342 :       switch (getProofType())
                 [ +  - ]
    2009                 :            :       {
    2010                 :          0 :         case ArithProofType::AssumeAP:
    2011                 :            :         case ArithProofType::EqualityEngineAP:
    2012                 :            :         {
    2013                 :          0 :           Unreachable() << "These should be handled above";
    2014                 :            :           break;
    2015                 :            :         }
    2016                 :      59560 :         case ArithProofType::FarkasAP:
    2017                 :            :         {
    2018                 :            :           // Per docs in constraint.h,
    2019                 :            :           // the 0th farkas coefficient is for the negation of the deduced
    2020                 :            :           // constraint the 1st corresponds to the last antecedent the nth
    2021                 :            :           // corresponds to the first antecedent Then, the farkas coefficients
    2022                 :            :           // and the antecedents are in the same order.
    2023                 :            : 
    2024                 :            :           // Enumerate child proofs (negation included) in d_farkasCoefficients
    2025                 :            :           // order
    2026                 :      59560 :           Node plit = getNegation()->getProofLiteral();
    2027                 :      59560 :           std::vector<std::shared_ptr<ProofNode>> farkasChildren;
    2028                 :      59560 :           farkasChildren.push_back(pnm->mkAssume(plit));
    2029                 :      59560 :           farkasChildren.insert(
    2030                 :      59560 :               farkasChildren.end(), children.rbegin(), children.rend());
    2031                 :            : 
    2032                 :      59560 :           NodeManager* nm = d_database->nodeManager();
    2033                 :            : 
    2034                 :            :           // Enumerate d_farkasCoefficients as nodes.
    2035                 :      59560 :           std::vector<Node> farkasCoeffs;
    2036                 :      59560 :           TypeNode type = plit[0].getType();
    2037         [ +  + ]:     489609 :           for (Rational r : *getFarkasCoefficients())
    2038                 :            :           {
    2039                 :     430049 :             farkasCoeffs.push_back(nm->mkConstRealOrInt(Rational(r)));
    2040                 :     430049 :           }
    2041                 :            :           std::vector<Node> farkasCoeffsUse =
    2042                 :      59560 :               getMacroSumUbCoeff(nm, farkasChildren, farkasCoeffs);
    2043                 :            : 
    2044                 :            :           // Apply the scaled-sum rule.
    2045                 :            :           std::shared_ptr<ProofNode> sumPf =
    2046                 :            :               pnm->mkNode(ProofRule::MACRO_ARITH_SCALE_SUM_UB,
    2047                 :            :                           farkasChildren,
    2048                 :      59560 :                           farkasCoeffsUse);
    2049                 :            : 
    2050                 :            :           // Provable rewrite the result
    2051                 :      59560 :           Node falsen = nm->mkConst(false);
    2052                 :      59560 :           auto botPf = ensurePredTransform(pnm, sumPf, falsen);
    2053                 :            : 
    2054                 :            :           // Scope out the negated constraint, yielding a proof of the
    2055                 :            :           // constraint.
    2056                 :     178680 :           std::vector<Node> assump{plit};
    2057                 :     119120 :           auto maybeDoubleNotPf = pnm->mkScope(botPf, assump, false);
    2058                 :            : 
    2059                 :            :           // No need to ensure that the expected node aggrees with `assump`
    2060                 :            :           // because we are not providing an expected node.
    2061                 :            :           //
    2062                 :            :           // Prove that this is the literal (may need to clean a double-not)
    2063                 :      59560 :           Node plit2 = getProofLiteral();
    2064                 :      59560 :           pf = ensurePredTransform(pnm, maybeDoubleNotPf, plit2);
    2065                 :            : 
    2066                 :      59560 :           break;
    2067                 :      59560 :         }
    2068                 :     539013 :         case ArithProofType::IntTightenAP:
    2069                 :            :         {
    2070         [ +  + ]:     539013 :           if (isUpperBound())
    2071                 :            :           {
    2072                 :    1059102 :             pf = pnm->mkNode(
    2073                 :    1588653 :                 ProofRule::INT_TIGHT_UB, children, {}, getProofLiteral());
    2074                 :            :           }
    2075         [ +  - ]:       9462 :           else if (isLowerBound())
    2076                 :            :           {
    2077                 :      18924 :             pf = pnm->mkNode(
    2078                 :      28386 :                 ProofRule::INT_TIGHT_LB, children, {}, getProofLiteral());
    2079                 :            :           }
    2080                 :            :           else
    2081                 :            :           {
    2082                 :          0 :             Unreachable();
    2083                 :            :           }
    2084                 :     539013 :           break;
    2085                 :            :         }
    2086                 :          0 :         case ArithProofType::IntHoleAP:
    2087                 :            :         {
    2088                 :            :           // Use proofLit to ensure deterministic node ID assignments
    2089                 :          0 :           Node proofLit = getProofLiteral();
    2090                 :          0 :           pf = pnm->mkTrustedNode(
    2091                 :          0 :               TrustId::THEORY_INFERENCE_ARITH, children, {proofLit}, proofLit);
    2092                 :          0 :           break;
    2093                 :          0 :         }
    2094                 :      39769 :         case ArithProofType::TrichotomyAP:
    2095                 :            :         {
    2096                 :      79538 :           pf = pnm->mkNode(
    2097                 :     119307 :               ProofRule::ARITH_TRICHOTOMY, children, {}, getProofLiteral());
    2098                 :      39769 :           break;
    2099                 :            :         }
    2100                 :          0 :         case ArithProofType::InternalAssumeAP:
    2101                 :            :         case ArithProofType::NoAP:
    2102                 :            :         default:
    2103                 :            :         {
    2104                 :          0 :           Unreachable() << getProofType()
    2105                 :          0 :                         << " should not be visible in explanation";
    2106                 :            :           break;
    2107                 :            :         }
    2108                 :            :       }
    2109                 :            :     }
    2110                 :    1322562 :   }
    2111                 :    8844700 :   return pf;
    2112                 :          0 : }
    2113                 :            : 
    2114                 :       1730 : Node Constraint::externalExplainByAssertions(NodeManager* nm,
    2115                 :            :                                              ConstraintCP a,
    2116                 :            :                                              ConstraintCP b)
    2117                 :            : {
    2118                 :       1730 :   NodeBuilder nb(nm, Kind::AND);
    2119                 :       1730 :   a->externalExplainByAssertions(nb);
    2120                 :       1730 :   b->externalExplainByAssertions(nb);
    2121                 :       3460 :   return nb;
    2122                 :       1730 : }
    2123                 :            : 
    2124                 :          0 : Node Constraint::externalExplainByAssertions(NodeManager* nm,
    2125                 :            :                                              ConstraintCP a,
    2126                 :            :                                              ConstraintCP b,
    2127                 :            :                                              ConstraintCP c)
    2128                 :            : {
    2129                 :          0 :   NodeBuilder nb(nm, Kind::AND);
    2130                 :          0 :   a->externalExplainByAssertions(nb);
    2131                 :          0 :   b->externalExplainByAssertions(nb);
    2132                 :          0 :   c->externalExplainByAssertions(nb);
    2133                 :          0 :   return nb;
    2134                 :          0 : }
    2135                 :            : 
    2136                 :     827405 : ConstraintP Constraint::getStrictlyWeakerLowerBound(bool hasLiteral,
    2137                 :            :                                                     bool asserted) const
    2138                 :            : {
    2139 [ -  + ][ -  + ]:     827405 :   Assert(initialized());
                 [ -  - ]
    2140 [ +  + ][ +  - ]:     827405 :   Assert(!asserted || hasLiteral);
         [ -  + ][ -  + ]
                 [ -  - ]
    2141                 :            : 
    2142                 :     827405 :   SortedConstraintMapConstIterator i = d_variablePosition;
    2143                 :     827405 :   const SortedConstraintMap& scm = constraintSet();
    2144                 :     827405 :   SortedConstraintMapConstIterator i_begin = scm.begin();
    2145         [ +  + ]:    1716779 :   while (i != i_begin)
    2146                 :            :   {
    2147                 :    1052544 :     --i;
    2148                 :    1052544 :     const ValueCollection& vc = i->second;
    2149         [ +  + ]:    1052544 :     if (vc.hasLowerBound())
    2150                 :            :     {
    2151                 :     328317 :       ConstraintP weaker = vc.getLowerBound();
    2152                 :            : 
    2153                 :            :       // asserted -> hasLiteral
    2154                 :            :       // hasLiteral -> weaker->hasLiteral()
    2155                 :            :       // asserted -> weaker->assertedToTheTheory()
    2156         [ +  + ]:     328317 :       if ((!hasLiteral || (weaker->hasLiteral()))
    2157 [ +  - ][ +  + ]:     656634 :           && (!asserted || (weaker->assertedToTheTheory())))
         [ +  + ][ +  + ]
    2158                 :            :       {
    2159                 :     163170 :         return weaker;
    2160                 :            :       }
    2161                 :            :     }
    2162                 :            :   }
    2163                 :     664235 :   return NullConstraint;
    2164                 :            : }
    2165                 :            : 
    2166                 :     582879 : ConstraintP Constraint::getStrictlyWeakerUpperBound(bool hasLiteral,
    2167                 :            :                                                     bool asserted) const
    2168                 :            : {
    2169                 :     582879 :   SortedConstraintMapConstIterator i = d_variablePosition;
    2170                 :     582879 :   const SortedConstraintMap& scm = constraintSet();
    2171                 :     582879 :   SortedConstraintMapConstIterator i_end = scm.end();
    2172                 :            : 
    2173                 :     582879 :   ++i;
    2174         [ +  + ]:    1086645 :   for (; i != i_end; ++i)
    2175                 :            :   {
    2176                 :     709810 :     const ValueCollection& vc = i->second;
    2177         [ +  + ]:     709810 :     if (vc.hasUpperBound())
    2178                 :            :     {
    2179                 :     260466 :       ConstraintP weaker = vc.getUpperBound();
    2180         [ +  + ]:     260466 :       if ((!hasLiteral || (weaker->hasLiteral()))
    2181 [ +  - ][ +  + ]:     520932 :           && (!asserted || (weaker->assertedToTheTheory())))
         [ +  + ][ +  + ]
    2182                 :            :       {
    2183                 :     206044 :         return weaker;
    2184                 :            :       }
    2185                 :            :     }
    2186                 :            :   }
    2187                 :            : 
    2188                 :     376835 :   return NullConstraint;
    2189                 :            : }
    2190                 :            : 
    2191                 :    8872163 : ConstraintP ConstraintDatabase::getBestImpliedBound(
    2192                 :            :     ArithVar v, ConstraintType t, const DeltaRational& r) const
    2193                 :            : {
    2194 [ -  + ][ -  + ]:    8872163 :   Assert(variableDatabaseIsSetup(v));
                 [ -  - ]
    2195 [ +  + ][ +  - ]:    8872163 :   Assert(t == UpperBound || t == LowerBound);
         [ -  + ][ -  + ]
                 [ -  - ]
    2196                 :            : 
    2197                 :    8872163 :   SortedConstraintMap& scm = getVariableSCM(v);
    2198         [ +  + ]:    8872163 :   if (t == UpperBound)
    2199                 :            :   {
    2200                 :    4228090 :     SortedConstraintMapConstIterator i = scm.lower_bound(r);
    2201                 :    4228090 :     SortedConstraintMapConstIterator i_end = scm.end();
    2202 [ +  + ][ +  - ]:    4228090 :     Assert(i == i_end || r <= i->first);
         [ -  + ][ -  + ]
                 [ -  - ]
    2203         [ +  + ]:    6389073 :     for (; i != i_end; i++)
    2204                 :            :     {
    2205 [ -  + ][ -  + ]:    3707768 :       Assert(r <= i->first);
                 [ -  - ]
    2206                 :    3707768 :       const ValueCollection& vc = i->second;
    2207         [ +  + ]:    3707768 :       if (vc.hasUpperBound())
    2208                 :            :       {
    2209                 :    1546785 :         return vc.getUpperBound();
    2210                 :            :       }
    2211                 :            :     }
    2212                 :    2681305 :     return NullConstraint;
    2213                 :            :   }
    2214                 :            :   else
    2215                 :            :   {
    2216 [ -  + ][ -  + ]:    4644073 :     Assert(t == LowerBound);
                 [ -  - ]
    2217         [ +  + ]:    4644073 :     if (scm.empty())
    2218                 :            :     {
    2219                 :     378163 :       return NullConstraint;
    2220                 :            :     }
    2221                 :            :     else
    2222                 :            :     {
    2223                 :    4265910 :       SortedConstraintMapConstIterator i = scm.lower_bound(r);
    2224                 :    4265910 :       SortedConstraintMapConstIterator i_begin = scm.begin();
    2225                 :    4265910 :       SortedConstraintMapConstIterator i_end = scm.end();
    2226 [ +  + ][ +  - ]:    4265910 :       Assert(i == i_end || r <= i->first);
         [ -  + ][ -  + ]
                 [ -  - ]
    2227                 :            : 
    2228                 :    4265910 :       int fdj = 0;
    2229                 :            : 
    2230         [ +  + ]:    4265910 :       if (i == i_end)
    2231                 :            :       {
    2232                 :    1703717 :         --i;
    2233         [ +  - ]:    3407434 :         Trace("getBestImpliedBound")
    2234                 :    1703717 :             << fdj++ << " " << r << " " << i->first << endl;
    2235                 :            :       }
    2236         [ +  + ]:    2562193 :       else if ((i->first) > r)
    2237                 :            :       {
    2238         [ +  + ]:     739357 :         if (i == i_begin)
    2239                 :            :         {
    2240                 :     644222 :           return NullConstraint;
    2241                 :            :         }
    2242                 :            :         else
    2243                 :            :         {
    2244                 :      95135 :           --i;
    2245         [ +  - ]:     190270 :           Trace("getBestImpliedBound")
    2246                 :      95135 :               << fdj++ << " " << r << " " << i->first << endl;
    2247                 :            :         }
    2248                 :            :       }
    2249                 :            : 
    2250                 :            :       do
    2251                 :            :       {
    2252         [ +  - ]:    7938570 :         Trace("getBestImpliedBound")
    2253                 :    3969285 :             << fdj++ << " " << r << " " << i->first << endl;
    2254 [ -  + ][ -  + ]:    3969285 :         Assert(r >= i->first);
                 [ -  - ]
    2255                 :    3969285 :         const ValueCollection& vc = i->second;
    2256                 :            : 
    2257         [ +  + ]:    3969285 :         if (vc.hasLowerBound())
    2258                 :            :         {
    2259                 :    1907499 :           return vc.getLowerBound();
    2260                 :            :         }
    2261                 :            : 
    2262         [ +  + ]:    2061786 :         if (i == i_begin)
    2263                 :            :         {
    2264                 :    1714189 :           break;
    2265                 :            :         }
    2266                 :            :         else
    2267                 :            :         {
    2268                 :     347597 :           --i;
    2269                 :            :         }
    2270                 :     347597 :       } while (true);
    2271                 :    1714189 :       return NullConstraint;
    2272                 :            :     }
    2273                 :            :   }
    2274                 :            : }
    2275                 :            : 
    2276                 :   30384100 : bool ConstraintDatabase::variableDatabaseIsSetup(ArithVar v) const
    2277                 :            : {
    2278                 :   30384100 :   return v < d_varDatabases.size();
    2279                 :            : }
    2280                 :            : 
    2281                 :      51016 : ConstraintDatabase::Watches::Watches(context::Context* satContext,
    2282                 :      51016 :                                      context::Context* userContext)
    2283                 :      51016 :     : d_constraintProofs(satContext),
    2284                 :      51016 :       d_canBePropagatedWatches(satContext),
    2285                 :      51016 :       d_assertionOrderWatches(satContext),
    2286                 :      51016 :       d_splitWatches(userContext)
    2287                 :            : {
    2288                 :      51016 : }
    2289                 :            : 
    2290                 :    1193410 : void Constraint::setLiteral(Node n)
    2291                 :            : {
    2292         [ +  - ]:    1193410 :   Trace("arith::constraint") << "Mapping " << *this << " to " << n << std::endl;
    2293 [ -  + ][ -  + ]:    1193410 :   Assert(Comparison::isNormalAtom(n));
                 [ -  - ]
    2294 [ -  + ][ -  + ]:    1193410 :   Assert(!hasLiteral());
                 [ -  - ]
    2295 [ -  + ][ -  + ]:    1193410 :   Assert(sanityChecking(n));
                 [ -  - ]
    2296                 :    1193410 :   d_literal = n;
    2297                 :    1193410 :   NodetoConstraintMap& map = d_database->d_nodetoConstraintMap;
    2298 [ -  + ][ -  + ]:    1193410 :   Assert(map.find(n) == map.end());
                 [ -  - ]
    2299                 :    1193410 :   map.insert(make_pair(d_literal, this));
    2300                 :    1193410 : }
    2301                 :            : 
    2302                 :    4633248 : Node Constraint::getProofLiteral() const
    2303                 :            : {
    2304 [ -  + ][ -  + ]:    4633248 :   Assert(d_database != nullptr);
                 [ -  - ]
    2305 [ -  + ][ -  + ]:    4633248 :   Assert(d_database->d_avariables.hasNode(d_variable));
                 [ -  - ]
    2306                 :    4633248 :   Node varPart = d_database->d_avariables.asNode(d_variable);
    2307                 :            :   Kind cmp;
    2308                 :    4633248 :   bool neg = false;
    2309 [ +  + ][ +  + ]:    4633248 :   switch (d_type)
                    [ - ]
    2310                 :            :   {
    2311                 :    1725103 :     case ConstraintType::UpperBound:
    2312                 :            :     {
    2313         [ +  + ]:    1725103 :       if (d_value.infinitesimalIsZero())
    2314                 :            :       {
    2315                 :     890247 :         cmp = Kind::LEQ;
    2316                 :            :       }
    2317                 :            :       else
    2318                 :            :       {
    2319                 :     834856 :         cmp = Kind::LT;
    2320                 :            :       }
    2321                 :    1725103 :       break;
    2322                 :            :     }
    2323                 :    1103529 :     case ConstraintType::LowerBound:
    2324                 :            :     {
    2325         [ +  + ]:    1103529 :       if (d_value.infinitesimalIsZero())
    2326                 :            :       {
    2327                 :     966302 :         cmp = Kind::GEQ;
    2328                 :            :       }
    2329                 :            :       else
    2330                 :            :       {
    2331                 :     137227 :         cmp = Kind::GT;
    2332                 :            :       }
    2333                 :    1103529 :       break;
    2334                 :            :     }
    2335                 :    1549174 :     case ConstraintType::Equality:
    2336                 :            :     {
    2337                 :    1549174 :       cmp = Kind::EQUAL;
    2338                 :    1549174 :       break;
    2339                 :            :     }
    2340                 :     255442 :     case ConstraintType::Disequality:
    2341                 :            :     {
    2342                 :     255442 :       cmp = Kind::EQUAL;
    2343                 :     255442 :       neg = true;
    2344                 :     255442 :       break;
    2345                 :            :     }
    2346                 :          0 :     default: Unreachable() << d_type;
    2347                 :            :   }
    2348                 :    4633248 :   NodeManager* nm = d_database->nodeManager();
    2349                 :            :   Node constPart = nm->mkConstRealOrInt(
    2350                 :   13899744 :       varPart.getType(), Rational(d_value.getNoninfinitesimalPart()));
    2351                 :   13899744 :   Node posLit = nm->mkNode(cmp, varPart, constPart);
    2352         [ +  + ]:    9266496 :   return neg ? posLit.negate() : posLit;
    2353                 :    4633248 : }
    2354                 :            : 
    2355                 :      75406 : void ConstraintDatabase::proveOr(std::vector<TrustNode>& out,
    2356                 :            :                                  ConstraintP a,
    2357                 :            :                                  ConstraintP b,
    2358                 :            :                                  bool negateSecond) const
    2359                 :            : {
    2360                 :      75406 :   Node la = a->getLiteral();
    2361                 :      75406 :   Node lb = b->getLiteral();
    2362         [ +  + ]:      75406 :   Node orN = (la < lb) ? la.orNode(lb) : lb.orNode(la);
    2363         [ +  + ]:      75406 :   if (isProofEnabled())
    2364                 :            :   {
    2365 [ -  + ][ -  + ]:      32643 :     Assert(b->getNegation()->getType() != ConstraintType::Disequality);
                 [ -  - ]
    2366                 :      32643 :     auto nm = nodeManager();
    2367                 :      32643 :     Node alit = a->getNegation()->getProofLiteral();
    2368                 :      32643 :     TypeNode type = alit[0].getType();
    2369                 :      32643 :     auto pf_neg_la = d_pnm->mkAssume(la.negate());
    2370                 :      32643 :     pf_neg_la = ensurePredTransform(d_pnm, pf_neg_la, alit);
    2371                 :      32643 :     Node blit = b->getNegation()->getProofLiteral();
    2372                 :      32643 :     auto pf_neg_lb = d_pnm->mkAssume(lb.negate());
    2373                 :      32643 :     pf_neg_lb = ensurePredTransform(d_pnm, pf_neg_lb, blit);
    2374         [ +  + ]:      32643 :     int sndSign = negateSecond ? -1 : 1;
    2375                 :     130572 :     std::vector<Pf> args{pf_neg_la, pf_neg_lb};
    2376                 :          0 :     std::vector<Node> coeffs{nm->mkConstReal(Rational(-1 * sndSign)),
    2377                 :     163215 :                              nm->mkConstReal(Rational(sndSign))};
    2378                 :      32643 :     std::vector<Node> coeffsUse = getMacroSumUbCoeff(nm, args, coeffs);
    2379                 :            :     auto sumubpf =
    2380                 :      32643 :         d_pnm->mkNode(ProofRule::MACRO_ARITH_SCALE_SUM_UB, args, coeffsUse);
    2381                 :      32643 :     auto bot_pf = ensurePredTransform(d_pnm, sumubpf, nm->mkConst(false));
    2382                 :      32643 :     std::vector<Node> as;
    2383                 :      32643 :     std::transform(orN.begin(), orN.end(), std::back_inserter(as), [](Node n) {
    2384                 :      65286 :       return n.negate();
    2385                 :            :     });
    2386                 :            :     // No need to ensure that the expected node aggrees with `as` because we
    2387                 :            :     // are not providing an expected node.
    2388                 :            :     auto pf =
    2389                 :     130572 :         d_pnm->mkNode(ProofRule::NOT_AND, {d_pnm->mkScope(bot_pf, as)}, {});
    2390                 :      32643 :     pf = ensurePredTransform(d_pnm, pf, orN);
    2391                 :      32643 :     out.push_back(d_pfGen->mkTrustNode(orN, pf));
    2392                 :      32643 :   }
    2393                 :            :   else
    2394                 :            :   {
    2395                 :      42763 :     out.push_back(TrustNode::mkTrustLemma(orN));
    2396                 :            :   }
    2397                 :      75406 : }
    2398                 :            : 
    2399                 :      70375 : void ConstraintDatabase::implies(std::vector<TrustNode>& out,
    2400                 :            :                                  ConstraintP a,
    2401                 :            :                                  ConstraintP b) const
    2402                 :            : {
    2403                 :      70375 :   Node la = a->getLiteral();
    2404                 :      70375 :   Node lb = b->getLiteral();
    2405                 :            : 
    2406         [ +  + ]:      70375 :   Node neg_la = (la.getKind() == Kind::NOT) ? la[0] : la.notNode();
    2407                 :            : 
    2408 [ -  + ][ -  + ]:      70375 :   Assert(lb != neg_la);
                 [ -  - ]
    2409 [ +  + ][ +  - ]:      70375 :   Assert(b->getNegation()->getType() == ConstraintType::LowerBound
         [ -  + ][ -  + ]
                 [ -  - ]
    2410                 :            :          || b->getNegation()->getType() == ConstraintType::UpperBound);
    2411                 :      70375 :   proveOr(out,
    2412                 :            :           a->getNegation(),
    2413                 :            :           b,
    2414                 :      70375 :           b->getNegation()->getType() == ConstraintType::LowerBound);
    2415                 :      70375 : }
    2416                 :            : 
    2417                 :       5031 : void ConstraintDatabase::mutuallyExclusive(std::vector<TrustNode>& out,
    2418                 :            :                                            ConstraintP a,
    2419                 :            :                                            ConstraintP b) const
    2420                 :            : {
    2421                 :       5031 :   Node la = a->getLiteral();
    2422                 :       5031 :   Node lb = b->getLiteral();
    2423                 :            : 
    2424                 :       5031 :   Node neg_la = la.negate();
    2425                 :       5031 :   Node neg_lb = lb.negate();
    2426                 :       5031 :   proveOr(out, a->getNegation(), b->getNegation(), true);
    2427                 :       5031 : }
    2428                 :            : 
    2429                 :     116538 : void ConstraintDatabase::outputUnateInequalityLemmas(
    2430                 :            :     std::vector<TrustNode>& out, ArithVar v) const
    2431                 :            : {
    2432                 :     116538 :   SortedConstraintMap& scm = getVariableSCM(v);
    2433                 :     116538 :   SortedConstraintMapConstIterator scm_iter = scm.begin();
    2434                 :     116538 :   SortedConstraintMapConstIterator scm_end = scm.end();
    2435                 :     116538 :   ConstraintP prev = NullConstraint;
    2436                 :            :   // get transitive unates
    2437                 :            :   // Only lower bounds or upperbounds should be done.
    2438         [ +  + ]:     373396 :   for (; scm_iter != scm_end; ++scm_iter)
    2439                 :            :   {
    2440                 :     256858 :     const ValueCollection& vc = scm_iter->second;
    2441         [ +  + ]:     256858 :     if (vc.hasUpperBound())
    2442                 :            :     {
    2443                 :     120728 :       ConstraintP ub = vc.getUpperBound();
    2444         [ +  + ]:     120728 :       if (ub->hasLiteral())
    2445                 :            :       {
    2446         [ +  + ]:     120726 :         if (prev != NullConstraint)
    2447                 :            :         {
    2448                 :      52630 :           implies(out, prev, ub);
    2449                 :            :         }
    2450                 :     120726 :         prev = ub;
    2451                 :            :       }
    2452                 :            :     }
    2453                 :            :   }
    2454                 :     116538 : }
    2455                 :            : 
    2456                 :     116538 : void ConstraintDatabase::outputUnateEqualityLemmas(std::vector<TrustNode>& out,
    2457                 :            :                                                    ArithVar v) const
    2458                 :            : {
    2459                 :     116538 :   vector<ConstraintP> equalities;
    2460                 :            : 
    2461                 :     116538 :   SortedConstraintMap& scm = getVariableSCM(v);
    2462                 :     116538 :   SortedConstraintMapConstIterator scm_iter = scm.begin();
    2463                 :     116538 :   SortedConstraintMapConstIterator scm_end = scm.end();
    2464                 :            : 
    2465         [ +  + ]:     373396 :   for (; scm_iter != scm_end; ++scm_iter)
    2466                 :            :   {
    2467                 :     256858 :     const ValueCollection& vc = scm_iter->second;
    2468         [ +  + ]:     256858 :     if (vc.hasEquality())
    2469                 :            :     {
    2470                 :      37953 :       ConstraintP eq = vc.getEquality();
    2471         [ +  - ]:      37953 :       if (eq->hasLiteral())
    2472                 :            :       {
    2473                 :      37953 :         equalities.push_back(eq);
    2474                 :            :       }
    2475                 :            :     }
    2476                 :            :   }
    2477                 :            : 
    2478                 :     116538 :   vector<ConstraintP>::const_iterator i, j, eq_end = equalities.end();
    2479         [ +  + ]:     154491 :   for (i = equalities.begin(); i != eq_end; ++i)
    2480                 :            :   {
    2481                 :      37953 :     ConstraintP at_i = *i;
    2482         [ +  + ]:      42984 :     for (j = i + 1; j != eq_end; ++j)
    2483                 :            :     {
    2484                 :       5031 :       ConstraintP at_j = *j;
    2485                 :            : 
    2486                 :       5031 :       mutuallyExclusive(out, at_i, at_j);
    2487                 :            :     }
    2488                 :            :   }
    2489                 :            : 
    2490         [ +  + ]:     154491 :   for (i = equalities.begin(); i != eq_end; ++i)
    2491                 :            :   {
    2492                 :      37953 :     ConstraintP eq = *i;
    2493                 :      37953 :     const ValueCollection& vc = eq->getValueCollection();
    2494 [ +  - ][ +  - ]:      37953 :     Assert(vc.hasEquality() && vc.getEquality()->hasLiteral());
         [ -  + ][ -  + ]
                 [ -  - ]
    2495                 :            : 
    2496 [ +  + ][ +  - ]:      37953 :     bool hasLB = vc.hasLowerBound() && vc.getLowerBound()->hasLiteral();
    2497 [ +  + ][ +  + ]:      37953 :     bool hasUB = vc.hasUpperBound() && vc.getUpperBound()->hasLiteral();
    2498                 :            : 
    2499         [ +  + ]:      37953 :     ConstraintP lb = hasLB ? vc.getLowerBound()
    2500                 :      34183 :                            : eq->getStrictlyWeakerLowerBound(true, false);
    2501         [ +  + ]:      37953 :     ConstraintP ub = hasUB ? vc.getUpperBound()
    2502                 :      37078 :                            : eq->getStrictlyWeakerUpperBound(true, false);
    2503                 :            : 
    2504 [ +  + ][ +  + ]:      37953 :     if (hasUB && hasLB && !eq->isSplit())
         [ +  - ][ +  + ]
    2505                 :            :     {
    2506                 :        550 :       out.push_back(eq->split());
    2507                 :            :     }
    2508         [ +  + ]:      37953 :     if (lb != NullConstraint)
    2509                 :            :     {
    2510                 :       5902 :       implies(out, eq, lb);
    2511                 :            :     }
    2512         [ +  + ]:      37953 :     if (ub != NullConstraint)
    2513                 :            :     {
    2514                 :      11843 :       implies(out, eq, ub);
    2515                 :            :     }
    2516                 :            :   }
    2517                 :     116538 : }
    2518                 :            : 
    2519                 :      28266 : void ConstraintDatabase::outputUnateEqualityLemmas(
    2520                 :            :     std::vector<TrustNode>& lemmas) const
    2521                 :            : {
    2522         [ +  + ]:     144804 :   for (ArithVar v = 0, N = d_varDatabases.size(); v < N; ++v)
    2523                 :            :   {
    2524                 :     116538 :     outputUnateEqualityLemmas(lemmas, v);
    2525                 :            :   }
    2526                 :      28266 : }
    2527                 :            : 
    2528                 :      28266 : void ConstraintDatabase::outputUnateInequalityLemmas(
    2529                 :            :     std::vector<TrustNode>& lemmas) const
    2530                 :            : {
    2531         [ +  + ]:     144804 :   for (ArithVar v = 0, N = d_varDatabases.size(); v < N; ++v)
    2532                 :            :   {
    2533                 :     116538 :     outputUnateInequalityLemmas(lemmas, v);
    2534                 :            :   }
    2535                 :      28266 : }
    2536                 :            : 
    2537                 :    7694054 : bool ConstraintDatabase::handleUnateProp(ConstraintP ant, ConstraintP cons)
    2538                 :            : {
    2539         [ +  + ]:    7694054 :   if (cons->negationHasProof())
    2540                 :            :   {
    2541         [ +  - ]:          4 :     Trace("arith::unate") << "handleUnate: " << ant << " implies " << cons
    2542                 :          2 :                           << endl;
    2543                 :          2 :     cons->impliedByUnate(nodeManager(), ant, true);
    2544                 :          2 :     d_raiseConflict.raiseConflict(cons, InferenceId::ARITH_CONF_UNATE_PROP);
    2545                 :          2 :     return true;
    2546                 :            :   }
    2547         [ +  + ]:    7694052 :   else if (!cons->isTrue())
    2548                 :            :   {
    2549                 :    3610328 :     ++d_statistics.d_unatePropagateImplications;
    2550         [ +  - ]:    7220656 :     Trace("arith::unate") << "handleUnate: " << ant << " implies " << cons
    2551                 :    3610328 :                           << endl;
    2552                 :    3610328 :     cons->impliedByUnate(nodeManager(), ant, false);
    2553                 :    3610328 :     cons->tryToPropagate();
    2554                 :    3610328 :     return false;
    2555                 :            :   }
    2556                 :            :   else
    2557                 :            :   {
    2558                 :    4083724 :     return false;
    2559                 :            :   }
    2560                 :            : }
    2561                 :            : 
    2562                 :    2236843 : void ConstraintDatabase::unatePropLowerBound(ConstraintP curr, ConstraintP prev)
    2563                 :            : {
    2564         [ +  - ]:    4473686 :   Trace("arith::unate") << "unatePropLowerBound " << curr << " " << prev
    2565                 :    2236843 :                         << endl;
    2566 [ -  + ][ -  + ]:    2236843 :   Assert(curr != prev);
                 [ -  - ]
    2567 [ -  + ][ -  + ]:    2236843 :   Assert(curr != NullConstraint);
                 [ -  - ]
    2568                 :    2236843 :   bool hasPrev = !(prev == NullConstraint);
    2569 [ +  + ][ +  - ]:    2236843 :   Assert(!hasPrev || curr->getValue() > prev->getValue());
         [ -  + ][ -  + ]
                 [ -  - ]
    2570                 :            : 
    2571                 :    2236843 :   ++d_statistics.d_unatePropagateCalls;
    2572                 :            : 
    2573                 :    2236843 :   const SortedConstraintMap& scm = curr->constraintSet();
    2574                 :    2236843 :   const SortedConstraintMapConstIterator scm_begin = scm.begin();
    2575                 :    2236843 :   SortedConstraintMapConstIterator scm_i = curr->d_variablePosition;
    2576                 :            : 
    2577                 :            :   // Ignore the first ValueCollection
    2578                 :            :   //  NOPE: (>= p c) then (= p c) NOPE
    2579                 :            :   //  NOPE: (>= p c) then (not (= p c)) NOPE
    2580                 :            : 
    2581         [ +  + ]:    8051739 :   while (scm_i != scm_begin)
    2582                 :            :   {
    2583                 :    6279478 :     --scm_i;  // move the iterator back
    2584                 :            : 
    2585                 :    6279478 :     const ValueCollection& vc = scm_i->second;
    2586                 :            : 
    2587                 :            :     // If it has the previous element, do nothing and stop!
    2588         [ +  + ]:    1791612 :     if (hasPrev && vc.hasConstraintOfType(prev->getType())
    2589 [ +  + ][ +  + ]:    8071090 :         && vc.getConstraintOfType(prev->getType()) == prev)
                 [ +  + ]
    2590                 :            :     {
    2591                 :     464580 :       break;
    2592                 :            :     }
    2593                 :            : 
    2594                 :            :     // Don't worry about implying the negation of upperbound.
    2595                 :            :     // These should all be handled by propagating the LowerBounds!
    2596         [ +  + ]:    5814898 :     if (vc.hasLowerBound())
    2597                 :            :     {
    2598                 :    2213832 :       ConstraintP lb = vc.getLowerBound();
    2599         [ -  + ]:    2213832 :       if (handleUnateProp(curr, lb))
    2600                 :            :       {
    2601                 :          2 :         return;
    2602                 :            :       }
    2603                 :            :     }
    2604         [ +  + ]:    5814898 :     if (vc.hasDisequality())
    2605                 :            :     {
    2606                 :     527414 :       ConstraintP dis = vc.getDisequality();
    2607         [ +  + ]:     527414 :       if (handleUnateProp(curr, dis))
    2608                 :            :       {
    2609                 :          2 :         return;
    2610                 :            :       }
    2611                 :            :     }
    2612                 :            :   }
    2613                 :            : }
    2614                 :            : 
    2615                 :    2015575 : void ConstraintDatabase::unatePropUpperBound(ConstraintP curr, ConstraintP prev)
    2616                 :            : {
    2617         [ +  - ]:    4031150 :   Trace("arith::unate") << "unatePropUpperBound " << curr << " " << prev
    2618                 :    2015575 :                         << endl;
    2619 [ -  + ][ -  + ]:    2015575 :   Assert(curr != prev);
                 [ -  - ]
    2620 [ -  + ][ -  + ]:    2015575 :   Assert(curr != NullConstraint);
                 [ -  - ]
    2621                 :    2015575 :   bool hasPrev = !(prev == NullConstraint);
    2622 [ +  + ][ +  - ]:    2015575 :   Assert(!hasPrev || curr->getValue() < prev->getValue());
         [ -  + ][ -  + ]
                 [ -  - ]
    2623                 :            : 
    2624                 :    2015575 :   ++d_statistics.d_unatePropagateCalls;
    2625                 :            : 
    2626                 :    2015575 :   const SortedConstraintMap& scm = curr->constraintSet();
    2627                 :    2015575 :   const SortedConstraintMapConstIterator scm_end = scm.end();
    2628                 :    2015575 :   SortedConstraintMapConstIterator scm_i = curr->d_variablePosition;
    2629                 :    2015575 :   ++scm_i;
    2630         [ +  + ]:    7989039 :   for (; scm_i != scm_end; ++scm_i)
    2631                 :            :   {
    2632                 :    6321791 :     const ValueCollection& vc = scm_i->second;
    2633                 :            : 
    2634                 :            :     // If it has the previous element, do nothing and stop!
    2635         [ +  + ]:    1156477 :     if (hasPrev && vc.hasConstraintOfType(prev->getType())
    2636 [ +  + ][ +  + ]:    7478268 :         && vc.getConstraintOfType(prev->getType()) == prev)
                 [ +  + ]
    2637                 :            :     {
    2638                 :     348327 :       break;
    2639                 :            :     }
    2640                 :            :     // Don't worry about implying the negation of upperbound.
    2641                 :            :     // These should all be handled by propagating the UpperBounds!
    2642         [ +  + ]:    5973464 :     if (vc.hasUpperBound())
    2643                 :            :     {
    2644                 :    2348557 :       ConstraintP ub = vc.getUpperBound();
    2645         [ -  + ]:    2348557 :       if (handleUnateProp(curr, ub))
    2646                 :            :       {
    2647                 :          0 :         return;
    2648                 :            :       }
    2649                 :            :     }
    2650         [ +  + ]:    5973464 :     if (vc.hasDisequality())
    2651                 :            :     {
    2652                 :     387872 :       ConstraintP dis = vc.getDisequality();
    2653         [ -  + ]:     387872 :       if (handleUnateProp(curr, dis))
    2654                 :            :       {
    2655                 :          0 :         return;
    2656                 :            :       }
    2657                 :            :     }
    2658                 :            :   }
    2659                 :            : }
    2660                 :            : 
    2661                 :    1787761 : void ConstraintDatabase::unatePropEquality(ConstraintP curr,
    2662                 :            :                                            ConstraintP prevLB,
    2663                 :            :                                            ConstraintP prevUB)
    2664                 :            : {
    2665         [ +  - ]:    3575522 :   Trace("arith::unate") << "unatePropEquality " << curr << " " << prevLB << " "
    2666                 :    1787761 :                         << prevUB << endl;
    2667 [ -  + ][ -  + ]:    1787761 :   Assert(curr != prevLB);
                 [ -  - ]
    2668 [ -  + ][ -  + ]:    1787761 :   Assert(curr != prevUB);
                 [ -  - ]
    2669 [ -  + ][ -  + ]:    1787761 :   Assert(curr != NullConstraint);
                 [ -  - ]
    2670                 :    1787761 :   bool hasPrevLB = !(prevLB == NullConstraint);
    2671                 :    1787761 :   bool hasPrevUB = !(prevUB == NullConstraint);
    2672 [ +  + ][ +  - ]:    1787761 :   Assert(!hasPrevLB || curr->getValue() >= prevLB->getValue());
         [ -  + ][ -  + ]
                 [ -  - ]
    2673 [ +  + ][ +  - ]:    1787761 :   Assert(!hasPrevUB || curr->getValue() <= prevUB->getValue());
         [ -  + ][ -  + ]
                 [ -  - ]
    2674                 :            : 
    2675                 :    1787761 :   ++d_statistics.d_unatePropagateCalls;
    2676                 :            : 
    2677                 :    1787761 :   const SortedConstraintMap& scm = curr->constraintSet();
    2678                 :    1787761 :   SortedConstraintMapConstIterator scm_curr = curr->d_variablePosition;
    2679                 :            :   SortedConstraintMapConstIterator scm_last =
    2680         [ +  + ]:    1787761 :       hasPrevUB ? prevUB->d_variablePosition : scm.end();
    2681                 :    1787761 :   SortedConstraintMapConstIterator scm_i;
    2682         [ +  + ]:    1787761 :   if (hasPrevLB)
    2683                 :            :   {
    2684                 :     219811 :     scm_i = prevLB->d_variablePosition;
    2685         [ +  + ]:     219811 :     if (scm_i != scm_curr)
    2686                 :            :     {  // If this does not move this past scm_curr, move it one forward
    2687                 :      55887 :       ++scm_i;
    2688                 :            :     }
    2689                 :            :   }
    2690                 :            :   else
    2691                 :            :   {
    2692                 :    1567950 :     scm_i = scm.begin();
    2693                 :            :   }
    2694                 :            : 
    2695         [ +  + ]:    2872864 :   for (; scm_i != scm_curr; ++scm_i)
    2696                 :            :   {
    2697                 :            :     // between the previous LB and the curr
    2698                 :    1085103 :     const ValueCollection& vc = scm_i->second;
    2699                 :            : 
    2700                 :            :     // Don't worry about implying the negation of upperbound.
    2701                 :            :     // These should all be handled by propagating the LowerBounds!
    2702         [ +  + ]:    1085103 :     if (vc.hasLowerBound())
    2703                 :            :     {
    2704                 :     332139 :       ConstraintP lb = vc.getLowerBound();
    2705         [ -  + ]:     332139 :       if (handleUnateProp(curr, lb))
    2706                 :            :       {
    2707                 :          0 :         return;
    2708                 :            :       }
    2709                 :            :     }
    2710         [ +  + ]:    1085103 :     if (vc.hasDisequality())
    2711                 :            :     {
    2712                 :     325185 :       ConstraintP dis = vc.getDisequality();
    2713         [ -  + ]:     325185 :       if (handleUnateProp(curr, dis))
    2714                 :            :       {
    2715                 :          0 :         return;
    2716                 :            :       }
    2717                 :            :     }
    2718                 :            :   }
    2719 [ -  + ][ -  + ]:    1787761 :   Assert(scm_i == scm_curr);
                 [ -  - ]
    2720 [ +  + ][ +  + ]:    1787761 :   if (!hasPrevUB || scm_i != scm_last)
                 [ +  + ]
    2721                 :            :   {
    2722                 :    1738512 :     ++scm_i;
    2723                 :            :   }  // hasPrevUB implies scm_i != scm_last
    2724                 :            : 
    2725         [ +  + ]:    4420882 :   for (; scm_i != scm_last; ++scm_i)
    2726                 :            :   {
    2727                 :            :     // between the curr and the previous UB imply the upperbounds and
    2728                 :            :     // disequalities.
    2729                 :    2633121 :     const ValueCollection& vc = scm_i->second;
    2730                 :            : 
    2731                 :            :     // Don't worry about implying the negation of upperbound.
    2732                 :            :     // These should all be handled by propagating the UpperBounds!
    2733         [ +  + ]:    2633121 :     if (vc.hasUpperBound())
    2734                 :            :     {
    2735                 :     901794 :       ConstraintP ub = vc.getUpperBound();
    2736         [ -  + ]:     901794 :       if (handleUnateProp(curr, ub))
    2737                 :            :       {
    2738                 :          0 :         return;
    2739                 :            :       }
    2740                 :            :     }
    2741         [ +  + ]:    2633121 :     if (vc.hasDisequality())
    2742                 :            :     {
    2743                 :     657261 :       ConstraintP dis = vc.getDisequality();
    2744         [ -  + ]:     657261 :       if (handleUnateProp(curr, dis))
    2745                 :            :       {
    2746                 :          0 :         return;
    2747                 :            :       }
    2748                 :            :     }
    2749                 :            :   }
    2750                 :            : }
    2751                 :            : 
    2752                 :    2490847 : std::pair<int, int> Constraint::unateFarkasSigns(ConstraintCP ca,
    2753                 :            :                                                  ConstraintCP cb)
    2754                 :            : {
    2755                 :    2490847 :   ConstraintType a = ca->getType();
    2756                 :    2490847 :   ConstraintType b = cb->getType();
    2757                 :            : 
    2758 [ -  + ][ -  + ]:    2490847 :   Assert(a != Disequality);
                 [ -  - ]
    2759 [ -  + ][ -  + ]:    2490847 :   Assert(b != Disequality);
                 [ -  - ]
    2760                 :            : 
    2761 [ +  + ][ +  + ]:    2490847 :   int a_sgn = (a == LowerBound) ? -1 : ((a == UpperBound) ? 1 : 0);
    2762 [ +  + ][ +  + ]:    2490847 :   int b_sgn = (b == LowerBound) ? -1 : ((b == UpperBound) ? 1 : 0);
    2763                 :            : 
    2764 [ +  + ][ +  + ]:    2490847 :   if (a_sgn == 0 && b_sgn == 0)
    2765                 :            :   {
    2766 [ -  + ][ -  + ]:     555325 :     Assert(a == Equality);
                 [ -  - ]
    2767 [ -  + ][ -  + ]:     555325 :     Assert(b == Equality);
                 [ -  - ]
    2768 [ -  + ][ -  + ]:     555325 :     Assert(ca->getValue() != cb->getValue());
                 [ -  - ]
    2769         [ +  + ]:     555325 :     if (ca->getValue() < cb->getValue())
    2770                 :            :     {
    2771                 :     174876 :       a_sgn = 1;
    2772                 :     174876 :       b_sgn = -1;
    2773                 :            :     }
    2774                 :            :     else
    2775                 :            :     {
    2776                 :     380449 :       a_sgn = -1;
    2777                 :     380449 :       b_sgn = 1;
    2778                 :            :     }
    2779                 :            :   }
    2780         [ +  + ]:    1935522 :   else if (a_sgn == 0)
    2781                 :            :   {
    2782 [ -  + ][ -  + ]:     372742 :     Assert(b_sgn != 0);
                 [ -  - ]
    2783 [ -  + ][ -  + ]:     372742 :     Assert(a == Equality);
                 [ -  - ]
    2784                 :     372742 :     a_sgn = -b_sgn;
    2785                 :            :   }
    2786         [ +  + ]:    1562780 :   else if (b_sgn == 0)
    2787                 :            :   {
    2788 [ -  + ][ -  + ]:     599589 :     Assert(a_sgn != 0);
                 [ -  - ]
    2789 [ -  + ][ -  + ]:     599589 :     Assert(b == Equality);
                 [ -  - ]
    2790                 :     599589 :     b_sgn = -a_sgn;
    2791                 :            :   }
    2792 [ -  + ][ -  + ]:    2490847 :   Assert(a_sgn != 0);
                 [ -  - ]
    2793 [ -  + ][ -  + ]:    2490847 :   Assert(b_sgn != 0);
                 [ -  - ]
    2794                 :            : 
    2795         [ +  - ]:    4981694 :   Trace("arith::unateFarkasSigns")
    2796                 :          0 :       << "Constraint::unateFarkasSigns(" << a << ", " << b << ") -> "
    2797                 :    2490847 :       << "(" << a_sgn << ", " << b_sgn << ")" << endl;
    2798                 :    4981694 :   return make_pair(a_sgn, b_sgn);
    2799                 :            : }
    2800                 :            : 
    2801                 :            : }  // namespace arith::linear
    2802                 :            : }  // namespace theory
    2803                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14