1 /********************* */ 2 /*! \file term_database_sygus.h 3 ** \verbatim 4 ** Top contributors (to current version): 5 ** Andrew Reynolds, Andres Noetzli, Morgan Deters 6 ** This file is part of the CVC4 project. 7 ** Copyright (c) 2009-2019 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.\endverbatim 11 ** 12 ** \brief term database sygus class 13 **/ 14 15 #include "cvc4_private.h" 16 17 #ifndef __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_SYGUS_H 18 #define __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_SYGUS_H 19 20 #include <unordered_set> 21 22 #include "theory/evaluator.h" 23 #include "theory/quantifiers/extended_rewrite.h" 24 #include "theory/quantifiers/sygus/sygus_eval_unfold.h" 25 #include "theory/quantifiers/sygus/sygus_explain.h" 26 #include "theory/quantifiers/term_database.h" 27 28 namespace CVC4 { 29 namespace theory { 30 namespace quantifiers { 31 32 class SynthConjecture; 33 34 /** A trie indexed by types that assigns unique identifiers to nodes. */ 35 class TypeNodeIdTrie 36 { 37 public: 38 /** children of this node */ 39 std::map<TypeNode, TypeNodeIdTrie> d_children; 40 /** the data stored at this node */ 41 std::vector<Node> d_data; 42 /** add v to this trie, indexed by types */ 43 void add(Node v, std::vector<TypeNode>& types); 44 /** 45 * Assign each node in this trie an identifier such that 46 * assign[v1] = assign[v2] iff v1 and v2 are indexed by the same values. 47 */ 48 void assignIds(std::map<Node, unsigned>& assign, unsigned& idCount); 49 }; 50 51 /** role for registering an enumerator */ 52 enum EnumeratorRole 53 { 54 /** The enumerator populates a pool of terms (e.g. for PBE). */ 55 ROLE_ENUM_POOL, 56 /** The enumerator is the single solution of the problem. */ 57 ROLE_ENUM_SINGLE_SOLUTION, 58 /** 59 * The enumerator is part of the solution of the problem (e.g. multiple 60 * functions to synthesize). 61 */ 62 ROLE_ENUM_MULTI_SOLUTION, 63 /** The enumerator must satisfy some set of constraints */ 64 ROLE_ENUM_CONSTRAINED, 65 }; 66 std::ostream& operator<<(std::ostream& os, EnumeratorRole r); 67 68 // TODO :issue #1235 split and document this class 69 class TermDbSygus { 70 public: 71 TermDbSygus(context::Context* c, QuantifiersEngine* qe); ~TermDbSygus()72 ~TermDbSygus() {} 73 /** Reset this utility */ 74 bool reset(Theory::Effort e); 75 /** Identify this utility */ identify()76 std::string identify() const { return "TermDbSygus"; } 77 /** register the sygus type 78 * 79 * This initializes this database for sygus datatype type tn. This may 80 * throw an assertion failure if the sygus grammar has type errors. Otherwise, 81 * after registering a sygus type, the query functions in this class (such 82 * as sygusToBuiltinType, getKindConsNum, etc.) can be called for tn. 83 */ 84 void registerSygusType(TypeNode tn); 85 86 //------------------------------utilities 87 /** get the explanation utility */ getExplain()88 SygusExplain* getExplain() { return d_syexp.get(); } 89 /** get the extended rewrite utility */ getExtRewriter()90 ExtendedRewriter* getExtRewriter() { return d_ext_rw.get(); } 91 /** get the evaluator */ getEvaluator()92 Evaluator* getEvaluator() { return d_eval.get(); } 93 /** evaluation unfolding utility */ getEvalUnfold()94 SygusEvalUnfold* getEvalUnfold() { return d_eval_unfold.get(); } 95 //------------------------------end utilities 96 97 //------------------------------enumerators 98 /** 99 * Register a variable e that we will do enumerative search on. 100 * 101 * conj : the conjecture that the enumeration of e is for. 102 * 103 * f : the synth-fun that the enumeration of e is for.Notice that enumerator 104 * e may not be one-to-one with f in synthesis-through-unification approaches 105 * (e.g. decision tree construction for PBE synthesis). 106 * 107 * erole : the role of this enumerator (see definition of EnumeratorRole). 108 * Depending on this and the policy for actively-generated enumerators 109 * (--sygus-active-gen), the enumerator may be "actively-generated". 110 * For example, if --sygus-active-gen=var-agnostic, then the enumerator will 111 * only generate values whose variables are in canonical order (only x1-x2 112 * and not x2-x1 will be generated, assuming x1 and x2 are in the same 113 * "subclass", see getSubclassForVar). 114 * 115 * useSymbolicCons : whether we want model values for e to include symbolic 116 * constructors like the "any constant" variable. 117 * 118 * An "active guard" may be allocated by this method for e based on erole 119 * and the policies for active generation. 120 */ 121 void registerEnumerator(Node e, 122 Node f, 123 SynthConjecture* conj, 124 EnumeratorRole erole, 125 bool useSymbolicCons = false); 126 /** is e an enumerator registered with this class? */ 127 bool isEnumerator(Node e) const; 128 /** return the conjecture e is associated with */ 129 SynthConjecture* getConjectureForEnumerator(Node e) const; 130 /** return the function-to-synthesize e is associated with */ 131 Node getSynthFunForEnumerator(Node e) const; 132 /** get active guard for e */ 133 Node getActiveGuardForEnumerator(Node e) const; 134 /** are we using symbolic constructors for enumerator e? */ 135 bool usingSymbolicConsForEnumerator(Node e) const; 136 /** is this enumerator agnostic to variables? */ 137 bool isVariableAgnosticEnumerator(Node e) const; 138 /** is this enumerator a "basic" enumerator. 139 * 140 * A basic enumerator is one that does not rely on the sygus extension of the 141 * datatypes solver. Basic enumerators enumerate all concrete terms for their 142 * type for a single abstract value. 143 */ 144 bool isBasicEnumerator(Node e) const; 145 /** is this a "passively-generated" enumerator? 146 * 147 * A "passively-generated" enumerator is one for which the terms it enumerates 148 * are obtained by looking at its model value only. For passively-generated 149 * enumerators, it is the responsibility of the user of that enumerator (say 150 * a SygusModule) to block the current model value of it before asking for 151 * another value. By default, the Cegis module uses passively-generated 152 * enumerators and "conjecture-specific refinement" to rule out models 153 * for passively-generated enumerators. 154 * 155 * On the other hand, an "actively-generated" enumerator is one for which the 156 * terms it enumerates are not necessarily a subset of the model values the 157 * enumerator takes. Actively-generated enumerators are centrally managed by 158 * SynthConjecture. The user of actively-generated enumerators are prohibited 159 * from influencing its model value. For example, conjecture-specific 160 * refinement in Cegis is not applied to actively-generated enumerators. 161 */ 162 bool isPassiveEnumerator(Node e) const; 163 /** get all registered enumerators */ 164 void getEnumerators(std::vector<Node>& mts); 165 /** Register symmetry breaking lemma 166 * 167 * This function registers lem as a symmetry breaking lemma template for 168 * subterms of enumerator e. For more information on symmetry breaking 169 * lemma templates, see datatypes/datatypes_sygus.h. 170 * 171 * tn : the (sygus datatype) type that lem applies to, i.e. the 172 * type of terms that lem blocks models for, 173 * sz : the minimum size of terms that the lem blocks, 174 * isTempl : if this flag is false, then lem is a (concrete) lemma. 175 * If this flag is true, then lem is a symmetry breaking lemma template 176 * over x, where x is returned by the call to getFreeVar( tn, 0 ). 177 */ 178 void registerSymBreakLemma( 179 Node e, Node lem, TypeNode tn, unsigned sz, bool isTempl = true); 180 /** Has symmetry breaking lemmas been added for any enumerator? */ 181 bool hasSymBreakLemmas(std::vector<Node>& enums) const; 182 /** Get symmetry breaking lemmas 183 * 184 * Returns the set of symmetry breaking lemmas that have been registered 185 * for enumerator e. It adds these to lemmas. 186 */ 187 void getSymBreakLemmas(Node e, std::vector<Node>& lemmas) const; 188 /** Get the type of term symmetry breaking lemma lem applies to */ 189 TypeNode getTypeForSymBreakLemma(Node lem) const; 190 /** Get the minimum size of terms symmetry breaking lemma lem applies to */ 191 unsigned getSizeForSymBreakLemma(Node lem) const; 192 /** Returns true if lem is a lemma template, false if lem is a lemma */ 193 bool isSymBreakLemmaTemplate(Node lem) const; 194 /** Clear information about symmetry breaking lemmas for enumerator e */ 195 void clearSymBreakLemmas(Node e); 196 //------------------------------end enumerators 197 198 //-----------------------------conversion from sygus to builtin 199 /** get free variable 200 * 201 * This class caches a list of free variables for each type, which are 202 * used, for instance, for constructing canonical forms of terms with free 203 * variables. This function returns the i^th free variable for type tn. 204 * If useSygusType is true, then this function returns a variable of the 205 * analog type for sygus type tn (see d_fv for details). 206 */ 207 TNode getFreeVar(TypeNode tn, int i, bool useSygusType = false); 208 /** get free variable and increment 209 * 210 * This function returns the next free variable for type tn, and increments 211 * the counter in var_count for that type. 212 */ 213 TNode getFreeVarInc(TypeNode tn, 214 std::map<TypeNode, int>& var_count, 215 bool useSygusType = false); 216 /** returns true if n is a cached free variable (in d_fv). */ isFreeVar(Node n)217 bool isFreeVar(Node n) { return d_fv_stype.find(n) != d_fv_stype.end(); } 218 /** returns the index of n in the free variable cache (d_fv). */ getVarNum(Node n)219 int getVarNum(Node n) { return d_fv_num[n]; } 220 /** returns true if n has a cached free variable (in d_fv). */ 221 bool hasFreeVar(Node n); 222 /** get sygus proxy variable 223 * 224 * Returns a fresh variable of type tn with the SygusPrintProxyAttribute set 225 * to constant c. The type tn should be a sygus datatype type, and the type of 226 * c should be the analog type of tn. The semantics of the returned node 227 * is "the variable of sygus datatype tn that encodes constant c". 228 */ 229 Node getProxyVariable(TypeNode tn, Node c); 230 /** make generic 231 * 232 * This function returns a builtin term f( t1, ..., tn ) where f is the 233 * builtin op of the sygus datatype constructor specified by arguments 234 * dt and c. The mapping pre maps child indices to the term for that index 235 * in the term we are constructing. That is, for each i = 1,...,n: 236 * If i is in the domain of pre, then ti = pre[i]. 237 * If i is not in the domain of pre, then ti = d_fv[1][ var_count[Ti ] ], 238 * and var_count[Ti] is incremented. 239 */ 240 Node mkGeneric(const Datatype& dt, 241 unsigned c, 242 std::map<TypeNode, int>& var_count, 243 std::map<int, Node>& pre); 244 /** same as above, but with empty var_count */ 245 Node mkGeneric(const Datatype& dt, int c, std::map<int, Node>& pre); 246 /** same as above, but with empty pre */ 247 Node mkGeneric(const Datatype& dt, int c); 248 /** makes a symbolic term concrete 249 * 250 * Given a sygus datatype term n of type tn with holes (symbolic constructor 251 * applications), this function returns a term in which holes are replaced by 252 * unique variables. To track counters for introducing unique variables, we 253 * use the var_count map. 254 */ 255 Node canonizeBuiltin(Node n); 256 Node canonizeBuiltin(Node n, std::map<TypeNode, int>& var_count); 257 /** sygus to builtin 258 * 259 * Given a sygus datatype term n of type tn, this function returns its analog, 260 * that is, the term that n encodes. 261 */ 262 Node sygusToBuiltin(Node n, TypeNode tn); 263 /** same as above, but without tn */ sygusToBuiltin(Node n)264 Node sygusToBuiltin(Node n) { return sygusToBuiltin(n, n.getType()); } 265 /** evaluate builtin 266 * 267 * bn is a term of some sygus datatype tn. This function returns the rewritten 268 * form of bn [ args / vars(tn) ], where vars(tn) is the sygus variable 269 * list for type tn (see Datatype::getSygusVarList). 270 * 271 * If the argument tryEval is true, we consult the evaluator before the 272 * rewriter, for performance reasons. 273 */ 274 Node evaluateBuiltin(TypeNode tn, 275 Node bn, 276 std::vector<Node>& args, 277 bool tryEval = true); 278 /** evaluate with unfolding 279 * 280 * n is any term that may involve sygus evaluation functions. This function 281 * returns the result of unfolding the evaluation functions within n and 282 * rewriting the result. For example, if eval_A is the evaluation function 283 * for the datatype: 284 * A -> C_0 | C_1 | C_x | C_+( C_A, C_A ) 285 * corresponding to grammar: 286 * A -> 0 | 1 | x | A + A 287 * then calling this function on eval( C_+( x, 1 ), 4 ) = y returns 5 = y. 288 * The node returned by this function is in (extended) rewritten form. 289 */ 290 Node evaluateWithUnfolding(Node n); 291 /** same as above, but with a cache of visited nodes */ 292 Node evaluateWithUnfolding( 293 Node n, std::unordered_map<Node, Node, NodeHashFunction>& visited); 294 /** is evaluation point? 295 * 296 * Returns true if n is of the form eval( x, c1...cn ) for some variable x 297 * and constants c1...cn. 298 */ 299 bool isEvaluationPoint(Node n) const; 300 /** return the builtin type of tn 301 * 302 * The type tn should be a sygus datatype type that has been registered to 303 * this database. 304 */ 305 TypeNode sygusToBuiltinType(TypeNode tn); 306 //-----------------------------end conversion from sygus to builtin 307 308 /** print to sygus stream n on trace c */ 309 static void toStreamSygus(const char* c, Node n); 310 311 private: 312 /** reference to the quantifiers engine */ 313 QuantifiersEngine* d_quantEngine; 314 315 //------------------------------utilities 316 /** sygus explanation */ 317 std::unique_ptr<SygusExplain> d_syexp; 318 /** extended rewriter */ 319 std::unique_ptr<ExtendedRewriter> d_ext_rw; 320 /** evaluator */ 321 std::unique_ptr<Evaluator> d_eval; 322 /** evaluation function unfolding utility */ 323 std::unique_ptr<SygusEvalUnfold> d_eval_unfold; 324 //------------------------------end utilities 325 326 //------------------------------enumerators 327 /** mapping from enumerator terms to the conjecture they are associated with 328 */ 329 std::map<Node, SynthConjecture*> d_enum_to_conjecture; 330 /** mapping from enumerator terms to the function-to-synthesize they are 331 * associated with 332 */ 333 std::map<Node, Node> d_enum_to_synth_fun; 334 /** mapping from enumerator terms to the guard they are associated with 335 * The guard G for an enumerator e has the semantics 336 * if G is true, then there are more values of e to enumerate". 337 */ 338 std::map<Node, Node> d_enum_to_active_guard; 339 /** 340 * Mapping from enumerators to whether we allow symbolic constructors to 341 * appear as subterms of them. 342 */ 343 std::map<Node, bool> d_enum_to_using_sym_cons; 344 /** mapping from enumerators to symmetry breaking clauses for them */ 345 std::map<Node, std::vector<Node> > d_enum_to_sb_lemmas; 346 /** mapping from symmetry breaking lemmas to type */ 347 std::map<Node, TypeNode> d_sb_lemma_to_type; 348 /** mapping from symmetry breaking lemmas to size */ 349 std::map<Node, unsigned> d_sb_lemma_to_size; 350 /** mapping from symmetry breaking lemmas to whether they are templates */ 351 std::map<Node, bool> d_sb_lemma_to_isTempl; 352 /** enumerators to whether they are actively-generated */ 353 std::map<Node, bool> d_enum_active_gen; 354 /** enumerators to whether they are variable agnostic */ 355 std::map<Node, bool> d_enum_var_agnostic; 356 /** enumerators to whether they are basic */ 357 std::map<Node, bool> d_enum_basic; 358 //------------------------------end enumerators 359 360 //-----------------------------conversion from sygus to builtin 361 /** a cache of fresh variables for each type 362 * 363 * We store two versions of this list: 364 * index 0: mapping from builtin types to fresh variables of that type, 365 * index 1: mapping from sygus types to fresh varaibles of the type they 366 * encode. 367 */ 368 std::map<TypeNode, std::vector<Node> > d_fv[2]; 369 /** Maps free variables to the domain type they are associated with in d_fv */ 370 std::map<Node, TypeNode> d_fv_stype; 371 /** Maps free variables to their index in d_fv. */ 372 std::map<Node, int> d_fv_num; 373 /** recursive helper for hasFreeVar, visited stores nodes we have visited. */ 374 bool hasFreeVar(Node n, std::map<Node, bool>& visited); 375 /** cache of getProxyVariable */ 376 std::map<TypeNode, std::map<Node, Node> > d_proxy_vars; 377 //-----------------------------end conversion from sygus to builtin 378 379 // TODO :issue #1235 : below here needs refactor 380 381 public: 382 Node d_true; 383 Node d_false; 384 385 private: 386 /** computes the map d_min_type_depth */ 387 void computeMinTypeDepthInternal( TypeNode root_tn, TypeNode tn, unsigned type_depth ); 388 bool involvesDivByZero( Node n, std::map< Node, bool >& visited ); 389 390 private: 391 // information for sygus types 392 std::map<TypeNode, TypeNode> d_register; // stores sygus -> builtin type 393 std::map<TypeNode, std::vector<Node> > d_var_list; 394 std::map<TypeNode, std::map<int, Kind> > d_arg_kind; 395 std::map<TypeNode, std::map<Kind, int> > d_kinds; 396 std::map<TypeNode, std::map<int, Node> > d_arg_const; 397 std::map<TypeNode, std::map<Node, int> > d_consts; 398 std::map<TypeNode, std::map<Node, int> > d_ops; 399 std::map<TypeNode, std::map<int, Node> > d_arg_ops; 400 std::map<TypeNode, std::map<Node, Node> > d_semantic_skolem; 401 // grammar information 402 // root -> type -> _ 403 /** 404 * For each sygus type t1, this maps datatype types t2 to the smallest size of 405 * a term of type t1 that includes t2 as a subterm. For example, for grammar: 406 * A -> B+B | 0 | B-D 407 * B -> C+C 408 * ... 409 * we have that d_min_type_depth[A] = { A -> 0, B -> 1, C -> 2, D -> 1 }. 410 */ 411 std::map<TypeNode, std::map<TypeNode, unsigned> > d_min_type_depth; 412 // std::map< TypeNode, std::map< Node, std::map< std::map< int, bool > > > 413 // d_consider_const; 414 // type -> cons -> _ 415 std::map<TypeNode, unsigned> d_min_term_size; 416 std::map<TypeNode, std::map<unsigned, unsigned> > d_min_cons_term_size; 417 /** a cache for getSelectorWeight */ 418 std::map<TypeNode, std::map<Node, unsigned> > d_sel_weight; 419 /** 420 * For each sygus type, the index of the "any constant" constructor, if it 421 * has one. 422 */ 423 std::map<TypeNode, unsigned> d_sym_cons_any_constant; 424 /** 425 * Whether any subterm of this type contains a symbolic constructor. This 426 * corresponds to whether sygus repair techniques will ever have any effect 427 * for this type. 428 */ 429 std::map<TypeNode, bool> d_has_subterm_sym_cons; 430 /** 431 * Map from sygus types and bound variables to their type subclass id. Note 432 * type class identifiers are computed for each type of registered sygus 433 * enumerators, but not all sygus types. For details, see getSubclassIdForVar. 434 */ 435 std::map<TypeNode, std::map<Node, unsigned> > d_var_subclass_id; 436 /** the list of variables with given subclass */ 437 std::map<TypeNode, std::map<unsigned, std::vector<Node> > > 438 d_var_subclass_list; 439 /** the index of each variable in the above list */ 440 std::map<TypeNode, std::map<Node, unsigned> > d_var_subclass_list_index; 441 442 public: // general sygus utilities 443 bool isRegistered(TypeNode tn) const; 444 // get the minimum depth of type in its parent grammar 445 unsigned getMinTypeDepth( TypeNode root_tn, TypeNode tn ); 446 // get the minimum size for a constructor term 447 unsigned getMinTermSize( TypeNode tn ); 448 unsigned getMinConsTermSize( TypeNode tn, unsigned cindex ); 449 /** get the weight of the selector, where tn is the domain of sel */ 450 unsigned getSelectorWeight(TypeNode tn, Node sel); 451 /** get subfield types 452 * 453 * This adds all "subfield types" of tn to sf_types. A type tnc is a subfield 454 * type of tn if there exists a selector chain S1( ... Sn( x )...) that has 455 * type tnc, where x has type tn. In other words, tnc is the type of some 456 * subfield of terms of type tn, at any depth. 457 */ 458 void getSubfieldTypes(TypeNode tn, std::vector<TypeNode>& sf_types); 459 460 public: 461 int getKindConsNum( TypeNode tn, Kind k ); 462 int getConstConsNum( TypeNode tn, Node n ); 463 int getOpConsNum( TypeNode tn, Node n ); 464 bool hasKind( TypeNode tn, Kind k ); 465 bool hasConst( TypeNode tn, Node n ); 466 bool hasOp( TypeNode tn, Node n ); 467 Node getConsNumConst( TypeNode tn, int i ); 468 Node getConsNumOp( TypeNode tn, int i ); 469 Kind getConsNumKind( TypeNode tn, int i ); 470 bool isKindArg( TypeNode tn, int i ); 471 bool isConstArg( TypeNode tn, int i ); 472 /** get arg type */ 473 TypeNode getArgType(const DatatypeConstructor& c, unsigned i) const; 474 /** is type match */ 475 bool isTypeMatch( const DatatypeConstructor& c1, const DatatypeConstructor& c2 ); 476 /** 477 * Get the index of the "any constant" constructor of type tn if it has one, 478 * or returns -1 otherwise. 479 */ 480 int getAnyConstantConsNum(TypeNode tn) const; 481 /** has subterm symbolic constructor 482 * 483 * Returns true if any subterm of type tn can be a symbolic constructor. 484 */ 485 bool hasSubtermSymbolicCons(TypeNode tn) const; 486 //--------------------------------- variable subclasses 487 /** Get subclass id for variable 488 * 489 * This returns the "subclass" identifier for variable v in sygus 490 * type tn. A subclass identifier groups variables based on the sygus 491 * types they occur in: 492 * A -> A + B | C + C | x | y | z | w | u 493 * B -> y | z 494 * C -> u 495 * The variables in this grammar can be grouped according to the sygus types 496 * they appear in: 497 * { x,w } occur in A 498 * { y,z } occur in A,B 499 * { u } occurs in A,C 500 * We say that e.g. x, w are in the same subclass. 501 * 502 * If this method returns 0, then v is not a variable in sygus type tn. 503 * Otherwise, this method returns a positive value n, such that 504 * getSubclassIdForVar[v1] = getSubclassIdForVar[v2] iff v1 and v2 are in the 505 * same subclass. 506 * 507 * The type tn should be the type of an enumerator registered to this 508 * database, where notice that we do not compute this information for the 509 * subfield types of the enumerator. 510 */ 511 unsigned getSubclassForVar(TypeNode tn, Node v) const; 512 /** 513 * Get the number of variable in the subclass with identifier sc for type tn. 514 */ 515 unsigned getNumSubclassVars(TypeNode tn, unsigned sc) const; 516 /** Get the i^th variable in the subclass with identifier sc for type tn */ 517 Node getVarSubclassIndex(TypeNode tn, unsigned sc, unsigned i) const; 518 /** 519 * Get the a variable's index in its subclass list. This method returns true 520 * iff variable v has been assigned a subclass in tn. It updates index to 521 * be v's index iff the method returns true. 522 */ 523 bool getIndexInSubclassForVar(TypeNode tn, Node v, unsigned& index) const; 524 //--------------------------------- end variable subclasses 525 /** return whether n is an application of a symbolic constructor */ 526 bool isSymbolicConsApp(Node n) const; 527 /** can construct kind 528 * 529 * Given a sygus datatype type tn, if this method returns true, then there 530 * exists values of tn whose builtin analog is equivalent to 531 * <k>( t1, ..., tn ). The sygus types of t1...tn are added to arg_types. 532 * 533 * For example, if: 534 * A -> A+A | ite( B, A, A ) | x | 1 | 0 535 * B -> and( B, B ) | not( B ) | or( B, B ) | A = A 536 * - canConstructKind( A, +, ... ) returns true and adds {A,A} to arg_types, 537 * - canConstructKind( B, not, ... ) returns true and adds { B } to arg types. 538 * 539 * We also may infer that operator is constructable. For example, 540 * - canConstructKind( B, ite, ... ) may return true, adding { B, B, B } to 541 * arg_types, noting that the term 542 * (and (or (not b1) b2) (or b1 b3)) is equivalent to (ite b1 b2 b3) 543 * The argument aggr is whether we use aggressive techniques like the one 544 * above to infer a kind is constructable. If this flag is false, we only 545 * check if the kind is literally a constructor of the grammar. 546 */ 547 bool canConstructKind(TypeNode tn, 548 Kind k, 549 std::vector<TypeNode>& argts, 550 bool aggr = false); 551 552 TypeNode getSygusTypeForVar( Node v ); 553 Node sygusSubstituted( TypeNode tn, Node n, std::vector< Node >& args ); 554 Node getSygusNormalized( Node n, std::map< TypeNode, int >& var_count, std::map< Node, Node >& subs ); 555 Node getNormalized(TypeNode t, Node prog); 556 unsigned getSygusTermSize( Node n ); 557 /** given a term, construct an equivalent smaller one that respects syntax */ 558 Node minimizeBuiltinTerm( Node n ); 559 /** given a term, expand it into more basic components */ 560 Node expandBuiltinTerm( Node n ); 561 /** get comparison kind */ 562 Kind getComparisonKind( TypeNode tn ); 563 Kind getPlusKind( TypeNode tn, bool is_neg = false ); 564 /** involves div-by-zero */ 565 bool involvesDivByZero( Node n ); 566 /** get anchor */ 567 static Node getAnchor( Node n ); 568 static unsigned getAnchorDepth( Node n ); 569 570 public: 571 /** unfold 572 * 573 * This method returns the one-step unfolding of an evaluation function 574 * application. An example of a one step unfolding is: 575 * eval( C_+( d1, d2 ), t ) ---> +( eval( d1, t ), eval( d2, t ) ) 576 * 577 * This function does this unfolding for a (possibly symbolic) evaluation 578 * head, where the argument "variable to model" vtm stores the model value of 579 * variables from this head. This allows us to track an explanation of the 580 * unfolding in the vector exp when track_exp is true. 581 * 582 * For example, if vtm[d] = C_+( C_x(), C_0() ) and track_exp is true, then 583 * this method applied to eval( d, t ) will return 584 * +( eval( d.0, t ), eval( d.1, t ) ), and is-C_+( d ) is added to exp. 585 */ 586 Node unfold(Node en, 587 std::map<Node, Node>& vtm, 588 std::vector<Node>& exp, 589 bool track_exp = true); 590 /** 591 * Same as above, but without explanation tracking. This is used for concrete 592 * evaluation heads 593 */ 594 Node unfold(Node en); 595 Node getEagerUnfold( Node n, std::map< Node, Node >& visited ); 596 }; 597 598 }/* CVC4::theory::quantifiers namespace */ 599 }/* CVC4::theory namespace */ 600 }/* CVC4 namespace */ 601 602 #endif /* __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_H */ 603