Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Andrew Reynolds, Andres Noetzli, Tianyi Liang 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 : : * Regular expression solver for the theory of strings. 14 : : */ 15 : : 16 : : #include "cvc5_private.h" 17 : : 18 : : #ifndef CVC5__THEORY__STRINGS__REGEXP_SOLVER_H 19 : : #define CVC5__THEORY__STRINGS__REGEXP_SOLVER_H 20 : : 21 : : #include <map> 22 : : 23 : : #include "context/cdhashset.h" 24 : : #include "context/cdlist.h" 25 : : #include "context/context.h" 26 : : #include "expr/node.h" 27 : : #include "smt/env_obj.h" 28 : : #include "theory/strings/extf_solver.h" 29 : : #include "theory/strings/inference_manager.h" 30 : : #include "theory/strings/regexp_operation.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/term_registry.h" 35 : : #include "util/string.h" 36 : : 37 : : namespace cvc5::internal { 38 : : namespace theory { 39 : : namespace strings { 40 : : 41 : : class RegExpSolver : protected EnvObj 42 : : { 43 : : typedef context::CDList<Node> NodeList; 44 : : typedef context::CDHashMap<Node, bool> NodeBoolMap; 45 : : typedef context::CDHashMap<Node, int> NodeIntMap; 46 : : typedef context::CDHashMap<Node, unsigned> NodeUIntMap; 47 : : typedef context::CDHashMap<Node, Node> NodeNodeMap; 48 : : typedef context::CDHashSet<Node> NodeSet; 49 : : 50 : : public: 51 : : RegExpSolver(Env& env, 52 : : SolverState& s, 53 : : InferenceManager& im, 54 : : TermRegistry& tr, 55 : : CoreSolver& cs, 56 : : ExtfSolver& es, 57 : : SequencesStatistics& stats); 58 : 51133 : ~RegExpSolver() {} 59 : : 60 : : /** check regular expression memberships 61 : : * 62 : : * This checks the satisfiability of all regular expression memberships 63 : : * of the form (not) s in R. We use various heuristic techniques based on 64 : : * unrolling, combined with techniques from Liang et al, "A Decision Procedure 65 : : * for Regular Membership and Length Constraints over Unbounded Strings", 66 : : * FroCoS 2015. 67 : : */ 68 : : void checkMemberships(Theory::Effort e); 69 : : /** 70 : : * Check regular expression memberships eagerly, before running the CAV 14 71 : : * procedure for word equations. Adds lemmas based on our strategy involving 72 : : * reductions or simplifications. 73 : : */ 74 : : void checkMembershipsEager(); 75 : : 76 : : private: 77 : : /** compute asserted memberships, store in d_assertedMems */ 78 : : void computeAssertedMemberships(); 79 : : /** Compute active extended terms of kind k, grouped by representative. */ 80 : : std::map<Node, std::vector<Node>> computeAssertions(Kind k) const; 81 : : /** 82 : : * Check inclusions, 83 : : * Assumes d_assertedMems has been computed. 84 : : */ 85 : : void checkInclusions(); 86 : : /** 87 : : * Check evaluations, which applies substitutions for normal forms to 88 : : * regular expression memberships and evaluates them, and also calls 89 : : * other methods (e.g. partial derivative computations) for the purposes 90 : : * of discovering conflictx. 91 : : * Assumes d_assertedMems has been computed. 92 : : */ 93 : : void checkEvaluations(); 94 : : /** 95 : : * Check unfold, which unfolds regular expression memberships based on the 96 : : * effort level. 97 : : * Assumes d_assertedMems has been computed. 98 : : */ 99 : : void checkUnfold(Theory::Effort effort); 100 : : /** 101 : : * Check memberships in equivalence class for regular expression 102 : : * inclusion. 103 : : * 104 : : * This method returns false if it discovered a conflict for this set of 105 : : * assertions, and true otherwise. It discovers a conflict e.g. if mems 106 : : * contains str.in.re(xi, Ri) and ~str.in.re(xj, Rj) and Rj includes Ri. 107 : : * 108 : : * @param mems Vector of memberships of the form: (~)str.in.re(x1, R1) 109 : : * ... (~)str.in.re(xn, Rn) where x1 = ... = xn in the 110 : : * current context. The function removes elements from this 111 : : * vector that were marked as reduced. 112 : : * @return False if a conflict was detected, true otherwise 113 : : */ 114 : : bool checkEqcInclusion(std::vector<Node>& mems); 115 : : 116 : : /** 117 : : * Check memberships for equivalence class. 118 : : * The vector mems is a vector of memberships of the form: 119 : : * (~) (x1 in R1 ) ... (~) (xn in Rn) 120 : : * where x1 = ... = xn in the current context. 121 : : * 122 : : * This method may add lemmas or conflicts via the inference manager. 123 : : * 124 : : * This method returns false if it discovered a conflict for this set of 125 : : * assertions, and true otherwise. It discovers a conflict e.g. if mems 126 : : * contains (xi in Ri) and (xj in Rj) and intersect(xi,xj) is empty. 127 : : */ 128 : : bool checkEqcIntersect(const std::vector<Node>& mems); 129 : : /** 130 : : * Return true if we should process regular expression unfoldings with 131 : : * the given polarity at the given effort. 132 : : */ 133 : : bool shouldUnfold(Theory::Effort e, bool pol) const; 134 : : /** 135 : : * Add the unfolding lemma for asserted regular expression membership 136 : : * assertion. Return true if a lemma was successfully sent to the inference 137 : : * manager. 138 : : */ 139 : : bool doUnfold(const Node& assertion); 140 : : // Constants 141 : : Node d_emptyString; 142 : : Node d_emptyRegexp; 143 : : Node d_true; 144 : : Node d_false; 145 : : /** The solver state of the parent of this object */ 146 : : SolverState& d_state; 147 : : /** the output channel of the parent of this object */ 148 : : InferenceManager& d_im; 149 : : /** reference to the core solver, used for certain queries */ 150 : : CoreSolver& d_csolver; 151 : : /** reference to the extended function solver of the parent */ 152 : : ExtfSolver& d_esolver; 153 : : /** Reference to the statistics for the theory of strings/sequences. */ 154 : : SequencesStatistics& d_statistics; 155 : : /** 156 : : * Check partial derivative 157 : : * 158 : : * Returns false if a lemma pertaining to checking the partial derivative 159 : : * of x in r was added. In this case, addedLemma is updated to true. 160 : : * 161 : : * The argument atom is the assertion that explains x in r, which is the 162 : : * normalized form of atom that may be modified using a substitution whose 163 : : * explanation is nf_exp. 164 : : */ 165 : : bool checkPDerivative(Node x, Node r, Node atom, std::vector<Node>& nf_exp); 166 : : cvc5::internal::String getHeadConst(Node x); 167 : : bool deriveRegExp(Node x, Node r, Node atom, std::vector<Node>& ant); 168 : : Node getNormalSymRegExp(Node r, std::vector<Node>& nf_exp); 169 : : /** regular expression operation module */ 170 : : RegExpOpr d_regexp_opr; 171 : : /** Asserted memberships, cached during a full effort check */ 172 : : std::map<Node, std::vector<Node>> d_assertedMems; 173 : : }; /* class TheoryStrings */ 174 : : 175 : : } // namespace strings 176 : : } // namespace theory 177 : : } // namespace cvc5::internal 178 : : 179 : : #endif /* CVC5__THEORY__STRINGS__THEORY_STRINGS_H */