LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/strings - extf_solver.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2 2 100.0 %
Date: 2026-01-22 12:22:00 Functions: 2 2 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Andrew Reynolds, Andres Noetzli, Aina Niemetz
       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                 :            :  * Solver for extended functions of theory of strings.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "cvc5_private.h"
      17                 :            : 
      18                 :            : #ifndef CVC5__THEORY__STRINGS__EXTF_SOLVER_H
      19                 :            : #define CVC5__THEORY__STRINGS__EXTF_SOLVER_H
      20                 :            : 
      21                 :            : #include <map>
      22                 :            : #include <vector>
      23                 :            : 
      24                 :            : #include "context/cdo.h"
      25                 :            : #include "expr/node.h"
      26                 :            : #include "smt/env_obj.h"
      27                 :            : #include "theory/ext_theory.h"
      28                 :            : #include "theory/strings/base_solver.h"
      29                 :            : #include "theory/strings/core_solver.h"
      30                 :            : #include "theory/strings/inference_manager.h"
      31                 :            : #include "theory/strings/sequences_stats.h"
      32                 :            : #include "theory/strings/skolem_cache.h"
      33                 :            : #include "theory/strings/solver_state.h"
      34                 :            : #include "theory/strings/strings_rewriter.h"
      35                 :            : #include "theory/strings/theory_strings_preprocess.h"
      36                 :            : 
      37                 :            : namespace cvc5::internal {
      38                 :            : namespace theory {
      39                 :            : namespace strings {
      40                 :            : 
      41                 :            : /**
      42                 :            :  * Non-static information about an extended function t. This information is
      43                 :            :  * constructed and used during the check extended function evaluation
      44                 :            :  * inference schema.
      45                 :            :  *
      46                 :            :  * In the following, we refer to the "context-dependent simplified form"
      47                 :            :  * of a term t to be the result of rewriting t * sigma, where sigma is a
      48                 :            :  * derivable substitution in the current context. For example, the
      49                 :            :  * context-depdendent simplified form of contains( x++y, "a" ) given
      50                 :            :  * sigma = { x -> "" } is contains(y,"a").
      51                 :            :  */
      52                 :            : class ExtfInfoTmp
      53                 :            : {
      54                 :            :  public:
      55                 :     844928 :   ExtfInfoTmp() : d_modelActive(true) {}
      56                 :            :   /**
      57                 :            :    * If s is in d_ctn[true] (resp. d_ctn[false]), then contains( t, s )
      58                 :            :    * (resp. ~contains( t, s )) holds in the current context. The vector
      59                 :            :    * d_ctnFrom is the explanation for why this holds. For example,
      60                 :            :    * if d_ctn[false][i] is "A", then d_ctnFrom[false][i] might be
      61                 :            :    * t = x ++ y AND x = "" AND y = "B".
      62                 :            :    */
      63                 :            :   std::map<bool, std::vector<Node> > d_ctn;
      64                 :            :   std::map<bool, std::vector<Node> > d_ctnFrom;
      65                 :            :   /**
      66                 :            :    * The constant that t is entailed to be equal to, or null if none exist.
      67                 :            :    */
      68                 :            :   Node d_const;
      69                 :            :   /**
      70                 :            :    * The explanation for why t is equal to its context-dependent simplified
      71                 :            :    * form.
      72                 :            :    */
      73                 :            :   std::vector<Node> d_initExp;
      74                 :            :   std::vector<Node> d_exp;
      75                 :            :   /** This flag is false if t is reduced in the model. */
      76                 :            :   bool d_modelActive;
      77                 :            : };
      78                 :            : 
      79                 :            : /**
      80                 :            :  * Extended function solver for the theory of strings. This manages extended
      81                 :            :  * functions for the theory of strings using a combination of context-dependent
      82                 :            :  * simplification (Reynolds et al CAV 2017) and lazy reductions.
      83                 :            :  */
      84                 :            : class ExtfSolver : public InferSideEffectProcess, protected EnvObj
      85                 :            : {
      86                 :            :   typedef context::CDHashSet<Node> NodeSet;
      87                 :            : 
      88                 :            :  public:
      89                 :            :   ExtfSolver(Env& env,
      90                 :            :              SolverState& s,
      91                 :            :              InferenceManager& im,
      92                 :            :              TermRegistry& tr,
      93                 :            :              StringsRewriter& rewriter,
      94                 :            :              BaseSolver& bs,
      95                 :            :              CoreSolver& cs,
      96                 :            :              ExtTheory& et,
      97                 :            :              SequencesStatistics& statistics);
      98                 :            :   ~ExtfSolver();
      99                 :            :   /** check extended functions evaluation
     100                 :            :    *
     101                 :            :    * This applies "context-dependent simplification" for all active extended
     102                 :            :    * function terms in this SAT context. This infers facts of the form:
     103                 :            :    *   x = c => f( t1 ... tn ) = c'
     104                 :            :    * where the rewritten form of f( t1...tn ) { x |-> c } is c', and x = c
     105                 :            :    * is a (tuple of) equalities that are asserted in this SAT context, and
     106                 :            :    * f( t1 ... tn ) is a term from this SAT context.
     107                 :            :    *
     108                 :            :    * For more details, this is steps 4 when effort=0 and step 6 when
     109                 :            :    * effort=1 from Strategy 1 in Reynolds et al, "Scaling up DPLL(T) String
     110                 :            :    * Solvers using Context-Dependent Simplification", CAV 2017. When called with
     111                 :            :    * effort=3, we apply context-dependent simplification based on model values.
     112                 :            :    */
     113                 :            :   void checkExtfEval(int effort);
     114                 :            :   /** check extended function reductions
     115                 :            :    *
     116                 :            :    * This adds "reduction" lemmas for each active extended function in this SAT
     117                 :            :    * context. These are generally lemmas of the form:
     118                 :            :    *   F[t1...tn,k] ^ f( t1 ... tn ) = k
     119                 :            :    * where f( t1 ... tn ) is an active extended function, k is a fresh constant
     120                 :            :    * and F is a formula that constrains k based on the definition of f.
     121                 :            :    *
     122                 :            :    * For more details, this is step 7 from Strategy 1 in Reynolds et al,
     123                 :            :    * CAV 2017. We stratify this in practice based on the effort level,
     124                 :            :    * where for instance, we reduce negatively asserted str.contains only
     125                 :            :    * at LAST_CALL effort. For more information see discussion of "model-based
     126                 :            :    * reductions" in Reynolds et al CAV 2022.
     127                 :            :    */
     128                 :            :   void checkExtfReductions(Theory::Effort e);
     129                 :            :   /**
     130                 :            :    * Check for extended functions that should be applied eagerly. This is
     131                 :            :    * called earlier in the search strategy of strings, in particular before
     132                 :            :    * the core equality reasoning is done.
     133                 :            :    */
     134                 :            :   void checkExtfReductionsEager();
     135                 :            :   /** get preprocess module */
     136                 :            :   StringsPreprocess* getPreprocess() { return &d_preproc; }
     137                 :            : 
     138                 :            :   /**
     139                 :            :    * Get the current substitution for term n.
     140                 :            :    *
     141                 :            :    * This method returns a term that n is currently equal to in the current
     142                 :            :    * context. It updates exp to contain an explanation of why it is currently
     143                 :            :    * equal to that term.
     144                 :            :    *
     145                 :            :    * The argument effort determines what kind of term to return, either
     146                 :            :    * a constant in the equivalence class of n (effort=0), the normal form of
     147                 :            :    * n (effort=1,2) or the model value of n (effort>=3). The latter is only
     148                 :            :    * valid at LAST_CALL effort. If a term of the above form cannot be returned,
     149                 :            :    * then n itself is returned.
     150                 :            :    */
     151                 :            :   Node getCurrentSubstitutionFor(int effort, Node n, std::vector<Node>& exp);
     152                 :            :   /** get mapping from extended functions to their information
     153                 :            :    *
     154                 :            :    * This information is valid during a full effort check after a call to
     155                 :            :    * checkExtfEval.
     156                 :            :    */
     157                 :            :   const std::map<Node, ExtfInfoTmp>& getInfo() const;
     158                 :            :   //---------------------------------- information about ExtTheory
     159                 :            :   /** Are there any active extended functions? */
     160                 :            :   bool hasExtendedFunctions() const;
     161                 :            :   /**
     162                 :            :    * Get the function applications of kind k that are active in the current
     163                 :            :    * context (see ExtTheory::getActive).
     164                 :            :    */
     165                 :            :   std::vector<Node> getActive(Kind k) const;
     166                 :            :   /**
     167                 :            :    * Return true if n is active in the model. If this method returns false,
     168                 :            :    * then n is already satisfied in the model (its value in the model is
     169                 :            :    * the same as its representative in the equality engine).
     170                 :            :    */
     171                 :            :   bool isActiveInModel(Node n) const;
     172                 :            :   /**
     173                 :            :    * @return The relevant active terms. This method retrieves the relevant
     174                 :            :    * terms from the term registry and filters out inactive terms.
     175                 :            :    *
     176                 :            :    * Note that the set of active terms is not a subset of the relevant terms
     177                 :            :    * since active terms may include preregistered terms that don't appear
     178                 :            :    * in any current assertions.
     179                 :            :    */
     180                 :            :   std::vector<Node> getRelevantActive() const;
     181                 :            :   //---------------------------------- end information about ExtTheory
     182                 :            :   /**
     183                 :            :    * Print the relevant information regarding why we have a model, return as a
     184                 :            :    * string.
     185                 :            :    */
     186                 :            :   std::string debugPrintModel();
     187                 :            : 
     188                 :            :   /**
     189                 :            :    * Is extended function (or regular expression membership) reduced? Note that
     190                 :            :    * if n has Boolean type, our reductions are dependent upon the polarity of n,
     191                 :            :    * in which case n may be the negation of an extended function. For
     192                 :            :    * example, (not (str.in_re x R)) indicates that we have reduced
     193                 :            :    * (str.in_re x R) based on its negative unfolding.
     194                 :            :    */
     195                 :            :   bool isReduced(const Node& n) const;
     196                 :            :   /**
     197                 :            :    * Mark that extended function (or regular expression membership) n has been
     198                 :            :    * reduced. Like above, n could be a negation of an extended function of
     199                 :            :    * Boolean type.
     200                 :            :    */
     201                 :            :   void markReduced(const Node& n);
     202                 :            : 
     203                 :            :   /** Called when ii is ready to be processed as a fact */
     204                 :            :   void processFact(InferInfo& ii, ProofGenerator*& pg) override;
     205                 :            :   /** Called when ii is ready to be processed as a lemma */
     206                 :            :   TrustNode processLemma(InferInfo& ii, LemmaProperty& p) override;
     207                 :            : 
     208                 :            :  private:
     209                 :            :   /**
     210                 :            :    * Helper method for checkExtfReductions / maybeHasCandidateModel, returns
     211                 :            :    * true if a reduction lemma was sent if doSend = true, or would have been
     212                 :            :    * sent if doSend = false.
     213                 :            :    */
     214                 :            :   bool checkExtfReductionsInternal(int effort, bool doSend);
     215                 :            :   /**
     216                 :            :    * Determines if n should be reduced based on the effort level.
     217                 :            :    *
     218                 :            :    * @param effort the effort level
     219                 :            :    * @param n the term to reduce
     220                 :            :    * @param pol polarity of n, where 1 true, -1 false, 0 neither
     221                 :            :    */
     222                 :            :   bool shouldDoReduction(int effort, Node n, int pol);
     223                 :            :   /** do reduction
     224                 :            :    *
     225                 :            :    * This is called when an extended function application n is not able to be
     226                 :            :    * simplified by context-depdendent simplification, and we are resorting to
     227                 :            :    * expanding n to its full semantics via a reduction. This method returns
     228                 :            :    * true if it successfully reduced n by some reduction. If so, it either
     229                 :            :    * caches that the reduction lemma was sent, or marks n as reduced in this
     230                 :            :    * SAT-context. The argument effort has the same meaning as in
     231                 :            :    * checkExtfReductions.
     232                 :            :    *
     233                 :            :    * @param n the term to reduce
     234                 :            :    * @param pol polarity of n, where 1 true, -1 false, 0 neither
     235                 :            :    */
     236                 :            :   void doReduction(Node n, int pol);
     237                 :            :   /** check extended function inferences
     238                 :            :    *
     239                 :            :    * This function makes additional inferences for n that do not contribute
     240                 :            :    * to its reduction, but may help show a refutation.
     241                 :            :    *
     242                 :            :    * This function is called when the context-depdendent simplified form of
     243                 :            :    * n is nr. The argument "in" is the information object for n. The argument
     244                 :            :    * "effort" has the same meaning as the effort argument of checkExtfEval.
     245                 :            :    */
     246                 :            :   void checkExtfInference(Node n, Node nr, ExtfInfoTmp& in, int effort);
     247                 :            :   /** The solver state object */
     248                 :            :   SolverState& d_state;
     249                 :            :   /** The (custom) output channel of the theory of strings */
     250                 :            :   InferenceManager& d_im;
     251                 :            :   /** Reference to the term registry of theory of strings */
     252                 :            :   TermRegistry& d_termReg;
     253                 :            :   /** The theory rewriter for this theory. */
     254                 :            :   StringsRewriter& d_rewriter;
     255                 :            :   /** reference to the base solver, used for certain queries */
     256                 :            :   BaseSolver& d_bsolver;
     257                 :            :   /** reference to the core solver, used for certain queries */
     258                 :            :   CoreSolver& d_csolver;
     259                 :            :   /** the extended theory object for the theory of strings */
     260                 :            :   ExtTheory& d_extt;
     261                 :            :   /** Reference to the statistics for the theory of strings/sequences. */
     262                 :            :   SequencesStatistics& d_statistics;
     263                 :            :   /** preprocessing utility, for performing strings reductions */
     264                 :            :   StringsPreprocess d_preproc;
     265                 :            :   /** Common constants */
     266                 :            :   Node d_true;
     267                 :            :   Node d_false;
     268                 :            :   /** Empty vector */
     269                 :            :   std::vector<Node> d_emptyVec;
     270                 :            :   /** map extended functions to the above information */
     271                 :            :   std::map<Node, ExtfInfoTmp> d_extfInfoTmp;
     272                 :            :   /** map from reduced extended functions to their original */
     273                 :            :   std::map<Node, Node> d_extfToOrig;
     274                 :            :   /** any non-reduced extended functions exist? */
     275                 :            :   context::CDO<bool> d_hasExtf;
     276                 :            :   /** extended functions inferences cache */
     277                 :            :   NodeSet d_extfInferCache;
     278                 :            :   /** The set of extended functions we have sent reduction lemmas for */
     279                 :            :   NodeSet d_reduced;
     280                 :            :   /** Map from lemmas to the terms they justify the reduction of */
     281                 :            :   std::map<Node, Node> d_reductionWaitingMap;
     282                 :            : };
     283                 :            : 
     284                 :            : /** An extended theory callback */
     285                 :            : class StringsExtfCallback : public ExtTheoryCallback
     286                 :            : {
     287                 :            :  public:
     288                 :      50196 :   StringsExtfCallback() : d_esolver(nullptr) {}
     289                 :            :   /**
     290                 :            :    * Get current substitution based on the underlying extended function
     291                 :            :    * solver.
     292                 :            :    */
     293                 :            :   bool getCurrentSubstitution(int effort,
     294                 :            :                               const std::vector<Node>& vars,
     295                 :            :                               std::vector<Node>& subs,
     296                 :            :                               std::map<Node, std::vector<Node> >& exp) override;
     297                 :            :   /** The extended function solver */
     298                 :            :   ExtfSolver* d_esolver;
     299                 :            : };
     300                 :            : 
     301                 :            : }  // namespace strings
     302                 :            : }  // namespace theory
     303                 :            : }  // namespace cvc5::internal
     304                 :            : 
     305                 :            : #endif /* CVC5__THEORY__STRINGS__EXTF_SOLVER_H */

Generated by: LCOV version 1.14