LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/quantifiers - quant_conflict_find.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 16 16 100.0 %
Date: 2026-07-01 10:35:08 Functions: 13 13 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                 :            :  * Quantifiers conflict find class.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "cvc5_private.h"
      14                 :            : 
      15                 :            : #ifndef QUANT_CONFLICT_FIND
      16                 :            : #define QUANT_CONFLICT_FIND
      17                 :            : 
      18                 :            : #include <ostream>
      19                 :            : #include <vector>
      20                 :            : 
      21                 :            : #include "context/cdhashmap.h"
      22                 :            : #include "context/cdlist.h"
      23                 :            : #include "expr/node_trie.h"
      24                 :            : #include "theory/quantifiers/inst_match.h"
      25                 :            : #include "theory/quantifiers/quant_module.h"
      26                 :            : 
      27                 :            : namespace cvc5::internal {
      28                 :            : namespace theory {
      29                 :            : namespace quantifiers {
      30                 :            : 
      31                 :            : class QuantConflictFind;
      32                 :            : class QuantInfo;
      33                 :            : 
      34                 :            : // match generator
      35                 :            : class MatchGen : protected EnvObj
      36                 :            : {
      37                 :            :   friend class QuantInfo;
      38                 :            : 
      39                 :            :  public:
      40                 :            :   MatchGen(Env& env,
      41                 :            :            QuantConflictFind* p,
      42                 :            :            QuantInfo* qi,
      43                 :            :            Node n,
      44                 :            :            bool isVar = false);
      45                 :            : 
      46                 :            :   // type of the match generator
      47                 :            :   enum
      48                 :            :   {
      49                 :            :     typ_invalid,
      50                 :            :     typ_ground,
      51                 :            :     typ_pred,
      52                 :            :     typ_eq,
      53                 :            :     typ_formula,
      54                 :            :     typ_var,
      55                 :            :     typ_bool_var,
      56                 :            :     typ_tconstraint,
      57                 :            :     typ_tsym,
      58                 :            :   };
      59                 :            :   void debugPrintType(const char* c, short typ);
      60                 :            : 
      61                 :            :   bool d_tgt;
      62                 :            :   bool d_tgt_orig;
      63                 :            :   bool d_wasSet;
      64                 :            :   Node d_n;
      65                 :            :   std::vector<std::unique_ptr<MatchGen>> d_children;
      66                 :            :   short d_type;
      67                 :            :   bool d_type_not;
      68                 :            :   /** reset round
      69                 :            :    *
      70                 :            :    * Called once at the beginning of each full/last-call effort, prior to
      71                 :            :    * processing this match generator. This method returns false if the reset
      72                 :            :    * failed, e.g. if a conflict was encountered during term indexing.
      73                 :            :    */
      74                 :            :   bool reset_round();
      75                 :            :   void reset(bool tgt);
      76                 :            :   bool getNextMatch();
      77                 :     860128 :   bool isValid() const { return d_type != typ_invalid; }
      78                 :            :   void setInvalid();
      79                 :      95290 :   Node getNode() const { return d_n; }
      80                 :            : 
      81                 :            :   // is this term treated as UF application?
      82                 :            :   static bool isHandledBoolConnective(TNode n);
      83                 :            :   static bool isHandledUfTerm(TNode n);
      84                 :            :   // can this node be handled by the algorithm
      85                 :            :   static bool isHandled(TNode n);
      86                 :            : 
      87                 :            :  private:
      88                 :            :   // determine variable order
      89                 :            :   void determineVariableOrder(std::vector<size_t>& bvars);
      90                 :            :   void collectBoundVar(Node n,
      91                 :            :                        std::vector<int>& cbvars,
      92                 :            :                        std::map<Node, bool>& visited,
      93                 :            :                        bool& hasNested);
      94                 :     384313 :   size_t getNumChildren() const { return d_children.size(); }
      95                 :    1946196 :   MatchGen* getChild(size_t i) const
      96                 :            :   {
      97                 :    1946196 :     return d_children[d_children_order[i]].get();
      98                 :            :   }
      99                 :            :   bool doMatching();
     100                 :            :   /** The parent who owns this class */
     101                 :            :   QuantConflictFind* d_parent;
     102                 :            :   /** Quantifier info of the parent */
     103                 :            :   QuantInfo* d_qi;
     104                 :            :   // current children information
     105                 :            :   int d_child_counter;
     106                 :            :   bool d_use_children;
     107                 :            :   // children of this object
     108                 :            :   std::vector<size_t> d_children_order;
     109                 :            :   // current matching information
     110                 :            :   std::vector<TNodeTrie*> d_qn;
     111                 :            :   std::vector<std::map<TNode, TNodeTrie>::iterator> d_qni;
     112                 :            :   // for matching : each index is either a variable or a ground term
     113                 :            :   size_t d_qni_size;
     114                 :            :   std::map<size_t, size_t> d_qni_var_num;
     115                 :            :   std::map<size_t, TNode> d_qni_gterm;
     116                 :            :   std::map<size_t, size_t> d_qni_bound;
     117                 :            :   std::vector<size_t> d_qni_bound_except;
     118                 :            :   std::map<size_t, TNode> d_qni_bound_cons;
     119                 :            :   std::map<size_t, size_t> d_qni_bound_cons_var;
     120                 :            :   std::map<size_t, size_t>::iterator d_binding_it;
     121                 :            :   bool d_matched_basis;
     122                 :            :   bool d_binding;
     123                 :            :   // int getVarBindingVar();
     124                 :            :   std::map<size_t, Node> d_ground_eval;
     125                 :            : };
     126                 :            : 
     127                 :            : // info for quantifiers
     128                 :            : class QuantInfo : protected EnvObj
     129                 :            : {
     130                 :            :  public:
     131                 :            :   using VarMgMap = std::map<size_t, std::unique_ptr<MatchGen>>;
     132                 :            :   QuantInfo(Env& env,
     133                 :            :             QuantifiersState& qs,
     134                 :            :             TermRegistry& tr,
     135                 :            :             QuantConflictFind* p,
     136                 :            :             Node q);
     137                 :            :   ~QuantInfo();
     138                 :            :   /** get quantified formula */
     139                 :            :   Node getQuantifiedFormula() const;
     140                 :            :   bool isBaseMatchComplete();
     141                 :            :   /** Get quantifiers inference manager */
     142                 :            :   QuantifiersInferenceManager& getInferenceManager();
     143                 :            :   std::vector<TNode> d_vars;
     144                 :            :   std::vector<TypeNode> d_var_types;
     145                 :            :   std::map<TNode, size_t> d_var_num;
     146                 :            :   std::vector<size_t> d_tsym_vars;
     147                 :            :   int getVarNum(TNode v) const;
     148                 :     606225 :   bool isVar(TNode v) const { return d_var_num.find(v) != d_var_num.end(); }
     149                 :    2418907 :   size_t getNumVars() const { return d_vars.size(); }
     150                 :       2735 :   TNode getVar(size_t i) const { return d_vars[i]; }
     151                 :    7902718 :   VarMgMap::const_iterator var_mg_find(size_t i) const
     152                 :            :   {
     153                 :    7902718 :     return d_var_mg.find(i);
     154                 :            :   }
     155                 :    5625621 :   VarMgMap::const_iterator var_mg_end() const { return d_var_mg.end(); }
     156                 :    1219653 :   bool containsVarMg(size_t i) const { return var_mg_find(i) != var_mg_end(); }
     157                 :     435507 :   bool matchGeneratorIsValid() const { return d_mg->isValid(); }
     158                 :     303096 :   bool getNextMatch() { return d_mg->getNextMatch(); }
     159                 :            :   bool reset_round();
     160                 :            :   size_t getCurrentRepVar(size_t v);
     161                 :            :   TNode getCurrentValue(TNode n);
     162                 :            :   TNode getCurrentExpValue(TNode n);
     163                 :            :   bool getCurrentCanBeEqual(size_t v, TNode n, bool chDiseq = false);
     164                 :            :   int addConstraint(size_t v, TNode n, bool polarity);
     165                 :            :   int addConstraint(size_t v, TNode n, int vn, bool polarity, bool doRemove);
     166                 :            :   bool setMatch(size_t v, TNode n, bool isGroundRep, bool isGround);
     167                 :            :   void unsetMatch(size_t v);
     168                 :            :   bool isMatchSpurious();
     169                 :            :   bool isTConstraintSpurious(const std::vector<Node>& terms);
     170                 :            :   bool entailmentTest(Node lit, bool chEnt = true);
     171                 :            :   bool completeMatch(std::vector<size_t>& assigned, bool doContinue = false);
     172                 :            :   void revertMatch(const std::vector<size_t>& assigned);
     173                 :            :   void debugPrintMatch(const char* c) const;
     174                 :            :   bool isConstrainedVar(size_t v);
     175                 :            :   void getMatch(std::vector<Node>& terms);
     176                 :            : 
     177                 :            :   // current constraints
     178                 :            :   std::vector<TNode> d_match;
     179                 :            :   std::vector<TNode> d_match_term;
     180                 :            :   std::map<size_t, std::map<TNode, size_t>> d_curr_var_deq;
     181                 :            :   std::map<Node, bool> d_tconstraints;
     182                 :            : 
     183                 :            :  private:
     184                 :            :   void registerNode(Node n, bool hasPol, bool pol, bool beneathQuant = false);
     185                 :            :   void flatten(Node n, bool beneathQuant);
     186                 :            :   void getPropagateVars(std::vector<TNode>& vars,
     187                 :            :                         TNode n,
     188                 :            :                         bool pol,
     189                 :            :                         std::map<TNode, bool>& visited);
     190                 :            :   /** Reference to the quantifiers state */
     191                 :            :   QuantifiersState& d_qs;
     192                 :            :   /** The parent who owns this class */
     193                 :            :   QuantConflictFind* d_parent;
     194                 :            :   /** An instantiation match */
     195                 :            :   InstMatch d_instMatch;
     196                 :            :   std::unique_ptr<MatchGen> d_mg;
     197                 :            :   Node d_q;
     198                 :            :   VarMgMap d_var_mg;
     199                 :            :   // for completing match
     200                 :            :   std::vector<size_t> d_unassigned;
     201                 :            :   std::vector<TypeNode> d_unassigned_tn;
     202                 :            :   size_t d_unassigned_nvar;
     203                 :            :   size_t d_una_index;
     204                 :            :   std::vector<int> d_una_eqc_count;
     205                 :            :   // optimization: track which arguments variables appear under UF terms in
     206                 :            :   std::map<size_t, std::map<TNode, std::vector<size_t>>> d_var_rel_dom;
     207                 :            :   // optimization: number of variables set, to track when we can stop
     208                 :            :   std::unordered_set<size_t> d_vars_set;
     209                 :            :   std::vector<Node> d_extra_var;
     210                 :            : };
     211                 :            : 
     212                 :            : class QuantConflictFind : public QuantifiersModule
     213                 :            : {
     214                 :            :   friend class MatchGen;
     215                 :            :   friend class QuantInfo;
     216                 :            : 
     217                 :            :  public:
     218                 :            :   QuantConflictFind(Env& env,
     219                 :            :                     QuantifiersState& qs,
     220                 :            :                     QuantifiersInferenceManager& qim,
     221                 :            :                     QuantifiersRegistry& qr,
     222                 :            :                     TermRegistry& tr);
     223                 :            : 
     224                 :            :   /** register quantifier */
     225                 :            :   void registerQuantifier(Node q) override;
     226                 :            :   /** needs check */
     227                 :            :   bool needsCheck(Theory::Effort level) override;
     228                 :            :   /** reset round */
     229                 :            :   void reset_round(Theory::Effort level) override;
     230                 :            :   /** check
     231                 :            :    *
     232                 :            :    * This method attempts to construct a conflicting or propagating instance.
     233                 :            :    * If such an instance exists, then it makes a call to
     234                 :            :    * Instantiation::addInstantiation.
     235                 :            :    */
     236                 :            :   void check(Theory::Effort level, QEffort quant_e) override;
     237                 :            : 
     238                 :            :   /** statistics class */
     239                 :            :   class Statistics
     240                 :            :   {
     241                 :            :    public:
     242                 :            :     IntStat d_inst_rounds;
     243                 :            :     IntStat d_entailment_checks;
     244                 :            :     Statistics(StatisticsRegistry& sr);
     245                 :            :   };
     246                 :            :   Statistics d_statistics;
     247                 :            :   /** Identify this module */
     248                 :            :   std::string identify() const override;
     249                 :            :   /** is n a propagating instance?
     250                 :            :    *
     251                 :            :    * A propagating instance is any formula that consists of Boolean connectives,
     252                 :            :    * equality, quantified formulas, and terms that exist in the current
     253                 :            :    * context (those in the master equality engine).
     254                 :            :    *
     255                 :            :    * Notice the distinction that quantified formulas that do not appear in the
     256                 :            :    * current context are considered to be legal in propagating instances. This
     257                 :            :    * choice is significant for TPTP, where a net of ~200 benchmarks are gained
     258                 :            :    * due to this decision.
     259                 :            :    *
     260                 :            :    * Propagating instances are the second most useful kind of instantiation
     261                 :            :    * after conflicting instances and are used as a second effort in the
     262                 :            :    * algorithm performed by this class.
     263                 :            :    */
     264                 :            :   bool isPropagatingInstance(Node n) const;
     265                 :            : 
     266                 :            :   enum Effort : unsigned
     267                 :            :   {
     268                 :            :     EFFORT_CONFLICT,
     269                 :            :     EFFORT_PROP_EQ,
     270                 :            :     EFFORT_INVALID,
     271                 :            :   };
     272                 :            :   void setEffort(Effort e) { d_effort = e; }
     273                 :            : 
     274                 :     463847 :   bool atConflictEffort() const
     275                 :            :   {
     276                 :     463847 :     return d_effort == QuantConflictFind::EFFORT_CONFLICT;
     277                 :            :   }
     278                 :            : 
     279                 :            :   TNode getZero(TypeNode tn, Kind k);
     280                 :            : 
     281                 :            :  private:
     282                 :            :   /** check quantified formula
     283                 :            :    *
     284                 :            :    * This method is called by the above check method for each quantified
     285                 :            :    * formula q. It attempts to find a conflicting or propagating instance for
     286                 :            :    * q, depending on the effort level (d_effort).
     287                 :            :    *
     288                 :            :    * isConflict: this is set to true if we discovered a conflicting instance.
     289                 :            :    * This flag may be set instead of d_conflict if --qcf-all-conflict is true,
     290                 :            :    * in which we continuing adding all conflicts.
     291                 :            :    * addedLemmas: tracks the total number of lemmas added, and is incremented by
     292                 :            :    * this method when applicable.
     293                 :            :    */
     294                 :            :   void checkQuantifiedFormula(Node q, bool& isConflict, unsigned& addedLemmas);
     295                 :            :   void debugPrint(const char* c) const;
     296                 :            :   void debugPrintQuant(const char* c, Node q) const;
     297                 :            :   void debugPrintQuantBody(const char* c,
     298                 :            :                            Node q,
     299                 :            :                            Node n,
     300                 :            :                            bool doVarNum = true) const;
     301                 :            :   void setIrrelevantFunction(TNode f);
     302                 :            :   // for debugging
     303                 :            :   std::vector<Node> d_quants;
     304                 :            :   std::map<Node, size_t> d_quant_id;
     305                 :            :   /** Map from quantified formulas to their info class to compute instances */
     306                 :            :   std::map<Node, std::unique_ptr<QuantInfo>> d_qinfo;
     307                 :            :   /** Map from type -> list(eqc) of that type */
     308                 :            :   std::map<TypeNode, std::vector<TNode>> d_eqcs;
     309                 :            :   /** Zeros for (type, kind) pairs */
     310                 :            :   std::map<std::pair<TypeNode, Kind>, Node> d_zero;
     311                 :            :   // for storing nodes created during t-constraint solving (prevents memory
     312                 :            :   // leaks)
     313                 :            :   std::vector<Node> d_tempCache;
     314                 :            :   // optimization: list of quantifiers that depend on ground function
     315                 :            :   // applications
     316                 :            :   std::map<TNode, std::vector<Node>> d_func_rel_dom;
     317                 :            :   std::map<TNode, bool> d_irr_func;
     318                 :            :   std::map<Node, bool> d_irr_quant;
     319                 :            :   /** The current effort */
     320                 :            :   Effort d_effort;
     321                 :            : };
     322                 :            : 
     323                 :            : std::ostream& operator<<(std::ostream& os, const QuantConflictFind::Effort& e);
     324                 :            : 
     325                 :            : }  // namespace quantifiers
     326                 :            : }  // namespace theory
     327                 :            : }  // namespace cvc5::internal
     328                 :            : 
     329                 :            : #endif

Generated by: LCOV version 1.14