LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/quantifiers/sygus - transition_inference.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 303 318 95.3 %
Date: 2026-04-26 10:45:53 Functions: 20 20 100.0 %
Branches: 225 330 68.2 %

           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                 :            :  * Implementation of utility for inferring whether a synthesis conjecture
      11                 :            :  * encodes a transition system.
      12                 :            :  */
      13                 :            : #include "theory/quantifiers/sygus/transition_inference.h"
      14                 :            : 
      15                 :            : #include "expr/node_algorithm.h"
      16                 :            : #include "expr/skolem_manager.h"
      17                 :            : #include "theory/arith/arith_msum.h"
      18                 :            : #include "theory/quantifiers/term_util.h"
      19                 :            : #include "theory/rewriter.h"
      20                 :            : 
      21                 :            : using namespace cvc5::internal::kind;
      22                 :            : 
      23                 :            : namespace cvc5::internal {
      24                 :            : namespace theory {
      25                 :            : namespace quantifiers {
      26                 :            : 
      27                 :        630 : bool DetTrace::DetTraceTrie::add(Node loc, const std::vector<Node>& val)
      28                 :            : {
      29                 :        630 :   DetTraceTrie* curr = this;
      30         [ +  + ]:       1876 :   for (const Node& v : val)
      31                 :            :   {
      32                 :       1246 :     curr = &(curr->d_children[v]);
      33                 :            :   }
      34         [ +  - ]:        630 :   if (curr->d_children.empty())
      35                 :            :   {
      36                 :        630 :     curr->d_children[loc].clear();
      37                 :        630 :     return true;
      38                 :            :   }
      39                 :          0 :   return false;
      40                 :            : }
      41                 :            : 
      42                 :         14 : Node DetTrace::DetTraceTrie::constructFormula(NodeManager* nm,
      43                 :            :                                               const std::vector<Node>& vars,
      44                 :            :                                               unsigned index)
      45                 :            : {
      46         [ -  + ]:         14 :   if (index == vars.size())
      47                 :            :   {
      48                 :          0 :     return nm->mkConst(true);
      49                 :            :   }
      50                 :         14 :   std::vector<Node> disj;
      51         [ +  + ]:         48 :   for (std::pair<const Node, DetTraceTrie>& p : d_children)
      52                 :            :   {
      53                 :         34 :     Node eq = vars[index].eqNode(p.first);
      54         [ +  + ]:         34 :     if (index < vars.size() - 1)
      55                 :            :     {
      56                 :         10 :       Node conc = p.second.constructFormula(nm, vars, index + 1);
      57                 :         10 :       disj.push_back(nm->mkNode(Kind::AND, eq, conc));
      58                 :         10 :     }
      59                 :            :     else
      60                 :            :     {
      61                 :         24 :       disj.push_back(eq);
      62                 :            :     }
      63                 :         34 :   }
      64 [ -  + ][ -  + ]:         14 :   Assert(!disj.empty());
                 [ -  - ]
      65         [ +  + ]:         14 :   return disj.size() == 1 ? disj[0] : nm->mkNode(Kind::OR, disj);
      66                 :         14 : }
      67                 :            : 
      68                 :        630 : bool DetTrace::increment(Node loc, std::vector<Node>& vals)
      69                 :            : {
      70         [ +  - ]:        630 :   if (d_trie.add(loc, vals))
      71                 :            :   {
      72         [ +  + ]:       1876 :     for (unsigned i = 0, vsize = vals.size(); i < vsize; i++)
      73                 :            :     {
      74                 :       1246 :       d_curr[i] = vals[i];
      75                 :            :     }
      76                 :        630 :     return true;
      77                 :            :   }
      78                 :          0 :   return false;
      79                 :            : }
      80                 :            : 
      81                 :          4 : Node DetTrace::constructFormula(NodeManager* nm, const std::vector<Node>& vars)
      82                 :            : {
      83                 :          4 :   return d_trie.constructFormula(nm, vars);
      84                 :            : }
      85                 :            : 
      86                 :        634 : void DetTrace::print(CVC5_UNUSED const char* c) const
      87                 :            : {
      88         [ +  + ]:       1886 :   for (const Node& n : d_curr)
      89                 :            :   {
      90         [ +  - ]:       1252 :     Trace(c) << n << " ";
      91                 :            :   }
      92                 :        634 : }
      93                 :            : 
      94                 :        495 : Node TransitionInference::getFunction() const { return d_func; }
      95                 :            : 
      96                 :        602 : void TransitionInference::getVariables(std::vector<Node>& vars) const
      97                 :            : {
      98                 :        602 :   vars.insert(vars.end(), d_vars.begin(), d_vars.end());
      99                 :        602 : }
     100                 :            : 
     101                 :        602 : Node TransitionInference::getPreCondition() const { return d_pre.d_this; }
     102                 :       1226 : Node TransitionInference::getPostCondition() const { return d_post.d_this; }
     103                 :       1210 : Node TransitionInference::getTransitionRelation() const
     104                 :            : {
     105                 :       1210 :   return d_trans.d_this;
     106                 :            : }
     107                 :            : 
     108                 :       1421 : void TransitionInference::getConstantSubstitution(
     109                 :            :     const std::vector<Node>& vars,
     110                 :            :     const std::vector<Node>& disjuncts,
     111                 :            :     std::vector<Node>& const_var,
     112                 :            :     std::vector<Node>& const_subs,
     113                 :            :     bool reqPol)
     114                 :            : {
     115         [ +  + ]:       4547 :   for (const Node& d : disjuncts)
     116                 :            :   {
     117                 :       3126 :     Node sn;
     118         [ +  + ]:       3126 :     if (!const_var.empty())
     119                 :            :     {
     120                 :        944 :       sn = d.substitute(const_var.begin(),
     121                 :            :                         const_var.end(),
     122                 :            :                         const_subs.begin(),
     123                 :        472 :                         const_subs.end());
     124                 :        472 :       sn = rewrite(sn);
     125                 :            :     }
     126                 :            :     else
     127                 :            :     {
     128                 :       2654 :       sn = d;
     129                 :            :     }
     130                 :       3126 :     bool slit_pol = sn.getKind() != Kind::NOT;
     131         [ +  + ]:       3126 :     Node slit = sn.getKind() == Kind::NOT ? sn[0] : sn;
     132 [ +  + ][ +  + ]:       3126 :     if (slit.getKind() == Kind::EQUAL && slit_pol == reqPol)
                 [ +  + ]
     133                 :            :     {
     134                 :            :       // check if it is a variable equality
     135                 :        422 :       TNode v;
     136                 :        422 :       Node s;
     137         [ +  + ]:        847 :       for (unsigned r = 0; r < 2; r++)
     138                 :            :       {
     139         [ +  + ]:        663 :         if (std::find(vars.begin(), vars.end(), slit[r]) != vars.end())
     140                 :            :         {
     141         [ +  + ]:        239 :           if (!expr::hasSubterm(slit[1 - r], slit[r]))
     142                 :            :           {
     143                 :        238 :             v = slit[r];
     144                 :        238 :             s = slit[1 - r];
     145                 :        238 :             break;
     146                 :            :           }
     147                 :            :         }
     148                 :            :       }
     149         [ +  + ]:        422 :       if (v.isNull())
     150                 :            :       {
     151                 :            :         // solve for var
     152                 :        184 :         std::map<Node, Node> msum;
     153         [ +  + ]:        184 :         if (ArithMSum::getMonomialSumLit(slit, msum))
     154                 :            :         {
     155         [ +  + ]:        233 :           for (std::pair<const Node, Node>& m : msum)
     156                 :            :           {
     157         [ +  + ]:        172 :             if (std::find(vars.begin(), vars.end(), m.first) != vars.end())
     158                 :            :             {
     159                 :         54 :               Node veq_c;
     160                 :         54 :               Node val;
     161                 :            :               int ires =
     162                 :         54 :                   ArithMSum::isolate(m.first, msum, veq_c, val, Kind::EQUAL);
     163         [ +  - ]:         54 :               if (ires != 0 && veq_c.isNull()
     164                 :        108 :                   && !expr::hasSubterm(val, m.first))
     165                 :            :               {
     166                 :         54 :                 v = m.first;
     167                 :         54 :                 s = val;
     168                 :            :               }
     169                 :         54 :             }
     170                 :            :           }
     171                 :            :         }
     172                 :        184 :       }
     173         [ +  + ]:        422 :       if (!v.isNull())
     174                 :            :       {
     175                 :        292 :         TNode ts = s;
     176         [ +  + ]:        486 :         for (unsigned k = 0, csize = const_subs.size(); k < csize; k++)
     177                 :            :         {
     178                 :        194 :           const_subs[k] = rewrite(const_subs[k].substitute(v, ts));
     179                 :            :         }
     180         [ +  - ]:        584 :         Trace("cegqi-inv-debug2")
     181                 :        292 :             << "...substitution : " << v << " -> " << s << std::endl;
     182                 :        292 :         const_var.push_back(v);
     183                 :        292 :         const_subs.push_back(s);
     184                 :        292 :       }
     185                 :        422 :     }
     186                 :       3126 :   }
     187                 :       1421 : }
     188                 :            : 
     189                 :       1458 : void TransitionInference::process(Node n, Node f)
     190                 :            : {
     191                 :            :   // set the function
     192                 :       1458 :   d_func = f;
     193                 :       1458 :   process(n);
     194                 :       1458 : }
     195                 :            : 
     196                 :       1458 : void TransitionInference::process(Node n)
     197                 :            : {
     198                 :       1458 :   NodeManager* nm = nodeManager();
     199                 :       1458 :   d_complete = true;
     200                 :       1458 :   d_trivial = true;
     201                 :       1458 :   std::vector<Node> n_check;
     202         [ +  + ]:       1458 :   if (n.getKind() == Kind::AND)
     203                 :            :   {
     204         [ +  + ]:       1559 :     for (const Node& nc : n)
     205                 :            :     {
     206                 :       1090 :       n_check.push_back(nc);
     207                 :       1090 :     }
     208                 :            :   }
     209                 :            :   else
     210                 :            :   {
     211                 :        989 :     n_check.push_back(n);
     212                 :            :   }
     213         [ +  + ]:       3537 :   for (const Node& nn : n_check)
     214                 :            :   {
     215                 :       2079 :     std::map<bool, std::map<Node, bool> > visited;
     216                 :       2079 :     std::map<bool, Node> terms;
     217                 :       2079 :     std::vector<Node> disjuncts;
     218         [ +  - ]:       4158 :     Trace("cegqi-inv") << "TransitionInference : Process disjunct : " << nn
     219                 :       2079 :                        << std::endl;
     220         [ +  + ]:       2079 :     if (!processDisjunct(nn, terms, disjuncts, visited, true))
     221                 :            :     {
     222                 :        283 :       d_complete = false;
     223                 :        283 :       continue;
     224                 :            :     }
     225         [ +  + ]:       1796 :     if (terms.empty())
     226                 :            :     {
     227                 :        375 :       continue;
     228                 :            :     }
     229                 :       1421 :     Node curr;
     230                 :            :     // The component that this disjunct contributes to, where
     231                 :            :     // 1 : pre-condition, -1 : post-condition, 0 : transition relation
     232                 :            :     int comp_num;
     233                 :       1421 :     std::map<bool, Node>::iterator itt = terms.find(false);
     234         [ +  + ]:       1421 :     if (itt != terms.end())
     235                 :            :     {
     236                 :        909 :       curr = itt->second;
     237         [ +  + ]:        909 :       if (terms.find(true) != terms.end())
     238                 :            :       {
     239                 :         66 :         comp_num = 0;
     240                 :            :       }
     241                 :            :       else
     242                 :            :       {
     243                 :        843 :         comp_num = -1;
     244                 :            :       }
     245                 :            :     }
     246                 :            :     else
     247                 :            :     {
     248                 :        512 :       curr = terms[true];
     249                 :        512 :       comp_num = 1;
     250                 :            :     }
     251         [ +  - ]:       1421 :     Trace("cegqi-inv-debug2") << "  normalize based on " << curr << std::endl;
     252                 :       1421 :     std::vector<Node> vars;
     253                 :       1421 :     std::vector<Node> svars;
     254                 :       1421 :     getNormalizedSubstitution(curr, d_vars, vars, svars, disjuncts);
     255         [ +  + ]:       4531 :     for (unsigned j = 0, dsize = disjuncts.size(); j < dsize; j++)
     256                 :            :     {
     257         [ +  - ]:       3110 :       Trace("cegqi-inv-debug2") << "  apply " << disjuncts[j] << std::endl;
     258                 :       6220 :       disjuncts[j] = rewrite(disjuncts[j].substitute(
     259                 :       3110 :           vars.begin(), vars.end(), svars.begin(), svars.end()));
     260         [ +  - ]:       3110 :       Trace("cegqi-inv-debug2") << "  ..." << disjuncts[j] << std::endl;
     261                 :            :     }
     262                 :       1421 :     std::vector<Node> const_var;
     263                 :       1421 :     std::vector<Node> const_subs;
     264         [ +  + ]:       1421 :     if (comp_num == 0)
     265                 :            :     {
     266                 :            :       // transition
     267 [ -  + ][ -  + ]:         66 :       Assert(terms.find(true) != terms.end());
                 [ -  - ]
     268                 :         66 :       Node next = terms[true];
     269                 :        132 :       next = rewrite(next.substitute(
     270                 :         66 :           vars.begin(), vars.end(), svars.begin(), svars.end()));
     271         [ +  - ]:        132 :       Trace("cegqi-inv-debug")
     272                 :         66 :           << "transition next predicate : " << next << std::endl;
     273                 :            :       // make the primed variables if we have not already
     274         [ +  - ]:         66 :       if (d_prime_vars.empty())
     275                 :            :       {
     276         [ +  + ]:        374 :         for (unsigned j = 0, nchild = next.getNumChildren(); j < nchild; j++)
     277                 :            :         {
     278                 :        616 :           Node v = NodeManager::mkDummySkolem("ir", next[j].getType());
     279                 :        308 :           d_prime_vars.push_back(v);
     280                 :        308 :         }
     281                 :            :       }
     282                 :            :       // normalize the other direction
     283         [ +  - ]:         66 :       Trace("cegqi-inv-debug2") << "  normalize based on " << next << std::endl;
     284                 :         66 :       std::vector<Node> rvars;
     285                 :         66 :       std::vector<Node> rsvars;
     286                 :         66 :       getNormalizedSubstitution(next, d_prime_vars, rvars, rsvars, disjuncts);
     287 [ -  + ][ -  + ]:         66 :       Assert(rvars.size() == rsvars.size());
                 [ -  - ]
     288         [ +  + ]:        368 :       for (unsigned j = 0, dsize = disjuncts.size(); j < dsize; j++)
     289                 :            :       {
     290         [ +  - ]:        302 :         Trace("cegqi-inv-debug2") << "  apply " << disjuncts[j] << std::endl;
     291                 :        604 :         disjuncts[j] = rewrite(disjuncts[j].substitute(
     292                 :        302 :             rvars.begin(), rvars.end(), rsvars.begin(), rsvars.end()));
     293         [ +  - ]:        302 :         Trace("cegqi-inv-debug2") << "  ..." << disjuncts[j] << std::endl;
     294                 :            :       }
     295                 :         66 :       getConstantSubstitution(
     296                 :         66 :           d_prime_vars, disjuncts, const_var, const_subs, false);
     297                 :         66 :     }
     298                 :            :     else
     299                 :            :     {
     300                 :       1355 :       getConstantSubstitution(d_vars, disjuncts, const_var, const_subs, false);
     301                 :            :     }
     302                 :       1421 :     Node res;
     303         [ +  + ]:       1421 :     if (disjuncts.empty())
     304                 :            :     {
     305                 :         12 :       res = nm->mkConst(false);
     306                 :            :     }
     307         [ +  + ]:       1409 :     else if (disjuncts.size() == 1)
     308                 :            :     {
     309                 :        309 :       res = disjuncts[0];
     310                 :            :     }
     311                 :            :     else
     312                 :            :     {
     313                 :       1100 :       res = nm->mkNode(Kind::OR, disjuncts);
     314                 :            :     }
     315         [ +  + ]:       1421 :     if (expr::hasBoundVar(res))
     316                 :            :     {
     317         [ +  - ]:        626 :       Trace("cegqi-inv-debug2") << "...failed, free variable." << std::endl;
     318                 :        626 :       d_complete = false;
     319                 :        626 :       continue;
     320                 :            :     }
     321         [ +  - ]:       1590 :     Trace("cegqi-inv") << "*** inferred "
     322         [ -  - ]:        795 :                        << (comp_num == 1 ? "pre"
     323         [ -  - ]:          0 :                                          : (comp_num == -1 ? "post" : "trans"))
     324                 :        795 :                        << "-condition : " << res << std::endl;
     325 [ +  + ][ +  + ]:        795 :     Component& c =
     326                 :            :         (comp_num == 1 ? d_pre : (comp_num == -1 ? d_post : d_trans));
     327                 :        795 :     c.d_conjuncts.push_back(res);
     328         [ +  + ]:        795 :     if (!const_var.empty())
     329                 :            :     {
     330                 :        133 :       bool has_const_eq = const_var.size() == d_vars.size();
     331         [ +  - ]:        266 :       Trace("cegqi-inv") << "    with constant substitution, complete = "
     332                 :        133 :                          << has_const_eq << " : " << std::endl;
     333         [ +  + ]:        390 :       for (unsigned i = 0, csize = const_var.size(); i < csize; i++)
     334                 :            :       {
     335         [ +  - ]:        514 :         Trace("cegqi-inv") << "      " << const_var[i] << " -> "
     336                 :        257 :                            << const_subs[i] << std::endl;
     337         [ +  + ]:        257 :         if (has_const_eq)
     338                 :            :         {
     339                 :        144 :           c.d_const_eq[res][const_var[i]] = const_subs[i];
     340                 :            :         }
     341                 :            :       }
     342         [ +  - ]:        266 :       Trace("cegqi-inv") << "...size = " << const_var.size()
     343                 :        133 :                          << ", #vars = " << d_vars.size() << std::endl;
     344                 :            :     }
     345 [ +  + ][ +  + ]:       8403 :   }
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
                 [ +  + ]
     346                 :            : 
     347                 :            :   // finalize the components
     348         [ +  + ]:       5832 :   for (int i = -1; i <= 1; i++)
     349                 :            :   {
     350 [ +  + ][ +  + ]:       4374 :     Component& c = (i == 1 ? d_pre : (i == -1 ? d_post : d_trans));
     351                 :       4374 :     Node ret;
     352         [ +  + ]:       4374 :     if (c.d_conjuncts.empty())
     353                 :            :     {
     354                 :       3587 :       ret = nm->mkConst(true);
     355                 :            :     }
     356         [ +  + ]:        787 :     else if (c.d_conjuncts.size() == 1)
     357                 :            :     {
     358                 :        781 :       ret = c.d_conjuncts[0];
     359                 :            :     }
     360                 :            :     else
     361                 :            :     {
     362                 :          6 :       ret = nm->mkNode(Kind::AND, c.d_conjuncts);
     363                 :            :     }
     364 [ +  + ][ +  + ]:       4374 :     if (i == 0 || i == 1)
     365                 :            :     {
     366                 :            :       // pre-condition and transition are negated
     367                 :       2916 :       ret = TermUtil::simpleNegate(ret);
     368                 :            :     }
     369                 :       4374 :     c.d_this = ret;
     370                 :       4374 :   }
     371                 :       1458 : }
     372                 :       1487 : void TransitionInference::getNormalizedSubstitution(
     373                 :            :     Node curr,
     374                 :            :     const std::vector<Node>& pvars,
     375                 :            :     std::vector<Node>& vars,
     376                 :            :     std::vector<Node>& subs,
     377                 :            :     std::vector<Node>& disjuncts)
     378                 :            : {
     379         [ +  + ]:       4597 :   for (unsigned j = 0, nchild = curr.getNumChildren(); j < nchild; j++)
     380                 :            :   {
     381         [ +  + ]:       3110 :     if (curr[j].getKind() == Kind::BOUND_VARIABLE)
     382                 :            :     {
     383                 :            :       // if the argument is a bound variable, add to the renaming
     384                 :       3009 :       vars.push_back(curr[j]);
     385                 :       3009 :       subs.push_back(pvars[j]);
     386                 :            :     }
     387                 :            :     else
     388                 :            :     {
     389                 :            :       // otherwise, treat as a constraint on the variable
     390                 :            :       // For example, this transforms e.g. a precondition clause
     391                 :            :       // I( 0, 1 ) to x1 != 0 OR x2 != 1 OR I( x1, x2 ).
     392                 :        101 :       Node eq = curr[j].eqNode(pvars[j]);
     393                 :        101 :       disjuncts.push_back(eq.negate());
     394                 :        101 :     }
     395                 :            :   }
     396                 :       1487 : }
     397                 :            : 
     398                 :      22821 : bool TransitionInference::processDisjunct(
     399                 :            :     Node n,
     400                 :            :     std::map<bool, Node>& terms,
     401                 :            :     std::vector<Node>& disjuncts,
     402                 :            :     std::map<bool, std::map<Node, bool> >& visited,
     403                 :            :     bool topLevel)
     404                 :            : {
     405         [ +  + ]:      22821 :   if (visited[topLevel].find(n) != visited[topLevel].end())
     406                 :            :   {
     407                 :       4830 :     return true;
     408                 :            :   }
     409                 :      17991 :   visited[topLevel][n] = true;
     410 [ +  + ][ +  + ]:      17991 :   bool childTopLevel = n.getKind() == Kind::OR && topLevel;
     411                 :            :   // if another part mentions UF or a free variable, then fail
     412                 :      17991 :   bool lit_pol = n.getKind() != Kind::NOT;
     413         [ +  + ]:      17991 :   Node lit = n.getKind() == Kind::NOT ? n[0] : n;
     414                 :            :   // is it an application of the function-to-synthesize? Yes if we haven't
     415                 :            :   // encountered a function or if it matches the existing d_func.
     416                 :      53973 :   if (lit.getKind() == Kind::APPLY_UF
     417 [ +  + ][ +  - ]:      17991 :       && (d_func.isNull() || lit.getOperator() == d_func))
         [ +  + ][ +  + ]
         [ +  + ][ -  - ]
     418                 :            :   {
     419                 :       1770 :     Node op = lit.getOperator();
     420                 :            :     // initialize the variables
     421         [ +  + ]:       1770 :     if (d_trivial)
     422                 :            :     {
     423                 :       1093 :       d_trivial = false;
     424                 :       1093 :       d_func = op;
     425         [ +  - ]:       1093 :       Trace("cegqi-inv-debug") << "Use " << op << " with args ";
     426         [ +  + ]:       3235 :       for (const Node& l : lit)
     427                 :            :       {
     428                 :       4284 :         Node v = NodeManager::mkDummySkolem("i", l.getType());
     429                 :       2142 :         d_vars.push_back(v);
     430         [ +  - ]:       2142 :         Trace("cegqi-inv-debug") << v << " ";
     431                 :       2142 :       }
     432         [ +  - ]:       1093 :       Trace("cegqi-inv-debug") << std::endl;
     433                 :            :     }
     434 [ -  + ][ -  + ]:       1770 :     Assert(!d_func.isNull());
                 [ -  - ]
     435         [ +  + ]:       1770 :     if (topLevel)
     436                 :            :     {
     437         [ +  - ]:       1487 :       if (terms.find(lit_pol) == terms.end())
     438                 :            :       {
     439                 :       1487 :         terms[lit_pol] = lit;
     440                 :       1487 :         return true;
     441                 :            :       }
     442                 :            :       else
     443                 :            :       {
     444         [ -  - ]:          0 :         Trace("cegqi-inv-debug")
     445                 :          0 :             << "...failed, repeated inv-app : " << lit << std::endl;
     446                 :          0 :         return false;
     447                 :            :       }
     448                 :            :     }
     449         [ +  - ]:        566 :     Trace("cegqi-inv-debug")
     450                 :        283 :         << "...failed, non-entailed inv-app : " << lit << std::endl;
     451                 :        283 :     return false;
     452                 :       1770 :   }
     453 [ +  + ][ +  + ]:      16221 :   else if (topLevel && !childTopLevel)
     454                 :            :   {
     455                 :       3719 :     disjuncts.push_back(n);
     456                 :            :   }
     457         [ +  + ]:      36498 :   for (const Node& nc : n)
     458                 :            :   {
     459         [ +  + ]:      20742 :     if (!processDisjunct(nc, terms, disjuncts, visited, childTopLevel))
     460                 :            :     {
     461                 :        465 :       return false;
     462                 :            :     }
     463         [ +  + ]:      20742 :   }
     464                 :      15756 :   return true;
     465                 :      17991 : }
     466                 :            : 
     467                 :         43 : TraceIncStatus TransitionInference::initializeTrace(DetTrace& dt,
     468                 :            :                                                     Node loc,
     469                 :            :                                                     bool fwd)
     470                 :            : {
     471         [ +  - ]:         43 :   Component& c = fwd ? d_pre : d_post;
     472 [ -  + ][ -  + ]:         43 :   Assert(c.has(loc));
                 [ -  - ]
     473                 :         43 :   std::map<Node, std::map<Node, Node> >::iterator it = c.d_const_eq.find(loc);
     474         [ +  + ]:         43 :   if (it != c.d_const_eq.end())
     475                 :            :   {
     476                 :         10 :     std::vector<Node> next;
     477         [ +  + ]:         28 :     for (const Node& v : d_vars)
     478                 :            :     {
     479 [ -  + ][ -  + ]:         18 :       Assert(it->second.find(v) != it->second.end());
                 [ -  - ]
     480                 :         18 :       next.push_back(it->second[v]);
     481                 :         18 :       dt.d_curr.push_back(it->second[v]);
     482                 :            :     }
     483         [ +  - ]:         10 :     Trace("cegqi-inv-debug2") << "dtrace : initial increment" << std::endl;
     484                 :         10 :     bool ret = dt.increment(loc, next);
     485 [ -  + ][ -  + ]:         10 :     AlwaysAssert(ret);
                 [ -  - ]
     486                 :         10 :     return TRACE_INC_SUCCESS;
     487                 :         10 :   }
     488                 :         33 :   return TRACE_INC_INVALID;
     489                 :            : }
     490                 :            : 
     491                 :        624 : TraceIncStatus TransitionInference::incrementTrace(DetTrace& dt,
     492                 :            :                                                    Node loc,
     493                 :            :                                                    bool fwd)
     494                 :            : {
     495 [ -  + ][ -  + ]:        624 :   Assert(d_trans.has(loc));
                 [ -  - ]
     496                 :            :   // check if it satisfies the pre/post condition
     497         [ +  - ]:        624 :   Node cc = fwd ? getPostCondition() : getPreCondition();
     498 [ -  + ][ -  + ]:        624 :   Assert(!cc.isNull());
                 [ -  - ]
     499                 :        624 :   Node ccr = rewrite(cc.substitute(
     500                 :       1872 :       d_vars.begin(), d_vars.end(), dt.d_curr.begin(), dt.d_curr.end()));
     501         [ +  - ]:        624 :   if (ccr.isConst())
     502                 :            :   {
     503 [ +  - ][ -  + ]:        624 :     if (ccr.getConst<bool>() == (fwd ? false : true))
     504                 :            :     {
     505         [ -  - ]:          0 :       Trace("cegqi-inv-debug2") << "dtrace : counterexample" << std::endl;
     506                 :          0 :       return TRACE_INC_CEX;
     507                 :            :     }
     508                 :            :   }
     509                 :            : 
     510                 :            :   // terminates?
     511                 :        624 :   Node c = getTransitionRelation();
     512 [ -  + ][ -  + ]:        624 :   Assert(!c.isNull());
                 [ -  - ]
     513                 :            : 
     514 [ -  + ][ -  + ]:        624 :   Assert(d_vars.size() == dt.d_curr.size());
                 [ -  - ]
     515                 :        624 :   Node cr = rewrite(c.substitute(
     516                 :       1872 :       d_vars.begin(), d_vars.end(), dt.d_curr.begin(), dt.d_curr.end()));
     517         [ +  + ]:        624 :   if (cr.isConst())
     518                 :            :   {
     519         [ +  - ]:          4 :     if (!cr.getConst<bool>())
     520                 :            :     {
     521         [ +  - ]:          4 :       Trace("cegqi-inv-debug2") << "dtrace : terminated" << std::endl;
     522                 :          4 :       return TRACE_INC_TERMINATE;
     523                 :            :     }
     524                 :          0 :     return TRACE_INC_INVALID;
     525                 :            :   }
     526         [ -  + ]:        620 :   if (!fwd)
     527                 :            :   {
     528                 :            :     // only implemented in forward direction
     529                 :          0 :     DebugUnhandled();
     530                 :            :     return TRACE_INC_INVALID;
     531                 :            :   }
     532                 :        620 :   Component& cm = d_trans;
     533                 :        620 :   std::map<Node, std::map<Node, Node> >::iterator it = cm.d_const_eq.find(loc);
     534         [ -  + ]:        620 :   if (it == cm.d_const_eq.end())
     535                 :            :   {
     536                 :          0 :     return TRACE_INC_INVALID;
     537                 :            :   }
     538                 :        620 :   std::vector<Node> next;
     539         [ +  + ]:       1848 :   for (const Node& pv : d_prime_vars)
     540                 :            :   {
     541 [ -  + ][ -  + ]:       1228 :     Assert(it->second.find(pv) != it->second.end());
                 [ -  - ]
     542                 :       1228 :     Node pvs = it->second[pv];
     543 [ -  + ][ -  + ]:       1228 :     Assert(d_vars.size() == dt.d_curr.size());
                 [ -  - ]
     544                 :       1228 :     Node pvsr = rewrite(pvs.substitute(
     545                 :       3684 :         d_vars.begin(), d_vars.end(), dt.d_curr.begin(), dt.d_curr.end()));
     546                 :       1228 :     next.push_back(pvsr);
     547                 :       1228 :   }
     548         [ +  - ]:        620 :   if (dt.increment(loc, next))
     549                 :            :   {
     550         [ +  - ]:        620 :     Trace("cegqi-inv-debug2") << "dtrace : success increment" << std::endl;
     551                 :        620 :     return TRACE_INC_SUCCESS;
     552                 :            :   }
     553                 :            :   // looped
     554         [ -  - ]:          0 :   Trace("cegqi-inv-debug2") << "dtrace : looped" << std::endl;
     555                 :          0 :   return TRACE_INC_TERMINATE;
     556                 :        624 : }
     557                 :            : 
     558                 :         45 : TraceIncStatus TransitionInference::initializeTrace(DetTrace& dt, bool fwd)
     559                 :            : {
     560         [ +  - ]:         45 :   Trace("cegqi-inv-debug2") << "Initialize trace" << std::endl;
     561         [ +  - ]:         45 :   Component& c = fwd ? d_pre : d_post;
     562         [ +  + ]:         45 :   if (c.d_conjuncts.size() == 1)
     563                 :            :   {
     564                 :         43 :     return initializeTrace(dt, c.d_conjuncts[0], fwd);
     565                 :            :   }
     566                 :          2 :   return TRACE_INC_INVALID;
     567                 :            : }
     568                 :            : 
     569                 :        624 : TraceIncStatus TransitionInference::incrementTrace(DetTrace& dt, bool fwd)
     570                 :            : {
     571         [ +  - ]:        624 :   if (d_trans.d_conjuncts.size() == 1)
     572                 :            :   {
     573                 :        624 :     return incrementTrace(dt, d_trans.d_conjuncts[0], fwd);
     574                 :            :   }
     575                 :          0 :   return TRACE_INC_INVALID;
     576                 :            : }
     577                 :            : 
     578                 :          4 : Node TransitionInference::constructFormulaTrace(DetTrace& dt) const
     579                 :            : {
     580                 :          4 :   return dt.constructFormula(nodeManager(), d_vars);
     581                 :            : }
     582                 :            : 
     583                 :            : }  // namespace quantifiers
     584                 :            : }  // namespace theory
     585                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14