LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/ff - cocoa_encoder.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 5 5 100.0 %
Date: 2026-05-04 10:34:19 Functions: 5 5 100.0 %
Branches: 0 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                 :            :  * encoding Nodes as cocoa ring elements.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "cvc5_private.h"
      14                 :            : 
      15                 :            : #ifdef CVC5_USE_COCOA
      16                 :            : 
      17                 :            : #ifndef CVC5__THEORY__FF__COCOA_H
      18                 :            : #define CVC5__THEORY__FF__COCOA_H
      19                 :            : 
      20                 :            : // external includes
      21                 :            : #include <CoCoA/ring.H>
      22                 :            : #include <CoCoA/symbol.H>
      23                 :            : 
      24                 :            : // std includes
      25                 :            : #include <optional>
      26                 :            : #include <string>
      27                 :            : #include <unordered_map>
      28                 :            : #include <unordered_set>
      29                 :            : 
      30                 :            : // internal includes
      31                 :            : #include "expr/node.h"
      32                 :            : #include "theory/ff/cocoa_util.h"
      33                 :            : #include "theory/ff/core.h"
      34                 :            : #include "theory/ff/util.h"
      35                 :            : 
      36                 :            : namespace cvc5::internal {
      37                 :            : namespace theory {
      38                 :            : namespace ff {
      39                 :            : 
      40                 :            : /**
      41                 :            :  *  Create cocoa symbol, sanitizing varName.
      42                 :            :  *  If index is given, subscript the symbol by it.
      43                 :            :  */
      44                 :            : CoCoA::symbol cocoaSym(const std::string& varName,
      45                 :            :                        std::optional<size_t> index = {});
      46                 :            : 
      47                 :            : /**
      48                 :            :  * Class for encoding a Node as a Poly.
      49                 :            :  *
      50                 :            :  * Requires two passes over the nodes. On the first pass it collects variables,
      51                 :            :  * !=s, and bitsums. On the second, it encodes. The first stage is called
      52                 :            :  * "Stage::Scan", the second is "Stage::Encode".
      53                 :            :  *
      54                 :            :  * Two stages are necessary because when creating a CoCoA polynomial ring, one
      55                 :            :  * must declare all the variables up-front. So, before we create any polynomials
      56                 :            :  * (to encode terms), we must know all the (CoCoA) variables. CoCoA variables
      57                 :            :  * are used to encode cvc5 variables, bitsums, and witnesses of disequality (a
      58                 :            :  * != b is encoded as (a - b)w = 1, where w is the witness).
      59                 :            :  */
      60                 :            : class CocoaEncoder : public FieldObj
      61                 :            : {
      62                 :            :  public:
      63                 :            :   /** Create a new encoder, for this field. */
      64                 :            :   CocoaEncoder(NodeManager* nm, const FfSize& size);
      65                 :            :   /** Add a fact (one must call this twice per fact, once per stage). */
      66                 :            :   void addFact(const Node& fact);
      67                 :            :   /** Start Stage::Encode. */
      68                 :            :   void endScan();
      69                 :            :   /**
      70                 :            :    * Get the polys who's common zero we are finding (excluding bitsums).
      71                 :            :    * Available in Stage::Encode.
      72                 :            :    */
      73                 :       5290 :   const std::vector<Poly>& polys() const { return d_polys; }
      74                 :            :   /**
      75                 :            :    * Get the bitsum polys.
      76                 :            :    * These have form: x - b0 - 2*b1 - 4b2 ... - 2^n*b_n.
      77                 :            :    * Available in Stage::Encode.
      78                 :            :    */
      79                 :       4452 :   const std::vector<Poly>& bitsumPolys() const { return d_bitsumPolys; }
      80                 :            :   /**
      81                 :            :    * Get the poly for this term
      82                 :            :    * Available in Stage::Encode.
      83                 :            :    */
      84                 :       5109 :   const Poly& getTermEncoding(const Node& t) const { return d_cache.at(t); }
      85                 :            :   /**
      86                 :            :    * Get the bitsum terms (for the bitsumPolys).
      87                 :            :    * Available in Stage::Encode.
      88                 :            :    */
      89                 :            :   std::vector<Node> bitsums() const;
      90                 :            :   /**
      91                 :            :    * The coefficient ring of the poly ring we're encoding into.
      92                 :            :    * Available in Stage::Encode.
      93                 :            :    */
      94                 :         26 :   const CoCoA::ring& coeffRing() const { return d_coeffRing.value(); }
      95                 :            :   /**
      96                 :            :    * The poly ring we've encoded into.
      97                 :            :    * Available in Stage::Encode.
      98                 :            :    */
      99                 :       2792 :   const CoCoA::ring& polyRing() const { return d_polyRing.value(); }
     100                 :            :   /**
     101                 :            :    * A list of (indeterminant num, Node) pairs. Useful for extracting a model.
     102                 :            :    * Available in Stage::Encode.
     103                 :            :    */
     104                 :            :   std::vector<std::pair<size_t, Node>> nodeIndets() const;
     105                 :            :   /**
     106                 :            :    * Convert a (coefficient) Scalar to a FiniteFieldValue.
     107                 :            :    */
     108                 :            :   FiniteFieldValue cocoaFfToFfVal(const Scalar& elem) const;
     109                 :            :   /**
     110                 :            :    * Does some fact that imply this poly?
     111                 :            :    */
     112                 :            :   bool polyHasFact(const Poly& poly) const;
     113                 :            :   /**
     114                 :            :    * Get the fact that implies this poly.
     115                 :            :    */
     116                 :            :   const Node& polyFact(const Poly& poly) const;
     117                 :            : 
     118                 :            :  private:
     119                 :            :   /**
     120                 :            :    * Get a fresh symbol that starts with varName.
     121                 :            :    * If index is given, subscript the symbol by it.
     122                 :            :    */
     123                 :            :   CoCoA::symbol freshSym(const std::string& varName,
     124                 :            :                          std::optional<size_t> index = {});
     125                 :            :   /** a bitsum or a var */
     126                 :            :   const Node& symNode(CoCoA::symbol s) const;
     127                 :            :   /** have we assigned this symbol to some Node? */
     128                 :            :   bool hasNode(CoCoA::symbol s) const;
     129                 :            :   /** get the poly for this symbol */
     130                 :            :   const Poly& symPoly(CoCoA::symbol s) const;
     131                 :            :   /** encode this term as a poly (caching) */
     132                 :            :   void encodeTerm(const Node& t);
     133                 :            :   /** encode this fact as a poly that must be zero (caching) */
     134                 :            :   void encodeFact(const Node& f);
     135                 :            : 
     136                 :            :   /** Which pass we're in. */
     137                 :            :   enum class Stage
     138                 :            :   {
     139                 :            :     /** collecting: variable, !=, bitsum */
     140                 :            :     Scan,
     141                 :            :     /** encoding terms */
     142                 :            :     Encode,
     143                 :            :   };
     144                 :            : 
     145                 :            :   // configuration
     146                 :            : 
     147                 :            :   /** the stage that we're in; initially scanning */
     148                 :            :   Stage d_stage{Stage::Scan};
     149                 :            : 
     150                 :            :   // populated during Stage::Scan
     151                 :            : 
     152                 :            :   /** all nodes scanned */
     153                 :            :   std::unordered_set<Node> d_scanned{};
     154                 :            :   /** all variables seen */
     155                 :            :   std::unordered_set<std::string> d_vars{};
     156                 :            :   /** map: bitsum term to its symbol */
     157                 :            :   std::unordered_map<Node, CoCoA::symbol> d_bitsumSyms{};
     158                 :            :   /** map: variable term to its symbol */
     159                 :            :   std::unordered_map<Node, CoCoA::symbol> d_varSyms{};
     160                 :            :   /** map: term (a != b) to the symbol for the inverse of (a - b) */
     161                 :            :   std::unordered_map<Node, CoCoA::symbol> d_diseqSyms{};
     162                 :            :   /** all symbols */
     163                 :            :   std::vector<CoCoA::symbol> d_syms{};
     164                 :            :   /** map: symbol name to polynomial */
     165                 :            :   std::unordered_map<std::string, Poly> d_symPolys{};
     166                 :            :   /** map: symbol name to term */
     167                 :            :   std::unordered_map<std::string, Node> d_symNodes{};
     168                 :            : 
     169                 :            :   // populated at the end of Stage::Scan
     170                 :            : 
     171                 :            :   /** the coefficient ring */
     172                 :            :   std::optional<CoCoA::ring> d_coeffRing{};
     173                 :            :   /** the polynomial ring */
     174                 :            :   std::optional<CoCoA::ring> d_polyRing{};
     175                 :            : 
     176                 :            :   // populated during Stage::Encode
     177                 :            : 
     178                 :            :   /** encoding cache */
     179                 :            :   std::unordered_map<Node, Poly> d_cache{};
     180                 :            :   /** polynomials that must be zero (except bitsums) */
     181                 :            :   std::vector<Poly> d_polys{};
     182                 :            :   /** bitsum polynomials that must be zero */
     183                 :            :   std::vector<Poly> d_bitsumPolys{};
     184                 :            :   /** polys to the facts that imply them */
     185                 :            :   std::unordered_map<std::string, Node> d_polyFacts{};
     186                 :            : };
     187                 :            : 
     188                 :            : }  // namespace ff
     189                 :            : }  // namespace theory
     190                 :            : }  // namespace cvc5::internal
     191                 :            : 
     192                 :            : #endif /* CVC5__THEORY__FF__COCOA_H */
     193                 :            : 
     194                 :            : #endif /* CVC5_USE_COCOA */

Generated by: LCOV version 1.14