LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/preprocessing/passes - non_clausal_simp.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 201 218 92.2 %
Date: 2024-08-29 11:49:29 Functions: 6 6 100.0 %
Branches: 134 255 52.5 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Aina Niemetz, Andrew Reynolds, Gereon Kremer
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2024 by the authors listed in the file AUTHORS
       8                 :            :  * in the top-level source directory and their institutional affiliations.
       9                 :            :  * All rights reserved.  See the file COPYING in the top-level source
      10                 :            :  * directory for licensing information.
      11                 :            :  * ****************************************************************************
      12                 :            :  *
      13                 :            :  * Non-clausal simplification preprocessing pass.
      14                 :            :  *
      15                 :            :  * Run the nonclausal solver and try to solve all assigned theory literals.
      16                 :            :  */
      17                 :            : 
      18                 :            : #include "preprocessing/passes/non_clausal_simp.h"
      19                 :            : 
      20                 :            : #include <vector>
      21                 :            : 
      22                 :            : #include "context/cdo.h"
      23                 :            : #include "options/smt_options.h"
      24                 :            : #include "preprocessing/assertion_pipeline.h"
      25                 :            : #include "preprocessing/preprocessing_pass_context.h"
      26                 :            : #include "smt/preprocess_proof_generator.h"
      27                 :            : #include "theory/booleans/circuit_propagator.h"
      28                 :            : #include "theory/theory.h"
      29                 :            : #include "theory/theory_engine.h"
      30                 :            : #include "theory/theory_model.h"
      31                 :            : #include "theory/trust_substitutions.h"
      32                 :            : 
      33                 :            : using namespace cvc5::internal;
      34                 :            : using namespace cvc5::internal::theory;
      35                 :            : 
      36                 :            : namespace cvc5::internal {
      37                 :            : namespace preprocessing {
      38                 :            : namespace passes {
      39                 :            : 
      40                 :            : /* -------------------------------------------------------------------------- */
      41                 :            : 
      42                 :      48144 : NonClausalSimp::Statistics::Statistics(StatisticsRegistry& reg)
      43                 :            :     : d_numConstantProps(reg.registerInt(
      44                 :      48144 :         "preprocessing::passes::NonClausalSimp::NumConstantProps"))
      45                 :            : {
      46                 :      48144 : }
      47                 :            : 
      48                 :            : 
      49                 :            : /* -------------------------------------------------------------------------- */
      50                 :            : 
      51                 :      48144 : NonClausalSimp::NonClausalSimp(PreprocessingPassContext* preprocContext)
      52                 :            :     : PreprocessingPass(preprocContext, "non-clausal-simp"),
      53                 :            :       d_statistics(statisticsRegistry()),
      54                 :      96288 :       d_llpg(options().smt.produceProofs ? new smt::PreprocessProofGenerator(
      55                 :      34482 :                  d_env, userContext(), "NonClausalSimp::llpg")
      56                 :            :                                          : nullptr),
      57                 :      82626 :       d_tsubsList(userContext())
      58                 :            : {
      59                 :      48144 : }
      60                 :            : 
      61                 :      39223 : PreprocessingPassResult NonClausalSimp::applyInternal(
      62                 :            :     AssertionPipeline* assertionsToPreprocess)
      63                 :            : {
      64                 :      39223 :   d_preprocContext->spendResource(Resource::PreprocessStep);
      65                 :            : 
      66         [ -  + ]:      39223 :   if (TraceIsOn("non-clausal-simplify"))
      67                 :            :   {
      68         [ -  - ]:          0 :     for (size_t i = 0, size = assertionsToPreprocess->size(); i < size; ++i)
      69                 :            :     {
      70         [ -  - ]:          0 :       Trace("non-clausal-simplify")
      71                 :          0 :           << "Assertion #" << i << " : " << (*assertionsToPreprocess)[i]
      72                 :          0 :           << std::endl;
      73                 :            :     }
      74                 :            :   }
      75                 :            : 
      76                 :            :   theory::booleans::CircuitPropagator* propagator =
      77                 :      39223 :       d_preprocContext->getCircuitPropagator();
      78                 :      39223 :   propagator->initialize();
      79                 :            : 
      80                 :            :   // Assert all the assertions to the propagator
      81         [ +  - ]:      39223 :   Trace("non-clausal-simplify") << "asserting to propagator" << std::endl;
      82         [ +  + ]:     482380 :   for (size_t i = 0, size = assertionsToPreprocess->size(); i < size; ++i)
      83                 :            :   {
      84                 :     443157 :     Assert(rewrite((*assertionsToPreprocess)[i])
      85                 :          0 :            == (*assertionsToPreprocess)[i]) << (*assertionsToPreprocess)[i];
      86                 :            :     // Don't reprocess substitutions
      87         [ +  + ]:     443157 :     if (assertionsToPreprocess->isSubstsIndex(i))
      88                 :            :     {
      89                 :         30 :       continue;
      90                 :            :     }
      91         [ +  - ]:     886254 :     Trace("non-clausal-simplify")
      92                 :     443127 :         << "asserting " << (*assertionsToPreprocess)[i] << std::endl;
      93         [ +  - ]:     886254 :     Trace("cores") << "propagator->assertTrue: " << (*assertionsToPreprocess)[i]
      94                 :     443127 :                    << std::endl;
      95                 :     443127 :     propagator->assertTrue((*assertionsToPreprocess)[i]);
      96                 :            :   }
      97                 :            : 
      98         [ +  - ]:      39223 :   Trace("non-clausal-simplify") << "propagating" << std::endl;
      99                 :      78446 :   TrustNode conf = propagator->propagate();
     100         [ +  + ]:      39223 :   if (!conf.isNull())
     101                 :            :   {
     102                 :            :     // If in conflict, just return false
     103         [ +  - ]:       4932 :     Trace("non-clausal-simplify")
     104                 :       2466 :         << "conflict in non-clausal propagation" << std::endl;
     105                 :       2466 :     assertionsToPreprocess->pushBackTrusted(conf);
     106                 :       2466 :     return PreprocessingPassResult::CONFLICT;
     107                 :            :   }
     108                 :            : 
     109         [ +  - ]:      73514 :   Trace("non-clausal-simplify")
     110                 :      36757 :       << "Iterate through " << propagator->getLearnedLiterals().size()
     111                 :      36757 :       << " learned literals." << std::endl;
     112                 :            :   // No conflict, go through the literals and solve them
     113                 :      36757 :   NodeManager* nm = nodeManager();
     114                 :      36757 :   context::Context* u = userContext();
     115                 :      36757 :   Rewriter* rw = d_env.getRewriter();
     116                 :      36757 :   TrustSubstitutionMap& ttls = d_preprocContext->getTopLevelSubstitutions();
     117                 :      36757 :   CVC5_UNUSED SubstitutionMap& top_level_substs = ttls.get();
     118                 :            :   // constant propagations
     119                 :            :   std::shared_ptr<TrustSubstitutionMap> constantPropagations =
     120                 :            :       std::make_shared<TrustSubstitutionMap>(
     121                 :      73514 :           d_env, u, "NonClausalSimp::cprop", TrustId::PREPROCESS_LEMMA);
     122                 :      36757 :   SubstitutionMap& cps = constantPropagations->get();
     123                 :            :   // new substitutions
     124                 :            :   std::shared_ptr<TrustSubstitutionMap> newSubstitutions =
     125                 :            :       std::make_shared<TrustSubstitutionMap>(
     126                 :      73514 :           d_env, u, "NonClausalSimp::newSubs", TrustId::PREPROCESS_LEMMA);
     127                 :      36757 :   SubstitutionMap& nss = newSubstitutions->get();
     128                 :            : 
     129                 :      36757 :   size_t j = 0;
     130                 :      36757 :   std::vector<TrustNode>& learned_literals = propagator->getLearnedLiterals();
     131                 :            :   // if proofs are enabled, we will need to track the proofs of learned literals
     132         [ +  + ]:      36757 :   if (isProofEnabled())
     133                 :            :   {
     134                 :      15307 :     d_tsubsList.push_back(constantPropagations);
     135                 :      15307 :     d_tsubsList.push_back(newSubstitutions);
     136         [ +  + ]:     194514 :     for (const TrustNode& tll : learned_literals)
     137                 :            :     {
     138                 :     179207 :       d_llpg->notifyNewTrustedAssert(tll);
     139                 :            :     }
     140                 :            :   }
     141         [ +  + ]:     301606 :   for (size_t i = 0, size = learned_literals.size(); i < size; ++i)
     142                 :            :   {
     143                 :            :     // Simplify the literal we learned wrt previous substitutions
     144                 :     265778 :     Node learnedLiteral = learned_literals[i].getNode();
     145         [ +  - ]:     531554 :     Trace("non-clausal-simplify")
     146                 :     265777 :         << "Process learnedLiteral : " << learnedLiteral;
     147 [ -  + ][ -  + ]:     265777 :     Assert(rewrite(learnedLiteral) == learnedLiteral);
                 [ -  - ]
     148                 :     531554 :     Assert(top_level_substs.apply(learnedLiteral) == learnedLiteral)
     149 [ -  + ][ -  - ]:     265777 :         << learnedLiteral << " after subs is "
     150                 :     265777 :         << top_level_substs.apply(learnedLiteral);
     151                 :            :     // process the learned literal with substitutions and const propagations
     152                 :     531554 :     learnedLiteral = processLearnedLit(
     153                 :     265777 :         learnedLiteral, newSubstitutions.get(), constantPropagations.get());
     154         [ +  - ]:     531554 :     Trace("non-clausal-simplify")
     155                 :          0 :         << "Process learnedLiteral, after constProp : " << learnedLiteral
     156                 :     265777 :         << std::endl;
     157                 :            :     // It might just simplify to a constant
     158         [ +  + ]:     265777 :     if (learnedLiteral.isConst())
     159                 :            :     {
     160         [ +  + ]:       2069 :       if (learnedLiteral.getConst<bool>())
     161                 :            :       {
     162                 :            :         // If the learned literal simplifies to true, it's redundant
     163                 :       1142 :         continue;
     164                 :            :       }
     165                 :            :       else
     166                 :            :       {
     167                 :            :         // If the learned literal simplifies to false, we're in conflict
     168         [ +  - ]:       1854 :         Trace("non-clausal-simplify")
     169 [ -  + ][ -  - ]:        927 :             << "conflict with " << learned_literals[i].getNode() << std::endl;
     170                 :        927 :         Node n = nm->mkConst<bool>(false);
     171         [ +  + ]:        927 :         assertionsToPreprocess->push_back(n, false, d_llpg.get());
     172                 :        927 :         return PreprocessingPassResult::CONFLICT;
     173                 :            :       }
     174                 :            :     }
     175                 :            : 
     176                 :            :     // Solve it with the corresponding theory, possibly adding new
     177                 :            :     // substitutions to newSubstitutions
     178         [ +  - ]:     263708 :     Trace("non-clausal-simplify") << "solving " << learnedLiteral << std::endl;
     179                 :            : 
     180                 :            :     TrustNode tlearnedLiteral =
     181         [ +  + ]:     263709 :         TrustNode::mkTrustLemma(learnedLiteral, d_llpg.get());
     182                 :            :     Theory::PPAssertStatus solveStatus =
     183                 :     527417 :         d_preprocContext->getTheoryEngine()->solve(tlearnedLiteral,
     184                 :     263708 :                                                    *newSubstitutions.get());
     185                 :            : 
     186    [ +  - ][ + ]:     263707 :     switch (solveStatus)
     187                 :            :     {
     188                 :      53934 :       case Theory::PP_ASSERT_STATUS_SOLVED:
     189                 :            :       {
     190                 :            :         // The literal should rewrite to true
     191         [ +  - ]:     107868 :         Trace("non-clausal-simplify")
     192                 :      53934 :             << "solved " << learnedLiteral << std::endl;
     193 [ -  + ][ -  + ]:      53934 :         Assert(rewrite(nss.apply(learnedLiteral)).isConst());
                 [ -  - ]
     194                 :            :         // else fall through
     195                 :     263707 :         break;
     196                 :            :       }
     197                 :          0 :       case Theory::PP_ASSERT_STATUS_CONFLICT:
     198                 :            :       {
     199                 :            :         // If in conflict, we return false
     200         [ -  - ]:          0 :         Trace("non-clausal-simplify")
     201                 :          0 :             << "conflict while solving " << learnedLiteral << std::endl;
     202                 :          0 :         Node n = nm->mkConst<bool>(false);
     203                 :          0 :         assertionsToPreprocess->push_back(n);
     204                 :          0 :         return PreprocessingPassResult::CONFLICT;
     205                 :            :       }
     206                 :     209773 :       default:
     207                 :     419546 :         TNode t;
     208                 :     419546 :         TNode c;
     209                 :     629319 :         if (learnedLiteral.getKind() == Kind::EQUAL
     210                 :     209773 :             && (learnedLiteral[0].isConst() || learnedLiteral[1].isConst()))
     211                 :            :         {
     212                 :            :           // constant propagation
     213         [ +  + ]:      15354 :           if (learnedLiteral[0].isConst())
     214                 :            :           {
     215                 :       1587 :             t = learnedLiteral[1];
     216                 :       1587 :             c = learnedLiteral[0];
     217                 :            :           }
     218                 :            :           else
     219                 :            :           {
     220                 :      13767 :             t = learnedLiteral[0];
     221                 :      13767 :             c = learnedLiteral[1];
     222                 :            :           }
     223                 :            :         }
     224         [ -  + ]:     194419 :         else if (options().smt.simplificationBoolConstProp)
     225                 :            :         {
     226                 :            :           // From non-equalities, learn the Boolean equality. Notice that
     227                 :            :           // the equality case above is strictly more powerful that this, since
     228                 :            :           // e.g. (= t c) * { t -> c } also simplifies to true.
     229                 :          0 :           bool pol = learnedLiteral.getKind() != Kind::NOT;
     230                 :          0 :           c = nm->mkConst(pol);
     231         [ -  - ]:          0 :           t = pol ? learnedLiteral : learnedLiteral[0];
     232                 :            :         }
     233         [ +  + ]:     209773 :         if (!t.isNull())
     234                 :            :         {
     235 [ -  + ][ -  + ]:      15354 :           Assert(!t.isConst());
                 [ -  - ]
     236 [ -  + ][ -  + ]:      15354 :           Assert(rewrite(cps.apply(t)) == t);
                 [ -  - ]
     237 [ -  + ][ -  + ]:      15354 :           Assert(top_level_substs.apply(t) == t);
                 [ -  - ]
     238 [ -  + ][ -  + ]:      15354 :           Assert(nss.apply(t) == t);
                 [ -  - ]
     239                 :            :           // also add to learned literal
     240                 :      15354 :           ProofGenerator* cpg = constantPropagations->addSubstitutionSolved(
     241                 :            :               t, c, tlearnedLiteral);
     242                 :            :           // We need to justify (= t c) as a literal, since it is reasserted
     243                 :            :           // to the assertion pipeline below. We do this with the proof
     244                 :            :           // generator returned by the above call.
     245         [ +  + ]:      15354 :           if (isProofEnabled())
     246                 :            :           {
     247                 :       9679 :             d_llpg->notifyNewAssert(t.eqNode(c), cpg);
     248                 :            :           }
     249                 :            :         }
     250                 :            :         else
     251                 :            :         {
     252                 :            :           // Keep the learned literal
     253                 :     194419 :           learned_literals[j++] = learned_literals[i];
     254                 :            :         }
     255                 :            :         // Its a literal that could not be processed as a substitution or
     256                 :            :         // conflict. In this case, we notify the context of the learned
     257                 :            :         // literal, which will process it with the learned literal manager.
     258                 :     209773 :         d_preprocContext->notifyLearnedLiteral(learnedLiteral);
     259                 :     209773 :         break;
     260                 :            :     }
     261                 :            :   }
     262                 :            : 
     263                 :            : #ifdef CVC5_ASSERTIONS
     264                 :            :   // NOTE: When debugging this code, consider moving this check inside of the
     265                 :            :   // loop over propagator->getLearnedLiterals(). This check has been moved
     266                 :            :   // outside because it is costly for certain inputs (see bug 508).
     267                 :            :   //
     268                 :            :   // Check data structure invariants:
     269                 :            :   // 1. for each lhs of top_level_substs, does not appear anywhere in rhs of
     270                 :            :   // top_level_substs or anywhere in constantPropagations
     271                 :            :   // 2. each lhs of constantPropagations rewrites to itself
     272                 :            :   // 3. if l -> r is a constant propagation and l is a subterm of l' with l' ->
     273                 :            :   // r' another constant propagation, then l'[l/r] -> r' should be a
     274                 :            :   //    constant propagation too
     275                 :            :   // 4. each lhs of constantPropagations is different from each rhs
     276         [ +  + ]:      87658 :   for (SubstitutionMap::iterator pos = nss.begin(); pos != nss.end(); ++pos)
     277                 :            :   {
     278 [ -  + ][ -  + ]:      51829 :     Assert((*pos).first.isVar());
                 [ -  - ]
     279 [ -  + ][ -  + ]:      51829 :     Assert(top_level_substs.apply((*pos).first) == (*pos).first);
                 [ -  - ]
     280 [ -  + ][ -  + ]:      51829 :     Assert(top_level_substs.apply((*pos).second) == (*pos).second);
                 [ -  - ]
     281                 :      51829 :     Node app = nss.apply((*pos).second);
     282 [ -  + ][ -  + ]:      51829 :     Assert(nss.apply(app) == app);
                 [ -  - ]
     283                 :            :   }
     284         [ +  + ]:      51138 :   for (SubstitutionMap::iterator pos = cps.begin(); pos != cps.end(); ++pos)
     285                 :            :   {
     286 [ -  + ][ -  + ]:      15309 :     Assert((*pos).second.isConst());
                 [ -  - ]
     287 [ -  + ][ -  + ]:      15309 :     Assert(rewrite((*pos).first) == (*pos).first);
                 [ -  - ]
     288 [ -  + ][ -  + ]:      15309 :     Assert(cps.apply((*pos).second) == (*pos).second);
                 [ -  - ]
     289                 :            :   }
     290                 :            : #endif /* CVC5_ASSERTIONS */
     291                 :            : 
     292                 :            :   // Resize the learnt
     293         [ +  - ]:      71658 :   Trace("non-clausal-simplify")
     294                 :      35829 :       << "Resize non-clausal learned literals to " << j << std::endl;
     295                 :      35829 :   learned_literals.resize(j);
     296                 :            : 
     297                 :      71658 :   std::unordered_set<TNode> s;
     298         [ +  + ]:     452945 :   for (size_t i = 0, size = assertionsToPreprocess->size(); i < size; ++i)
     299                 :            :   {
     300                 :     417391 :     Node assertion = (*assertionsToPreprocess)[i];
     301         [ +  - ]:     417391 :     Trace("non-clausal-simplify") << "assertion = " << assertion << std::endl;
     302                 :     417391 :     TrustNode assertionNew = newSubstitutions->applyTrusted(assertion, rw);
     303         [ +  + ]:     417391 :     if (!assertionNew.isNull())
     304                 :            :     {
     305         [ +  - ]:     239142 :       Trace("non-clausal-simplify")
     306 [ -  + ][ -  - ]:     119571 :           << "assertionNew = " << assertionNew.getNode() << std::endl;
     307                 :     119571 :       assertionsToPreprocess->replaceTrusted(i, assertionNew);
     308                 :     119571 :       assertion = assertionNew.getNode();
     309 [ -  + ][ -  + ]:     119571 :       Assert(rewrite(assertion) == assertion);
                 [ -  - ]
     310                 :            :     }
     311                 :            :     for (;;)
     312                 :            :     {
     313                 :     422768 :       assertionNew = constantPropagations->applyTrusted(assertion, rw);
     314         [ +  + ]:     422768 :       if (assertionNew.isNull())
     315                 :            :       {
     316                 :     417391 :         break;
     317                 :            :       }
     318 [ -  + ][ -  + ]:       5377 :       Assert(assertionNew.getNode() != assertion);
                 [ -  - ]
     319                 :       5377 :       assertionsToPreprocess->replaceTrusted(i, assertionNew);
     320                 :       5377 :       assertion = assertionNew.getNode();
     321                 :       5377 :       d_statistics.d_numConstantProps += 1;
     322         [ +  - ]:      10754 :       Trace("non-clausal-simplify")
     323                 :       5377 :           << "assertionNew = " << assertion << std::endl;
     324                 :            :     }
     325                 :     417391 :     s.insert(assertion);
     326         [ +  - ]:     834782 :     Trace("non-clausal-simplify")
     327                 :     417391 :         << "non-clausal preprocessed: " << assertion << std::endl;
     328         [ +  + ]:     417391 :     if (assertionsToPreprocess->isInConflict())
     329                 :            :     {
     330                 :        275 :       return PreprocessingPassResult::CONFLICT;
     331                 :            :     }
     332                 :            :   }
     333                 :            : 
     334                 :            :   // If necessary, add as assertions if needed (when incremental). This is
     335                 :            :   // necessary because certain variables cannot truly be eliminated when
     336                 :            :   // we are in incremental mode. For example, say our first call to check-sat
     337                 :            :   // is a formula F containing variable x. On the second call to check-sat,
     338                 :            :   // say we solve a top-level assertion (= x t). Since the solver already has
     339                 :            :   // constraints involving x, we must still keep (= x t) as an assertion.
     340                 :            :   // However, notice that we do not retract the substitution { x -> t }. This
     341                 :            :   // means that all *subsequent* assertions after (= x t) will replace x by t.
     342         [ +  + ]:      35554 :   if (assertionsToPreprocess->storeSubstsInAsserts())
     343                 :            :   {
     344         [ +  + ]:       7562 :     for (const std::pair<const Node, const Node>& pos: nss)
     345                 :            :     {
     346                 :       7398 :       Node lhs = pos.first;
     347                 :            :       // If using incremental, we must check whether this variable has occurred
     348                 :            :       // before now. If it has, we must add as an assertion.
     349         [ +  + ]:       3699 :       if (d_preprocContext->getSymsInAssertions().contains(lhs))
     350                 :            :       {
     351                 :            :         // if it has, the substitution becomes an assertion
     352                 :       2306 :         TrustNode trhs = newSubstitutions->applyTrusted(lhs, rw);
     353 [ -  + ][ -  + ]:       2306 :         Assert(!trhs.isNull());
                 [ -  - ]
     354         [ +  - ]:       4612 :         Trace("non-clausal-simplify")
     355                 :          0 :             << "substitute: will notify SAT layer of substitution: "
     356 [ -  + ][ -  - ]:       2306 :             << trhs.getProven() << std::endl;
     357                 :            :         // note that trhs.getProven() may not be in rewritten form (e.g. the
     358                 :            :         // rewriter may swap order). This is handled internally within
     359                 :            :         // addSubstitutionNode.
     360                 :       2306 :         assertionsToPreprocess->addSubstitutionNode(trhs.getProven(),
     361                 :            :                                                     trhs.getGenerator());
     362                 :            :       }
     363                 :            :     }
     364                 :            :   }
     365                 :            : 
     366                 :            :   // Learned literals to conjoin. If proofs are enabled, all these are
     367                 :            :   // justified by d_llpg.
     368                 :      35554 :   std::vector<Node> learnedLitsToConjoin;
     369                 :            : 
     370         [ +  + ]:     226565 :   for (size_t i = 0; i < learned_literals.size(); ++i)
     371                 :            :   {
     372                 :     191011 :     Node learned = learned_literals[i].getNode();
     373 [ -  + ][ -  + ]:     191011 :     Assert(top_level_substs.apply(learned) == learned);
                 [ -  - ]
     374                 :            :     // process learned literal
     375                 :     382022 :     learned = processLearnedLit(
     376                 :     191011 :         learned, newSubstitutions.get(), constantPropagations.get());
     377         [ +  + ]:     191011 :     if (s.find(learned) != s.end())
     378                 :            :     {
     379                 :     109633 :       continue;
     380                 :            :     }
     381                 :      81378 :     s.insert(learned);
     382                 :      81378 :     learnedLitsToConjoin.push_back(learned);
     383         [ +  - ]:     162756 :     Trace("non-clausal-simplify")
     384                 :      81378 :         << "non-clausal learned : " << learned << std::endl;
     385                 :            :   }
     386                 :      35554 :   learned_literals.clear();
     387                 :            : 
     388         [ +  + ]:      50785 :   for (SubstitutionMap::iterator pos = cps.begin(); pos != cps.end(); ++pos)
     389                 :            :   {
     390                 :      15231 :     Node cProp = (*pos).first.eqNode((*pos).second);
     391 [ -  + ][ -  + ]:      15231 :     Assert(top_level_substs.apply(cProp) == cProp);
                 [ -  - ]
     392                 :            :     // process learned literal (substitutions only)
     393                 :      15231 :     cProp = processLearnedLit(cProp, newSubstitutions.get(), nullptr);
     394         [ +  + ]:      15231 :     if (s.find(cProp) != s.end())
     395                 :            :     {
     396                 :       9554 :       continue;
     397                 :            :     }
     398                 :       5677 :     s.insert(cProp);
     399                 :       5677 :     learnedLitsToConjoin.push_back(cProp);
     400         [ +  - ]:      11354 :     Trace("non-clausal-simplify")
     401                 :       5677 :         << "non-clausal constant propagation : " << cProp << std::endl;
     402                 :            :   }
     403                 :            : 
     404                 :            :   // Add new substitutions to topLevelSubstitutions
     405                 :            :   // Note that we don't have to keep rhs's in full solved form
     406                 :            :   // because SubstitutionMap::apply does a fixed-point iteration when
     407                 :            :   // substituting
     408                 :      35554 :   d_preprocContext->addSubstitutions(*newSubstitutions.get());
     409                 :            : 
     410         [ +  + ]:      35554 :   if (!learnedLitsToConjoin.empty())
     411                 :            :   {
     412         [ +  - ]:       9566 :     Trace("non-clausal-simplify")
     413                 :          0 :         << "non-clausal simplification, reassert: " << learnedLitsToConjoin
     414                 :       4783 :         << std::endl;
     415         [ +  + ]:      91838 :     for (const Node& lit : learnedLitsToConjoin)
     416                 :            :     {
     417         [ +  + ]:      87055 :       assertionsToPreprocess->push_back(lit, false, d_llpg.get());
     418                 :            :     }
     419                 :            :   }
     420                 :            : 
     421                 :            :   // Note that typically ttls.apply(assert)==assert here.
     422                 :            :   // However, this invariant is invalidated for cases where we use explicit
     423                 :            :   // equality assertions for variables solved in incremental mode that already
     424                 :            :   // exist in assertions, as described above.
     425                 :            : 
     426                 :      35554 :   return PreprocessingPassResult::NO_CONFLICT;
     427                 :            : }
     428                 :            : 
     429                 :     170807 : bool NonClausalSimp::isProofEnabled() const
     430                 :            : {
     431                 :     170807 :   return options().smt.produceProofs;
     432                 :            : }
     433                 :            : 
     434                 :     472019 : Node NonClausalSimp::processLearnedLit(Node lit,
     435                 :            :                                        theory::TrustSubstitutionMap* subs,
     436                 :            :                                        theory::TrustSubstitutionMap* cp)
     437                 :            : {
     438                 :     472019 :   Rewriter* rw = d_env.getRewriter();
     439                 :     944038 :   TrustNode tlit;
     440         [ +  - ]:     472019 :   if (subs != nullptr)
     441                 :            :   {
     442                 :     472019 :     tlit = subs->applyTrusted(lit, rw);
     443         [ +  + ]:     472019 :     if (!tlit.isNull())
     444                 :            :     {
     445                 :     118146 :       lit = processRewrittenLearnedLit(tlit);
     446                 :            :     }
     447         [ +  - ]:     944038 :     Trace("non-clausal-simplify")
     448                 :     472019 :         << "Process learnedLiteral, after newSubs : " << lit << std::endl;
     449                 :            :   }
     450                 :            :   // apply to fixed point
     451         [ +  + ]:     472019 :   if (cp != nullptr)
     452                 :            :   {
     453                 :            :     for (;;)
     454                 :            :     {
     455                 :     457338 :       tlit = cp->applyTrusted(lit, rw);
     456         [ +  + ]:     457338 :       if (tlit.isNull())
     457                 :            :       {
     458                 :     456788 :         break;
     459                 :            :       }
     460 [ -  + ][ -  + ]:        550 :       Assert(lit != tlit.getNode());
                 [ -  - ]
     461                 :        550 :       lit = processRewrittenLearnedLit(tlit);
     462                 :        550 :       d_statistics.d_numConstantProps += 1;
     463                 :            :     }
     464                 :            :   }
     465                 :     944038 :   return lit;
     466                 :            : }
     467                 :            : 
     468                 :     118696 : Node NonClausalSimp::processRewrittenLearnedLit(TrustNode trn)
     469                 :            : {
     470         [ +  + ]:     118696 :   if (isProofEnabled())
     471                 :            :   {
     472                 :      90640 :     d_llpg->notifyTrustedPreprocessed(trn);
     473                 :            :   }
     474                 :            :   // return the node
     475                 :     118696 :   return trn.getNode();
     476                 :            : }
     477                 :            : 
     478                 :            : }  // namespace passes
     479                 :            : }  // namespace preprocessing
     480                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14