LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/strings - theory_strings.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 30 30 100.0 %
Date: 2026-09-18 09:47:02 Functions: 7 7 100.0 %
Branches: 9 16 56.2 %

           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                 :            :  * Theory of strings.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "cvc5_private.h"
      14                 :            : 
      15                 :            : #ifndef CVC5__THEORY__STRINGS__THEORY_STRINGS_H
      16                 :            : #define CVC5__THEORY__STRINGS__THEORY_STRINGS_H
      17                 :            : 
      18                 :            : #include <climits>
      19                 :            : #include <deque>
      20                 :            : 
      21                 :            : #include "context/cdhashset.h"
      22                 :            : #include "context/cdlist.h"
      23                 :            : #include "expr/node_trie.h"
      24                 :            : #include "proof/trust_proof_generator.h"
      25                 :            : #include "theory/care_pair_argument_callback.h"
      26                 :            : #include "theory/ext_theory.h"
      27                 :            : #include "theory/strings/array_solver.h"
      28                 :            : #include "theory/strings/base_solver.h"
      29                 :            : #include "theory/strings/code_point_solver.h"
      30                 :            : #include "theory/strings/core_solver.h"
      31                 :            : #include "theory/strings/eager_solver.h"
      32                 :            : #include "theory/strings/extf_solver.h"
      33                 :            : #include "theory/strings/infer_info.h"
      34                 :            : #include "theory/strings/inference_manager.h"
      35                 :            : #include "theory/strings/model_cons_default.h"
      36                 :            : #include "theory/strings/normal_form.h"
      37                 :            : #include "theory/strings/proof_checker.h"
      38                 :            : #include "theory/strings/regexp_elim.h"
      39                 :            : #include "theory/strings/regexp_operation.h"
      40                 :            : #include "theory/strings/regexp_solver.h"
      41                 :            : #include "theory/strings/sequences_stats.h"
      42                 :            : #include "theory/strings/solver_state.h"
      43                 :            : #include "theory/strings/strategy.h"
      44                 :            : #include "theory/strings/strings_fmf.h"
      45                 :            : #include "theory/strings/strings_rewriter.h"
      46                 :            : #include "theory/strings/term_registry.h"
      47                 :            : #include "theory/theory.h"
      48                 :            : #include "theory/uf/equality_engine.h"
      49                 :            : 
      50                 :            : namespace cvc5::internal {
      51                 :            : namespace theory {
      52                 :            : namespace strings {
      53                 :            : 
      54                 :            : /**
      55                 :            :  * A theory solver for strings. At a high level, the solver implements
      56                 :            :  * techniques described in:
      57                 :            :  * - Liang et al, CAV 2014,
      58                 :            :  * - Reynolds et al, CAV 2017,
      59                 :            :  * - Reynolds et al, IJCAR 2020.
      60                 :            :  * Its rewriter is described in:
      61                 :            :  * - Reynolds et al, CAV 2019.
      62                 :            :  */
      63                 :            : class TheoryStrings : public Theory
      64                 :            : {
      65                 :            :   friend class InferenceManager;
      66                 :            :   typedef context::CDHashSet<Node> NodeSet;
      67                 :            :   typedef context::CDHashSet<TypeNode, std::hash<TypeNode>> TypeNodeSet;
      68                 :            : 
      69                 :            :  public:
      70                 :            :   TheoryStrings(Env& env, OutputChannel& out, Valuation valuation);
      71                 :            :   ~TheoryStrings();
      72                 :            :   //--------------------------------- initialization
      73                 :            :   /** get the official theory rewriter of this theory */
      74                 :            :   TheoryRewriter* getTheoryRewriter() override;
      75                 :            :   /** get the proof checker of this theory */
      76                 :            :   ProofRuleChecker* getProofChecker() override;
      77                 :            :   /**
      78                 :            :    * Returns true if we need an equality engine. If so, we initialize the
      79                 :            :    * information regarding how it should be setup. For details, see the
      80                 :            :    * documentation in Theory::needsEqualityEngine.
      81                 :            :    */
      82                 :            :   bool needsEqualityEngine(EeSetupInfo& esi) override;
      83                 :            :   /** finish initialization */
      84                 :            :   void finishInit() override;
      85                 :            :   //--------------------------------- end initialization
      86                 :            :   /** Identify this theory */
      87                 :            :   std::string identify() const override;
      88                 :            :   /** Explain */
      89                 :            :   TrustNode explain(TNode literal) override;
      90                 :            :   /** presolve */
      91                 :            :   void presolve() override;
      92                 :            :   /** preregister term */
      93                 :            :   void preRegisterTerm(TNode n) override;
      94                 :            :   //--------------------------------- standard check
      95                 :            :   /** Do we need a check call at last call effort? */
      96                 :            :   bool needsCheckLastEffort() override;
      97                 :            :   bool preNotifyFact(TNode atom,
      98                 :            :                      bool pol,
      99                 :            :                      TNode fact,
     100                 :            :                      bool isPrereg,
     101                 :            :                      bool isInternal) override;
     102                 :            :   void notifyFact(TNode atom, bool pol, TNode fact, bool isInternal) override;
     103                 :            :   /** Post-check, called after the fact queue of the theory is processed. */
     104                 :            :   void postCheck(Effort level) override;
     105                 :            :   //--------------------------------- end standard check
     106                 :            :   /** propagate method */
     107                 :            :   bool propagateLit(TNode literal);
     108                 :            :   /** Conflict when merging two constants */
     109                 :            :   void conflict(TNode a, TNode b);
     110                 :            :   /** called when a new equivalence class is created */
     111                 :            :   void eqNotifyNewClass(TNode t);
     112                 :            :   /** Called just after the merge of two equivalence classes */
     113                 :            :   void eqNotifyMerge(TNode t1, TNode t2);
     114                 :            :   /** preprocess rewrite */
     115                 :            :   TrustNode ppRewrite(TNode atom, std::vector<SkolemLemma>& lems) override;
     116                 :            :   TrustNode ppStaticRewrite(TNode atom) override;
     117                 :            :   /** Collect model values in m based on the relevant terms given by termSet */
     118                 :            :   bool collectModelValues(TheoryModel* m,
     119                 :            :                           const std::set<Node>& termSet) override;
     120                 :            : 
     121                 :            :  private:
     122                 :            :   /** NotifyClass for equality engine */
     123                 :            :   class NotifyClass : public eq::EqualityEngineNotify
     124                 :            :   {
     125                 :            :    public:
     126                 :      28896 :     NotifyClass(TheoryStrings& ts) : d_str(ts) {}
     127                 :     917939 :     bool eqNotifyTriggerPredicate(TNode predicate, bool value) override
     128                 :            :     {
     129         [ +  - ]:    1835878 :       Trace("strings") << "NotifyClass::eqNotifyTriggerPredicate(" << predicate
     130         [ -  - ]:     917939 :                        << ", " << (value ? "true" : "false") << ")"
     131                 :     917939 :                        << std::endl;
     132         [ +  + ]:     917939 :       if (value)
     133                 :            :       {
     134                 :     521884 :         return d_str.propagateLit(predicate);
     135                 :            :       }
     136                 :     396055 :       return d_str.propagateLit(predicate.notNode());
     137                 :            :     }
     138                 :    1084963 :     bool eqNotifyTriggerTermEquality(TheoryId tag,
     139                 :            :                                      TNode t1,
     140                 :            :                                      TNode t2,
     141                 :            :                                      bool value) override
     142                 :            :     {
     143         [ +  - ]:    2169926 :       Trace("strings") << "NotifyClass::eqNotifyTriggerTermMerge(" << tag
     144                 :    1084963 :                        << ", " << t1 << ", " << t2 << ")" << std::endl;
     145         [ +  + ]:    1084963 :       if (value)
     146                 :            :       {
     147                 :     805145 :         return d_str.propagateLit(t1.eqNode(t2));
     148                 :            :       }
     149                 :     279818 :       return d_str.propagateLit(t1.eqNode(t2).notNode());
     150                 :            :     }
     151                 :       3596 :     void eqNotifyConstantTermMerge(TNode t1, TNode t2) override
     152                 :            :     {
     153         [ +  - ]:       7192 :       Trace("strings") << "NotifyClass::eqNotifyConstantTermMerge(" << t1
     154                 :       3596 :                        << ", " << t2 << ")" << std::endl;
     155                 :       3596 :       d_str.conflict(t1, t2);
     156                 :       3596 :     }
     157                 :     284800 :     void eqNotifyNewClass(TNode t) override
     158                 :            :     {
     159         [ +  - ]:     284800 :       Trace("strings") << "NotifyClass::eqNotifyNewClass(" << t << std::endl;
     160                 :     284800 :       d_str.eqNotifyNewClass(t);
     161                 :     284800 :     }
     162                 :    2634137 :     void eqNotifyMerge(TNode t1, TNode t2) override
     163                 :            :     {
     164         [ +  - ]:    5268274 :       Trace("strings") << "NotifyClass::eqNotifyMerge(" << t1 << ", " << t2
     165                 :    2634137 :                        << std::endl;
     166                 :    2634137 :       d_str.eqNotifyMerge(t1, t2);
     167                 :    2634137 :     }
     168                 :     468987 :     void eqNotifyDisequal(CVC5_UNUSED TNode t1,
     169                 :            :                           CVC5_UNUSED TNode t2,
     170                 :            :                           CVC5_UNUSED TNode reason) override
     171                 :            :     {
     172                 :     468987 :     }
     173                 :            : 
     174                 :            :    private:
     175                 :            :     /** The theory of strings object to notify */
     176                 :            :     TheoryStrings& d_str;
     177                 :            :   }; /* class TheoryStrings::NotifyClass */
     178                 :            :   /** compute care graph */
     179                 :            :   void computeCareGraph() override;
     180                 :            :   /** notify shared term */
     181                 :            :   void notifySharedTerm(TNode n) override;
     182                 :            :   /** Collect model info for type tn
     183                 :            :    *
     184                 :            :    * Assigns model values (in m) to all relevant terms of the string-like type
     185                 :            :    * tn in the current context, which are stored in repSet[tn].
     186                 :            :    *
     187                 :            :    * @param tn The type to compute model values for
     188                 :            :    * @param toProcess Remaining types to compute model values for
     189                 :            :    * @param repSet A map of types to representatives of
     190                 :            :    * the equivalence classes of the given type
     191                 :            :    * @return false if a conflict is discovered while doing this assignment.
     192                 :            :    */
     193                 :            :   bool collectModelInfoType(
     194                 :            :       TypeNode tn,
     195                 :            :       std::unordered_set<TypeNode>& toProcess,
     196                 :            :       const std::map<TypeNode, std::unordered_set<Node>>& repSet,
     197                 :            :       TheoryModel* m);
     198                 :            : 
     199                 :            :   /** assert pending fact
     200                 :            :    *
     201                 :            :    * This asserts atom with polarity to the equality engine of this class,
     202                 :            :    * where exp is the explanation of why (~) atom holds.
     203                 :            :    *
     204                 :            :    * This call may trigger further initialization steps involving the terms
     205                 :            :    * of atom, including calls to registerTerm.
     206                 :            :    */
     207                 :            :   void assertPendingFact(Node atom, bool polarity, Node exp);
     208                 :            :   /**
     209                 :            :    * Turn a sequence constant into a skeleton specifying how to construct
     210                 :            :    * its value.
     211                 :            :    * In particular, this means that value:
     212                 :            :    *   (seq.++ (seq.unit 0) (seq.unit 1) (seq.unit 2))
     213                 :            :    * becomes:
     214                 :            :    *   (seq.++ (seq.unit k_0) (seq.unit k_1) (seq.unit k_2))
     215                 :            :    * where k_0, k_1, k_2 are fresh integer variables. These
     216                 :            :    * variables will be assigned values in the standard way by the
     217                 :            :    * model. This construction is necessary during model construction since the
     218                 :            :    * strings solver must constrain the length of the model of an equivalence
     219                 :            :    * class (e.g. in this case to length 3); moreover we cannot assign a concrete
     220                 :            :    * value since it may conflict with other skeletons we have assigned.
     221                 :            :    */
     222                 :            :   Node mkSkeletonFor(Node value);
     223                 :            :   /**
     224                 :            :    * Make the skeleton for the basis of constructing sequence r between
     225                 :            :    * indices currIndex (inclusive) and nextIndex (exclusive). For example, if
     226                 :            :    * currIndex = 2 and nextIndex = 5, then this returns:
     227                 :            :    *   (seq.++ (seq.unit k_{r,2}) (seq.unit k_{r,3}) (seq.unit k_{r,4}))
     228                 :            :    * where k_{r,2}, k_{r,3}, k_{r,4} are Skolem variables of the element type
     229                 :            :    * of r that are unique to the pairs (r,2), (r,3), (r,4). In other words,
     230                 :            :    * these Skolems abstractly represent the element at positions 2, 3, 4 in the
     231                 :            :    * model for r.
     232                 :            :    */
     233                 :            :   Node mkSkeletonFromBase(Node r, size_t currIndex, size_t nextIndex);
     234                 :            :   //-----------------------end inference steps
     235                 :            :   /** run the given inference step */
     236                 :            :   void runInferStep(InferStep s, Theory::Effort e, int effort);
     237                 :            :   /** run strategy for effort e */
     238                 :            :   void runStrategy(Theory::Effort e);
     239                 :            :   /** print strings equivalence classes for debugging */
     240                 :            :   std::string debugPrintStringsEqc();
     241                 :            :   /** Commonly used constants */
     242                 :            :   Node d_true;
     243                 :            :   Node d_false;
     244                 :            :   Node d_zero;
     245                 :            :   Node d_one;
     246                 :            :   Node d_neg_one;
     247                 :            :   /** The notify class */
     248                 :            :   NotifyClass d_notify;
     249                 :            :   /**
     250                 :            :    * Statistics for the theory of strings/sequences. All statistics for these
     251                 :            :    * theories is collected in this object.
     252                 :            :    */
     253                 :            :   SequencesStatistics d_statistics;
     254                 :            :   /** The solver state object */
     255                 :            :   SolverState d_state;
     256                 :            :   /** The term registry for this theory */
     257                 :            :   TermRegistry d_termReg;
     258                 :            :   /** An arithmetic entailment utility */
     259                 :            :   ArithEntail d_arithEntail;
     260                 :            :   /** A string entailment utility */
     261                 :            :   StringsEntail d_strEntail;
     262                 :            :   /** The theory rewriter for this theory. */
     263                 :            :   StringsRewriter d_rewriter;
     264                 :            :   /** The eager solver */
     265                 :            :   std::unique_ptr<EagerSolver> d_eagerSolver;
     266                 :            :   /** The extended theory callback */
     267                 :            :   StringsExtfCallback d_extTheoryCb;
     268                 :            :   /** The (custom) output channel of the theory of strings */
     269                 :            :   InferenceManager d_im;
     270                 :            :   /** Extended theory, responsible for context-dependent simplification. */
     271                 :            :   ExtTheory d_extTheory;
     272                 :            :   /** The proof rule checker */
     273                 :            :   StringProofRuleChecker d_checker;
     274                 :            :   /**
     275                 :            :    * The base solver, responsible for reasoning about congruent terms and
     276                 :            :    * inferring constants for equivalence classes.
     277                 :            :    */
     278                 :            :   BaseSolver d_bsolver;
     279                 :            :   /**
     280                 :            :    * The core solver, responsible for reasoning about string concatenation
     281                 :            :    * with length constraints.
     282                 :            :    */
     283                 :            :   CoreSolver d_csolver;
     284                 :            :   /**
     285                 :            :    * Extended function solver, responsible for reductions and simplifications
     286                 :            :    * involving extended string functions.
     287                 :            :    */
     288                 :            :   ExtfSolver d_esolver;
     289                 :            :   /** Code point solver */
     290                 :            :   CodePointSolver d_psolver;
     291                 :            :   /**
     292                 :            :    * The array solver, which implements specialized approaches for
     293                 :            :    * seq.nth/seq.update.
     294                 :            :    */
     295                 :            :   ArraySolver d_asolver;
     296                 :            :   /** regular expression solver module */
     297                 :            :   RegExpSolver d_rsolver;
     298                 :            :   /** regular expression elimination module */
     299                 :            :   RegExpElimination d_regexp_elim;
     300                 :            :   /** Strings finite model finding decision strategy */
     301                 :            :   StringsFmf d_stringsFmf;
     302                 :            :   /** Model constructor (default) */
     303                 :            :   ModelConsDefault d_mcd;
     304                 :            :   /** The representation of the strategy */
     305                 :            :   Strategy d_strat;
     306                 :            :   /**
     307                 :            :    * For model building, a counter on the number of abstract witness terms
     308                 :            :    * we have built, so that unique debug names can be assigned.
     309                 :            :    */
     310                 :            :   size_t d_absModelCounter;
     311                 :            :   /**
     312                 :            :    * For model building, a counter on the number of gaps constructed for
     313                 :            :    * string terms due to array reasoning. This is to allocate unique unspecified
     314                 :            :    * characters.
     315                 :            :    */
     316                 :            :   size_t d_strGapModelCounter;
     317                 :            :   /** The care pair argument callback, used for theory combination */
     318                 :            :   CarePairArgumentCallback d_cpacb;
     319                 :            :   /** For proof of ppStaticRewrite */
     320                 :            :   std::shared_ptr<TrustProofGenerator> d_psrewPg;
     321                 :            : }; /* class TheoryStrings */
     322                 :            : 
     323                 :            : }  // namespace strings
     324                 :            : }  // namespace theory
     325                 :            : }  // namespace cvc5::internal
     326                 :            : 
     327                 :            : #endif /* CVC5__THEORY__STRINGS__THEORY_STRINGS_H */

Generated by: LCOV version 1.14