LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/ff - gb.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 60 61 98.4 %
Date: 2026-04-21 10:32:34 Functions: 1 1 100.0 %
Branches: 36 48 75.0 %

           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                 :            :  */
      11                 :            : 
      12                 :            : #ifdef CVC5_USE_COCOA
      13                 :            : 
      14                 :            : #include "theory/ff/gb.h"
      15                 :            : 
      16                 :            : // external includes
      17                 :            : #include <CoCoA/ideal.H>
      18                 :            : #include <CoCoA/ring.H>
      19                 :            : #include <CoCoA/symbol.H>
      20                 :            : 
      21                 :            : // internal includes
      22                 :            : #include "options/ff_options.h"
      23                 :            : #include "theory/ff/cocoa_encoder.h"
      24                 :            : #include "theory/ff/multi_roots.h"
      25                 :            : 
      26                 :            : namespace cvc5::internal {
      27                 :            : namespace theory {
      28                 :            : namespace ff {
      29                 :            : 
      30                 :       1807 : FfResult gb(const std::vector<Node>& facts,
      31                 :            :             const FfSize& size,
      32                 :            :             const Env& env,
      33                 :            :             FfStatistics* stats)
      34                 :            : {
      35                 :       1807 :   CocoaEncoder enc(env.getNodeManager(), size);
      36                 :            :   // collect leaves
      37         [ +  + ]:      46681 :   for (const Node& node : facts)
      38                 :            :   {
      39                 :      44874 :     enc.addFact(node);
      40                 :            :   }
      41                 :       1807 :   enc.endScan();
      42                 :            :   // assert facts
      43         [ +  + ]:      46681 :   for (const Node& node : facts)
      44                 :            :   {
      45                 :      44874 :     enc.addFact(node);
      46                 :            :   }
      47                 :            : 
      48                 :            :   // compute a GB
      49                 :       1807 :   std::vector<CoCoA::RingElem> generators;
      50                 :       1807 :   generators.insert(generators.end(), enc.polys().begin(), enc.polys().end());
      51                 :       5421 :   generators.insert(
      52                 :       5421 :       generators.end(), enc.bitsumPolys().begin(), enc.bitsumPolys().end());
      53         [ +  + ]:       1807 :   if (env.getOptions().ff.ffFieldPolys)
      54                 :            :   {
      55                 :         11 :     CoCoA::PolyRing polyRing(enc.polyRing());
      56         [ +  + ]:         24 :     for (const auto& var : CoCoA::indets(polyRing))
      57                 :            :     {
      58                 :         13 :       CoCoA::BigInt characteristic = CoCoA::characteristic(enc.coeffRing());
      59                 :         13 :       const long power = CoCoA::LogCardinality(enc.coeffRing());
      60                 :         13 :       CoCoA::BigInt s = CoCoA::power(characteristic, power);
      61                 :         13 :       generators.push_back(CoCoA::power(var, s) - var);
      62                 :         13 :     }
      63                 :         11 :   }
      64                 :       1807 :   Tracer tracer(generators);
      65         [ +  - ]:       1807 :   if (stats) ++stats->d_numGbRuns;
      66         [ +  - ]:       1807 :   if (env.getOptions().ff.ffTraceGb) tracer.setFunctionPointers();
      67                 :       1807 :   const CoCoA::ideal ideal = CoCoA::ideal(generators);
      68                 :       1807 :   std::vector<Poly> basis;
      69                 :            :   {
      70         [ +  - ]:       1807 :     CodeTimer timer(stats ? &stats->d_timeGbRuns : nullptr);
      71                 :       1807 :     basis = GBasisTimeout(ideal, env.getResourceManager());
      72                 :       1807 :   }
      73         [ +  - ]:       1807 :   if (env.getOptions().ff.ffTraceGb) tracer.unsetFunctionPointers();
      74                 :            : 
      75                 :            :   // if it is trivial, create a conflict
      76 [ +  + ][ +  + ]:       1807 :   bool is_trivial = basis.size() == 1 && CoCoA::deg(basis.front()) == 0;
      77         [ +  + ]:       1807 :   if (is_trivial)
      78                 :            :   {
      79         [ +  - ]:       1695 :     Trace("ff::gb") << "Trivial GB" << std::endl;
      80         [ +  - ]:       1695 :     if (stats) ++stats->d_numTrivialUnsat;
      81         [ +  - ]:       1695 :     if (env.getOptions().ff.ffTraceGb)
      82                 :            :     {
      83                 :       1695 :       std::vector<size_t> coreIndices = tracer.trace(basis.front());
      84                 :       1695 :       FfCore conflict;
      85         [ +  + ]:      46162 :       for (size_t i = 0, n = facts.size(); i < n; ++i)
      86                 :            :       {
      87         [ +  - ]:      44467 :         Trace("ff::core") << "In " << i << " : " << facts[i] << std::endl;
      88                 :            :       }
      89         [ +  + ]:      13610 :       for (size_t i : coreIndices)
      90                 :            :       {
      91                 :            :         // omit (field polys, bitsum polys, ...) from core
      92         [ +  + ]:      11915 :         if (enc.polyHasFact(generators[i]))
      93                 :            :         {
      94         [ +  - ]:      11903 :           Trace("ff::core") << "Core: " << i << " : " << facts[i] << std::endl;
      95                 :      11903 :           conflict.push_back(enc.polyFact(generators[i]));
      96                 :            :         }
      97                 :            :       }
      98                 :       1695 :       return conflict;
      99                 :       1695 :     }
     100                 :            :     else
     101                 :            :     {
     102                 :            :       // set trivial conflict
     103                 :          0 :       return facts;
     104                 :            :     }
     105                 :            :   }
     106                 :            :   else
     107                 :            :   {
     108         [ +  - ]:        112 :     Trace("ff::gb") << "Non-trivial GB" << std::endl;
     109                 :            : 
     110                 :            :     // common root (vec of CoCoA base ring elements)
     111                 :            : 
     112                 :        112 :     std::vector<CoCoA::RingElem> root;
     113                 :            :     {
     114         [ +  - ]:        112 :       CodeTimer timer(stats ? &stats->d_modelConstructionTime : nullptr);
     115                 :        112 :       root = findZero(ideal, env, stats);
     116                 :        112 :     }
     117                 :            : 
     118         [ +  + ]:        112 :     if (root.empty())
     119                 :            :     {
     120                 :            :       // set trivial conflict
     121                 :          9 :       return facts;
     122                 :            :     }
     123                 :            :     else
     124                 :            :     {
     125                 :        103 :       FfModel model;
     126         [ +  + ]:        390 :       for (const auto& [idx, node] : enc.nodeIndets())
     127                 :            :       {
     128         [ +  - ]:        287 :         if (isFfLeaf(node))
     129                 :            :         {
     130                 :        287 :           model.emplace(node, enc.cocoaFfToFfVal(root[idx]));
     131                 :            :         }
     132                 :        103 :       }
     133                 :        103 :       return model;
     134                 :        103 :     }
     135                 :        112 :   }
     136                 :       1807 : }
     137                 :            : 
     138                 :            : }  // namespace ff
     139                 :            : }  // namespace theory
     140                 :            : }  // namespace cvc5::internal
     141                 :            : 
     142                 :            : #endif

Generated by: LCOV version 1.14