LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/uf - symmetry_breaker.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 5 5 100.0 %
Date: 2025-01-29 12:48:36 Functions: 2 2 100.0 %
Branches: 1 2 50.0 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Morgan Deters, Liana Hadarean, Mathias Preiner
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2025 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                 :            :  * Implementation of algorithm suggested by Deharbe, Fontaine, Merz,
      14                 :            :  * and Paleo, "Exploiting symmetry in SMT problems," CADE 2011.
      15                 :            :  *
      16                 :            :  * From the paper:
      17                 :            :  *
      18                 :            :  * <pre>
      19                 :            :  *   \f$ P := guess\_permutations(\phi) \f$
      20                 :            :  *   foreach \f$ {c_0, ..., c_n} \in P \f$ do
      21                 :            :  *     if \f$ invariant\_by\_permutations(\phi, {c_0, ..., c_n}) \f$ then
      22                 :            :  *       T := \f$ select\_terms(\phi, {c_0, ..., c_n}) \f$
      23                 :            :  *       cts := \f$ \emptyset \f$
      24                 :            :  *       while T != \f$ \empty \wedge |cts| <= n \f$ do
      25                 :            :  *         \f$ t := select\_most\_promising\_term(T, \phi) \f$
      26                 :            :  *         \f$ T := T \setminus {t} \f$
      27                 :            :  *         cts := cts \f$ \cup used\_in(t, {c_0, ..., c_n}) \f$
      28                 :            :  *         let \f$ c \in {c_0, ..., c_n} \setminus cts \f$
      29                 :            :  *         cts := cts \f$ \cup {c} \f$
      30                 :            :  *         if cts != \f$ {c_0, ..., c_n} \f$ then
      31                 :            :  *           \f$ \phi := \phi \wedge ( \vee_{c_i \in cts} t = c_i ) \f$
      32                 :            :  *         end
      33                 :            :  *       end
      34                 :            :  *     end
      35                 :            :  *   end
      36                 :            :  *   return \f$ \phi \f$
      37                 :            :  * </pre>
      38                 :            :  */
      39                 :            : 
      40                 :            : #include "cvc5_private.h"
      41                 :            : 
      42                 :            : #ifndef CVC5__THEORY__UF__SYMMETRY_BREAKER_H
      43                 :            : #define CVC5__THEORY__UF__SYMMETRY_BREAKER_H
      44                 :            : 
      45                 :            : #include <iostream>
      46                 :            : #include <list>
      47                 :            : #include <unordered_map>
      48                 :            : #include <vector>
      49                 :            : 
      50                 :            : #include "context/cdlist.h"
      51                 :            : #include "context/context.h"
      52                 :            : #include "expr/node.h"
      53                 :            : #include "expr/node_builder.h"
      54                 :            : #include "smt/env_obj.h"
      55                 :            : #include "util/statistics_stats.h"
      56                 :            : 
      57                 :            : namespace cvc5::internal {
      58                 :            : namespace theory {
      59                 :            : namespace uf {
      60                 :            : 
      61                 :            : class SymmetryBreaker : protected EnvObj, public context::ContextNotifyObj
      62                 :            : {
      63                 :            :   class Template {
      64                 :            :     Node d_template;
      65                 :            :     NodeBuilder d_assertions;
      66                 :            :     std::unordered_map<TNode, std::set<TNode>> d_sets;
      67                 :            :     std::unordered_map<TNode, TNode> d_reps;
      68                 :            : 
      69                 :            :     TNode find(TNode n);
      70                 :            :     bool matchRecursive(TNode t, TNode n);
      71                 :            : 
      72                 :            :   public:
      73                 :            :    Template(NodeManager* nm);
      74                 :            :    bool match(TNode n);
      75                 :      91906 :    std::unordered_map<TNode, std::set<TNode>>& partitions() { return d_sets; }
      76                 :            :    Node assertions()
      77                 :            :    {
      78                 :            :      switch (d_assertions.getNumChildren())
      79                 :            :      {
      80                 :            :        case 0: return Node::null();
      81                 :            :        case 1: return d_assertions[0];
      82                 :            :        default: return Node(d_assertions);
      83                 :            :      }
      84                 :            :     }
      85                 :            :     void reset();
      86                 :            :   };/* class SymmetryBreaker::Template */
      87                 :            : 
      88                 :            : public:
      89                 :            : 
      90                 :            :   typedef std::set<TNode> Permutation;
      91                 :            :   typedef std::set<Permutation> Permutations;
      92                 :            :   typedef TNode Term;
      93                 :            :   typedef std::list<Term> Terms;
      94                 :            :   typedef std::set<Term> TermEq;
      95                 :            :   typedef std::unordered_map<Term, TermEq> TermEqs;
      96                 :            : 
      97                 :            :  private:
      98                 :            :   /**
      99                 :            :    * This class wasn't initially built to be incremental.  It should
     100                 :            :    * be attached to a UserContext so that it clears everything when
     101                 :            :    * a pop occurs.  This "assertionsToRerun" is a set of assertions to
     102                 :            :    * feed back through assertFormula() when we started getting things
     103                 :            :    * again.  It's not just a matter of effectiveness, but also soundness;
     104                 :            :    * if some assertions (still in scope) are not seen by a symmetry-breaking
     105                 :            :    * round, then some symmetries that don't actually exist might be broken,
     106                 :            :    * leading to unsound results!
     107                 :            :    */
     108                 :            :   context::CDList<Node> d_assertionsToRerun;
     109                 :            :   bool d_rerunningAssertions;
     110                 :            : 
     111                 :            :   std::vector<Node> d_phi;
     112                 :            :   std::set<TNode> d_phiSet;
     113                 :            :   Permutations d_permutations;
     114                 :            :   Terms d_terms;
     115                 :            :   Template d_template;
     116                 :            :   std::unordered_map<Node, Node> d_normalizationCache;
     117                 :            :   TermEqs d_termEqs;
     118                 :            :   TermEqs d_termEqsOnly;
     119                 :            : 
     120                 :            :   void clear();
     121                 :            :   void rerunAssertionsIfNecessary();
     122                 :            : 
     123                 :            :   void guessPermutations();
     124                 :            :   bool invariantByPermutations(const Permutation& p);
     125                 :            :   void selectTerms(const Permutation& p);
     126                 :            :   Terms::iterator selectMostPromisingTerm(Terms& terms);
     127                 :            :   void insertUsedIn(Term term, const Permutation& p, std::set<Node>& cts);
     128                 :            :   Node normInternal(TNode phi, size_t level);
     129                 :            :   Node norm(TNode n);
     130                 :            : 
     131                 :            :   std::string d_name;
     132                 :            :   
     133                 :            :   // === STATISTICS ===
     134                 :            :   /** number of new clauses that come from the SymmetryBreaker */
     135                 :            :   struct Statistics {
     136                 :            :     /** number of new clauses that come from the SymmetryBreaker */
     137                 :            :     IntStat d_clauses;
     138                 :            :     IntStat d_units;
     139                 :            :     /** number of potential permutation sets we found */
     140                 :            :     IntStat d_permutationSetsConsidered;
     141                 :            :     /** number of invariant permutation sets we found */
     142                 :            :     IntStat d_permutationSetsInvariant;
     143                 :            :     /** time spent in invariantByPermutations() */
     144                 :            :     TimerStat d_invariantByPermutationsTimer;
     145                 :            :     /** time spent in selectTerms() */
     146                 :            :     TimerStat d_selectTermsTimer;
     147                 :            :     /** time spent in initial round of normalization */
     148                 :            :     TimerStat d_initNormalizationTimer;
     149                 :            : 
     150                 :            :     Statistics(StatisticsRegistry& sr, const std::string& name);
     151                 :            :   };
     152                 :            : 
     153                 :            :   Statistics d_stats;
     154                 :            : 
     155                 :            :  protected:
     156                 :      60069 :   void contextNotifyPop() override
     157                 :            :   {
     158         [ +  - ]:      60069 :     Trace("ufsymm") << "UFSYMM: clearing state due to pop" << std::endl;
     159                 :      60069 :     clear();
     160                 :      60069 :   }
     161                 :            : 
     162                 :            :  public:
     163                 :            :   SymmetryBreaker(Env& env, std::string name = "");
     164                 :            : 
     165                 :            :   void assertFormula(TNode phi);
     166                 :            :   void apply(std::vector<Node>& newClauses);
     167                 :            : 
     168                 :            : }; /* class SymmetryBreaker */
     169                 :            : 
     170                 :            : }  // namespace uf
     171                 :            : }  // namespace theory
     172                 :            : 
     173                 :            : std::ostream& operator<<(
     174                 :            :     std::ostream& out,
     175                 :            :     const cvc5::internal::theory::uf::SymmetryBreaker::Permutation& p);
     176                 :            : 
     177                 :            : }  // namespace cvc5::internal
     178                 :            : 
     179                 :            : #endif /* CVC5__THEORY__UF__SYMMETRY_BREAKER_H */

Generated by: LCOV version 1.14