1 /*********************                                                        */
2 /*! \file datatypes_sygus.h
3  ** \verbatim
4  ** Top contributors (to current version):
5  **   Andrew Reynolds, Dejan Jovanovic
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 Sygus utilities for theory of datatypes
13  **
14  ** Theory of datatypes.
15  **/
16 
17 #include "cvc4_private.h"
18 
19 #ifndef __CVC4__THEORY__DATATYPES__DATATYPES_SYGUS_NEW_H
20 #define __CVC4__THEORY__DATATYPES__DATATYPES_SYGUS_NEW_H
21 
22 #include <iostream>
23 #include <map>
24 
25 #include "context/cdhashmap.h"
26 #include "context/cdhashset.h"
27 #include "context/cdlist.h"
28 #include "context/cdo.h"
29 #include "context/context.h"
30 #include "expr/datatype.h"
31 #include "expr/node.h"
32 #include "theory/datatypes/sygus_simple_sym.h"
33 #include "theory/quantifiers/sygus/sygus_explain.h"
34 #include "theory/quantifiers/sygus/synth_conjecture.h"
35 #include "theory/quantifiers/sygus_sampler.h"
36 #include "theory/quantifiers/term_database.h"
37 
38 namespace CVC4 {
39 namespace theory {
40 namespace datatypes {
41 
42 class TheoryDatatypes;
43 
44 /**
45  * This is the sygus extension of the decision procedure for quantifier-free
46  * inductive datatypes. At a high level, this class takes as input a
47  * set of asserted testers is-C1( x ), is-C2( x.1 ), is-C3( x.2 ), and
48  * generates lemmas that restrict the models of x, if x is a "sygus enumerator"
49  * (see TermDbSygus::registerEnumerator).
50  *
51  * Some of these techniques are described in these papers:
52  * "Refutation-Based Synthesis in SMT", Reynolds et al 2017.
53  * "Sygus Techniques in the Core of an SMT Solver", Reynolds et al 2017.
54  *
55  * This class enforces two decisions stragies via calls to registerStrategy
56  * of the owning theory's DecisionManager:
57  * (1) Positive decisions on the active guards G of enumerators e registered
58  * to this class. These assert "there are more values to enumerate for e".
59  * (2) Positive bounds (DT_SYGUS_BOUND m n) for "measure terms" m (see below),
60  * where n is a non-negative integer. This asserts "the measure of terms
61  * we are enumerating for enumerators whose measure term m is at most n",
62  * where measure is commonly term size, but can also be height.
63  *
64  * We prioritize decisions of form (1) before (2). Both kinds of decision are
65  * critical for solution completeness, which is enforced by DecisionManager.
66  */
67 class SygusSymBreakNew
68 {
69   typedef context::CDHashMap< Node, int, NodeHashFunction > IntMap;
70   typedef context::CDHashMap< Node, Node, NodeHashFunction > NodeMap;
71   typedef context::CDHashMap< Node, bool, NodeHashFunction > BoolMap;
72   typedef context::CDHashSet<Node, NodeHashFunction> NodeSet;
73 
74  public:
75   SygusSymBreakNew(TheoryDatatypes* td,
76                    QuantifiersEngine* qe,
77                    context::Context* c);
78   ~SygusSymBreakNew();
79   /**
80    * Notify this class that tester for constructor tindex has been asserted for
81    * n. Exp is the literal corresponding to this tester. This method may add
82    * lemmas to the vector lemmas, for details see assertTesterInternal below.
83    * These lemmas are sent out on the output channel of datatypes by the caller.
84    */
85   void assertTester(int tindex, TNode n, Node exp, std::vector<Node>& lemmas);
86   /**
87    * Notify this class that literal n has been asserted with the given
88    * polarity. This method may add lemmas to the vector lemmas, for instance
89    * based on inferring consequences of (not) n. One example is if n is
90    * (DT_SIZE_BOUND x n), we add the lemma:
91    *   (DT_SIZE_BOUND x n) <=> ((DT_SIZE x) <= n )
92    */
93   void assertFact(Node n, bool polarity, std::vector<Node>& lemmas);
94   /** pre-register term n
95    *
96    * This is called when n is pre-registered with the theory of datatypes.
97    * If n is a sygus enumerator, then we may add lemmas to the vector lemmas
98    * that are used to enforce fairness regarding the size of n.
99    */
100   void preRegisterTerm(TNode n, std::vector<Node>& lemmas);
101   /** check
102    *
103    * This is called at last call effort, when the current model assignment is
104    * satisfiable according to the quantifier-free decision procedures and a
105    * model is built. This method may add lemmas to the vector lemmas based
106    * on dynamic symmetry breaking techniques, based on the model values of
107    * all preregistered enumerators.
108    */
109   void check(std::vector<Node>& lemmas);
110  private:
111   /** Pointer to the datatype theory that owns this class. */
112   TheoryDatatypes* d_td;
113   /** Pointer to the sygus term database */
114   quantifiers::TermDbSygus* d_tds;
115   /** the simple symmetry breaking utility */
116   SygusSimpleSymBreak d_ssb;
117   /**
118    * Map from terms to the index of the tester that is asserted for them in
119    * the current SAT context. In other words, if d_testers[n] = 2, then the
120    * tester is-C_2(n) is asserted in this SAT context.
121    */
122   IntMap d_testers;
123   /**
124    * Map from terms to the tester asserted for them. In the example above,
125    * d_testers[n] = is-C_2(n).
126    */
127   NodeMap d_testers_exp;
128   /**
129    * The set of (selector chain) terms that are active in the current SAT
130    * context. A selector chain term S_n( ... S_1( x )... ) is active if either:
131    * (1) n=0 and x is a sygus enumerator,
132    *   or:
133    * (2.1) S_{n-1}( ... S_1( x )) is active,
134    * (2.2) is-C( S_{n-1}( ... S_1( x )) ) is asserted in this SAT context, and
135    * (2.3) S_n is a selector for constructor C.
136    */
137   NodeSet d_active_terms;
138   /**
139    * Map from enumerators to a lower bound on their size in the current SAT
140    * context.
141    */
142   IntMap d_currTermSize;
143   /** zero */
144   Node d_zero;
145   /** true */
146   Node d_true;
147   /**
148    * Map from terms (selector chains) to their anchors. The anchor of a
149    * selector chain S1( ... Sn( x ) ... ) is x.
150    */
151   std::unordered_map<Node, Node, NodeHashFunction> d_term_to_anchor;
152   /**
153    * Map from anchors to the conjecture they are associated with.
154    */
155   std::map<Node, quantifiers::SynthConjecture*> d_anchor_to_conj;
156   /**
157    * Map from terms (selector chains) to their depth. The depth of a selector
158    * chain S1( ... Sn( x ) ... ) is:
159    *   weight( S1 ) + ... + weight( Sn ),
160    * where weight is the selector weight of Si
161    * (see SygusTermDatabase::getSelectorWeight).
162    */
163   std::unordered_map<Node, unsigned, NodeHashFunction> d_term_to_depth;
164   /**
165    * Map from terms (selector chains) to whether they are the topmost term
166    * of their type. For example, if:
167    *   S1 : T1 -> T2
168    *   S2 : T2 -> T2
169    *   S3 : T2 -> T1
170    *   S4 : T1 -> T3
171    * Then, x, S1( x ), and S4( S3( S2( S1( x ) ) ) ) are top-level terms,
172    * whereas S2( S1( x ) ) and S3( S2( S1( x ) ) ) are not.
173    */
174   std::unordered_map<Node, bool, NodeHashFunction> d_is_top_level;
175   /**
176    * Returns true if the selector chain n is top-level based on the above
177    * definition, when tn is the type of n.
178    */
179   bool computeTopLevel( TypeNode tn, Node n );
180 private:
181  /** This caches all information regarding symmetry breaking for an anchor. */
182  class SearchCache
183  {
184   public:
SearchCache()185     SearchCache(){}
186     /**
187      * A cache of all search terms for (types, sizes). See registerSearchTerm
188      * for definition of search terms.
189      */
190     std::map< TypeNode, std::map< unsigned, std::vector< Node > > > d_search_terms;
191     /** A cache of all symmetry breaking lemma templates for (types, sizes). */
192     std::map< TypeNode, std::map< unsigned, std::vector< Node > > > d_sb_lemmas;
193     /** search value
194      *
195      * For each sygus type, a map from a builtin term to a sygus term for that
196      * type that we encountered during the search whose analog rewrites to that
197      * term. The range of this map can be updated if we later encounter a sygus
198      * term that also rewrites to the builtin value but has a smaller term size.
199      */
200     std::map<TypeNode, std::unordered_map<Node, Node, NodeHashFunction>>
201         d_search_val;
202     /** the size of terms in the range of d_search val. */
203     std::map<TypeNode, std::unordered_map<Node, unsigned, NodeHashFunction>>
204         d_search_val_sz;
205     /** For each term, whether this cache has processed that term */
206     std::unordered_set<Node, NodeHashFunction> d_search_val_proc;
207   };
208   /** An instance of the above cache, for each anchor */
209   std::map< Node, SearchCache > d_cache;
210   //-----------------------------------traversal predicates
211   /** pre/post traversal predicates for each type, variable
212    *
213    * This stores predicates (pre, post) whose semantics correspond to whether
214    * a variable has occurred by a (pre, post) traversal of a symbolic term,
215    * where index = 0 corresponds to pre, index = 1 corresponds to post. For
216    * details, see getTraversalPredicate below.
217    */
218   std::map<TypeNode, std::map<Node, Node>> d_traversal_pred[2];
219   /** traversal applications to Boolean variables
220    *
221    * This maps each application of a traversal predicate pre_x( t ) or
222    * post_x( t ) to a fresh Boolean variable.
223    */
224   std::map<Node, Node> d_traversal_bool;
225   /** get traversal predicate
226    *
227    * Get the predicates (pre, post) whose semantics correspond to whether
228    * a variable has occurred by this point in a (pre, post) traversal of a term.
229    * The type of getTraversalPredicate(tn, n, _) is tn -> Bool.
230    *
231    * For example, consider the term:
232    *   f( x_1, g( x_2, x_3 ) )
233    * and a left-to-right, depth-first traversal of this term. Let e be
234    * a variable of the same type as this term. We say that for the above term:
235    *   pre_{x_1} is false for e, e.1 and true for e.2, e.2.1, e.2.2
236    *   pre_{x_2} is false for e, e.1, e.2, e.2.1, and true for e.2.2
237    *   pre_{x_3} is false for e, e.1, e.2, e.2.1, e.2.2
238    *   post_{x_1} is true for e.1, e.2.1, e.2.2, e.2, e
239    *   post_{x_2} is false for e.1 and true for e.2.1, e.2.2, e.2, e
240    *   post_{x_3} is false for e.1, e.2.1 and true for e.2.2, e.2, e
241    *
242    * We enforce a symmetry breaking scheme for each enumerator e that is
243    * "variable-agnostic" (see argument isVarAgnostic in registerEnumerator)
244    * that ensures the variables are ordered. This scheme makes use of these
245    * predicates, described in the following:
246    *
247    * Let x_1, ..., x_m be variables that occur in the same subclass in the type
248    * of e (see TermDbSygus::getSubclassForVar).
249    * For i = 1, ..., m:
250    *   // each variable does not occur initially in a traversal of e
251    *   ~pre_{x_i}( e ) AND
252    *   // for each subterm of e
253    *   template z.
254    *     // if this is variable x_i, then x_{i-1} must have already occurred
255    *     is-x_i( z ) => pre_{x_{i-1}}( z ) AND
256    *     for args a = 1...n
257    *       // pre-definition for each argument of this term
258    *       pre_{x_i}( z.a ) = a=0 ? pre_{x_i}( z ) : post_{x_i}( z.{a-1} ) AND
259    *     // post-definition for this term
260    *     post_{x_i}( z ) = post_{x_i}( z.n ) OR is-x_i( z )
261    *
262    * For clarity, above we have written pre and post as first-order predicates.
263    * However, applications of pre/post should be seen as indexed Boolean
264    * variables. The reason for this is pre and post cannot be given a consistent
265    * semantics. For example, consider term f( x_1, x_1 ) and enumerator variable
266    * e of the same type over which we are encoding a traversal. We have that
267    * pre_{x_1}( e.1 ) is false and pre_{x_1}( e.2 ) is true, although the model
268    * values for e.1 and e.2 are equal. Instead, pre_{x_1}( e.1 ) should be seen
269    * as a Boolean variable V_pre_{x_1,e.1} indexed by x_1 and e.1. and likewise
270    * for e.2. We convert all applications of pre/post to Boolean variables in
271    * the method eliminateTraversalPredicates below. Nevertheless, it is
272    * important that applications pre and post are encoded as APPLY_UF
273    * applications so that they behave as expected under substitutions. For
274    * example, pre_{x_1}( z.1 ) { z -> e.2 } results in pre_{x_1}( e.2.1 ), which
275    * after eliminateTraversalPredicates is V_pre_{x_1, e.2.1}.
276    */
277   Node getTraversalPredicate(TypeNode tn, Node n, bool isPre);
278   /** eliminate traversal predicates
279    *
280    * This replaces all applications of traversal predicates P( x ) in n with
281    * unique Boolean variables, given by d_traversal_bool[ P( x ) ], and
282    * returns the result.
283    */
284   Node eliminateTraversalPredicates(Node n);
285   //-----------------------------------end traversal predicates
286   /** a sygus sampler object for each (anchor, sygus type) pair
287    *
288    * This is used for the sygusRewVerify() option to verify the correctness of
289    * the rewriter.
290    */
291   std::map<Node, std::map<TypeNode, quantifiers::SygusSampler>> d_sampler;
292   /** Assert tester internal
293    *
294    * This function is called when the tester with index tindex is asserted for
295    * n, exp is the tester predicate. For example, for grammar:
296    *   A -> A+A | x | 1 | 0
297    * when is_+( d ) is asserted,
298    * assertTesterInternal(0, s( d ), is_+( s( d ) ),...) is called. This
299    * function may add lemmas to lemmas, which are sent out on the output
300    * channel of datatypes by the caller.
301    *
302    * These lemmas are of various forms, including:
303    * (1) dynamic symmetry breaking clauses for subterms of n (those added to
304    * lemmas on calls to addSymBreakLemmasFor, see function below),
305    * (2) static symmetry breaking clauses for subterms of n (those added to
306    * lemmas on getSimpleSymBreakPred, see function below),
307    * (3) conjecture-specific symmetry breaking lemmas, see
308    * SynthConjecture::getSymmetryBreakingPredicate,
309    * (4) fairness conflicts if sygusFair() is SYGUS_FAIR_DIRECT, e.g.:
310    *    size( d ) <= 1 V ~is-C1( d ) V ~is-C2( d.1 )
311    * where C1 and C2 are non-nullary constructors.
312    */
313   void assertTesterInternal( int tindex, TNode n, Node exp, std::vector< Node >& lemmas );
314   /**
315    * This function is called when term n is registered to the theory of
316    * datatypes. It makes the appropriate call to registerSearchTerm below,
317    * if applicable.
318    */
319   void registerTerm(Node n, std::vector<Node>& lemmas);
320 
321   //------------------------dynamic symmetry breaking
322   /** Register search term
323    *
324    * This function is called when selector chain n of the form
325    * S_1( ... S_m( x ) ... ) is registered to the theory of datatypes, where
326    * tn is the type of n, d indicates the depth of n (the sum of weights of the
327    * selectors S_1...S_m), and topLevel is whether n is a top-level term
328    * (see d_is_top_level). We refer to n as a "search term".
329    *
330    * The purpose of this function is to notify this class that symmetry breaking
331    * lemmas should be instantiated for n. Any symmetry breaking lemmas that
332    * are active for n (see description of addSymBreakLemmasFor) are added to
333    * lemmas in this call.
334    */
335   void registerSearchTerm( TypeNode tn, unsigned d, Node n, bool topLevel, std::vector< Node >& lemmas );
336   /** Register search value
337    *
338    * This function is called when a selector chain n has been assigned a model
339    * value nv. This function calls itself recursively so that extensions of the
340    * selector chain n are registered with all the subterms of nv. For example,
341    * if we call this function with:
342    *   n = x, nv = +( 1(), x() )
343    * we make recursive calls with:
344    *   n = x.1, nv = 1() and n = x.2, nv = x()
345    *
346    * a : the anchor of n,
347    * d : the depth of n.
348    *
349    * This function determines if the value nv is equivalent via rewriting to
350    * any previously registered search values for anchor a. If so, we construct
351    * a symmetry breaking lemma template and register it in d_cache[a]. For
352    * example, for grammar:
353    *   A -> A+A | x | 1 | 0
354    * Registering search value d -> x followed by d -> +( x, 0 ) results in the
355    * construction of the symmetry breaking lemma template:
356    *   ~is_+( z ) V ~is_x( z.1 ) V ~is_0( z.2 )
357    * which is stored in d_cache[a].d_sb_lemmas. This lemma is instantiated with
358    * z -> t for all terms t of appropriate depth, including d.
359    * This function strengthens blocking clauses using generalization techniques
360    * described in Reynolds et al SYNT 2017.
361    *
362    * The return value of this function is an abstraction of model assignment
363    * of nv to n, or null if we wish to exclude the model assignment nv to n.
364    * The return value of this method is different from nv itself, e.g. if it
365    * contains occurrences of the "any constant" constructor. For example, if
366    * nv is C_+( C_x(), C_{any_constant}( 5 ) ), then the return value of this
367    * function will either be null, or C_+( C_x(), C_{any_constant}( n.1.0 ) ),
368    * where n.1.0 is the appropriate selector chain applied to n. We build this
369    * abstraction since the semantics of C_{any_constant} is "any constant" and
370    * not "some constant". Thus, we should consider the subterm
371    * C_{any_constant}( 5 ) above to be an unconstrained variable (as represented
372    * by a selector chain), instead of the concrete value 5.
373    *
374    * The flag isVarAgnostic is whether "a" is a variable agnostic enumerator. If
375    * this is the case, we restrict symmetry breaking to subterms of n on its
376    * leftmost subchain. For example, consider the grammar:
377    *   A -> B=B
378    *   B -> B+B | x | y | 0
379    * Say we are registering the search value x = y+x. Notice that this value is
380    * ordered. If a were a variable-agnostic enumerator of type A in this
381    * case, we would only register x = y+x and x, and not y+x or y, since the
382    * latter two terms are not leftmost subterms in this value. If we did on the
383    * other hand register y+x, we would be prevented from solutions like x+y = 0
384    * later, since x+y is equivalent to (the already registered value) y+x.
385    *
386    * If doSym is false, we are not performing symmetry breaking on n. This flag
387    * is set to false on branches of n that are not leftmost.
388    */
389   Node registerSearchValue(Node a,
390                            Node n,
391                            Node nv,
392                            unsigned d,
393                            std::vector<Node>& lemmas,
394                            bool isVarAgnostic,
395                            bool doSym);
396   /** Register symmetry breaking lemma
397    *
398    * This function adds the symmetry breaking lemma template lem for terms of
399    * type tn with anchor a. This is added to d_cache[a].d_sb_lemmas. Notice that
400    * we use lem as a template with free variable x, e.g. our template is:
401    *   (lambda ((x tn)) lem)
402    * where x = getFreeVar( tn ). For all search terms t of the appropriate
403    * depth,
404    * we add the lemma lem{ x -> t } to lemmas.
405    *
406    * The argument sz indicates the size of terms that the lemma applies to, e.g.
407    *   ~is_+( z ) has size 1
408    *   ~is_+( z ) V ~is_x( z.1 ) V ~is_0( z.2 ) has size 1
409    *   ~is_+( z ) V ~is_+( z.1 ) has size 2
410    * This is equivalent to sum of weights of constructors corresponding to each
411    * tester, e.g. above + has weight 1, and x and 0 have weight 0.
412    */
413   void registerSymBreakLemma(
414       TypeNode tn, Node lem, unsigned sz, Node a, std::vector<Node>& lemmas);
415   /** Register symmetry breaking lemma for value
416    *
417    * This function adds a symmetry breaking lemma template for selector chains
418    * with anchor a, that effectively states that val should never be a subterm
419    * of any value for a.
420    *
421    * et : an "invariance test" (see sygus/sygus_invariance.h) which states a
422    * criterion that val meets, which is the reason for its exclusion. This is
423    * used for generalizing the symmetry breaking lemma template.
424    * valr : if non-null, this states a value that should *not* be excluded by
425    * the symmetry breaking lemma template, which is a restriction to the above
426    * generalization.
427    *
428    * This function may add instances of the symmetry breaking template for
429    * existing search terms, which are added to lemmas.
430    */
431   void registerSymBreakLemmaForValue(Node a,
432                                      Node val,
433                                      quantifiers::SygusInvarianceTest& et,
434                                      Node valr,
435                                      std::map<TypeNode, int>& var_count,
436                                      std::vector<Node>& lemmas);
437   /** Add symmetry breaking lemmas for term
438    *
439    * Adds all active symmetry breaking lemmas for selector chain t to lemmas. A
440    * symmetry breaking lemma L is active for t based on three factors:
441    * (1) the current search size sz(a) for its anchor a,
442    * (2) the depth d of term t (see d_term_to_depth),
443    * (3) the size sz(L) of the symmetry breaking lemma L.
444    * In particular, L is active if sz(L) <= sz(a) - d. In other words, a
445    * symmetry breaking lemma is active if it is intended to block terms of
446    * size sz(L), and the maximum size that t can take in the current search,
447    * sz(a)-d, is greater than or equal to this value.
448    *
449    * tn : the type of term t,
450    * a : the anchor of term t,
451    * d : the depth of term t.
452    */
453   void addSymBreakLemmasFor(
454       TypeNode tn, Node t, unsigned d, Node a, std::vector<Node>& lemmas);
455   /** calls the above function where a is the anchor t */
456   void addSymBreakLemmasFor( TypeNode tn, Node t, unsigned d, std::vector< Node >& lemmas );
457   //------------------------end dynamic symmetry breaking
458 
459   /** Get relevancy condition
460    *
461    * This returns (the negation of) a predicate that holds in the contexts in
462    * which the selector chain n is specified. For example, the negation of the
463    * relevancy condition for sel_{C2,1}( sel_{C1,1}( d ) ) is
464    *    ~( is-C1( d ) ^ is-C2( sel_{C1,1}( d ) ) )
465    * If shared selectors are enabled, this is a conjunction of disjunctions,
466    * since shared selectors may apply to multiple constructors.
467    */
468   Node getRelevancyCondition( Node n );
469   /** Cache of the above function */
470   std::map<Node, Node> d_rlv_cond;
471 
472   //------------------------static symmetry breaking
473   /** Get simple symmetry breakind predicate
474    *
475    * This function returns the "static" symmetry breaking lemma template for
476    * terms with type tn and constructor index tindex, for the given depth. This
477    * includes inferences about size with depth=0. Given grammar:
478    *   A -> ite( B, A, A ) | A+A | x | 1 | 0
479    *   B -> A = A
480    * Examples of static symmetry breaking lemma templates are:
481    *   for +, depth 0: size(z)=size(z.1)+size(z.2)+1
482    *   for +, depth 1: ~is-0( z.1 ) ^ ~is-0( z.2 ) ^ F
483    *     where F ensures the constructor of z.1 is less than that of z.2 based
484    *     on some ordering.
485    *   for ite, depth 1: z.2 != z.3
486    * These templates can be thought of as "hard-coded" cases of dynamic symmetry
487    * breaking lemma templates. Notice that the above lemma templates are in
488    * terms of getFreeVar( tn ), hence only one is created per
489    * (constructor, depth). A static symmetry break lemma template F[z] for
490    * constructor C are included in lemmas of the form:
491    *   is-C( t ) => F[t]
492    * where t is a search term, see registerSearchTerm for definition of search
493    * term.
494    *
495    * usingSymCons: whether we are using symbolic constructors for subterms in
496    * the type tn,
497    * isVarAgnostic: whether the terms we are enumerating are agnostic to
498    * variables.
499    *
500    * The latter two options may affect the form of the predicate we construct.
501    */
502   Node getSimpleSymBreakPred(Node e,
503                              TypeNode tn,
504                              int tindex,
505                              unsigned depth,
506                              bool usingSymCons,
507                              bool isVarAgnostic);
508   /** Cache of the above function */
509   std::map<Node,
510            std::map<TypeNode,
511                     std::map<int, std::map<bool, std::map<unsigned, Node>>>>>
512       d_simple_sb_pred;
513   /**
514    * For each search term, this stores the maximum depth for which we have added
515    * a static symmetry breaking lemma.
516    *
517    * This should be user context-dependent if sygus is updated to work in
518    * incremental mode.
519    */
520   std::unordered_map<Node, unsigned, NodeHashFunction> d_simple_proc;
521   //------------------------end static symmetry breaking
522 
523   /** Get the canonical free variable for type tn */
524   TNode getFreeVar( TypeNode tn );
525   /** get term order predicate
526    *
527    * Assuming that n1 and n2 are children of a commutative operator, this
528    * returns a symmetry breaking predicate that can be instantiated for n1 and
529    * n2 while preserving satisfiability. By default, this is the predicate
530    *   ( DT_SIZE n1 ) >= ( DT_SIZE n2 )
531    */
532   Node getTermOrderPredicate( Node n1, Node n2 );
533 
534  private:
535   /**
536    * Map from registered variables to whether they are a sygus enumerator.
537    *
538    * This should be user context-dependent if sygus is updated to work in
539    * incremental mode.
540    */
541   std::map<Node, bool> d_register_st;
542   //----------------------search size information
543   /**
544    * Checks whether e is a sygus enumerator, that is, a term for which this
545    * class will track size for.
546    *
547    * We associate each sygus enumerator e with a "measure term", which is used
548    * for bounding the size of terms for the models of e. The measure term for a
549    * sygus enumerator may be e itself (if e has an active guard), or an
550    * arbitrary sygus variable otherwise. A measure term m is one for which our
551    * decision strategy decides on literals of the form (DT_SYGUS_BOUND m n).
552    *
553    * After determining the measure term m for e, if applicable, we initialize
554    * SygusSizeDecisionStrategy for m below. This may result in lemmas
555    */
556   void registerSizeTerm(Node e, std::vector<Node>& lemmas);
557   /** A decision strategy for each measure term allocated by this class */
558   class SygusSizeDecisionStrategy : public DecisionStrategyFmf
559   {
560    public:
SygusSizeDecisionStrategy(Node t,context::Context * c,Valuation valuation)561     SygusSizeDecisionStrategy(Node t, context::Context* c, Valuation valuation)
562         : DecisionStrategyFmf(c, valuation), d_this(t), d_curr_search_size(0)
563     {
564     }
565     /** the measure term */
566     Node d_this;
567     /**
568      * For each size n, an explanation for why this measure term has size at
569      * most n. This is typically the literal (DT_SYGUS_BOUND m n), which
570      * we call the (n^th) "fairness literal" for m.
571      */
572     std::map< unsigned, Node > d_search_size_exp;
573     /**
574      * For each size, whether we have called SygusSymBreakNew::notifySearchSize.
575      */
576     std::map< unsigned, bool > d_search_size;
577     /**
578      * The current search size. This corresponds to the number of times
579      * incrementCurrentSearchSize has been called for this measure term.
580      */
581     unsigned d_curr_search_size;
582     /** the list of all enumerators whose measure term is this */
583     std::vector< Node > d_anchors;
584     /** get or make the measure value
585      *
586      * The measure value is an integer variable v that is a (symbolic) integer
587      * value that is constrained to be less than or equal to the current search
588      * size. For example, if we are using the fairness strategy
589      * SYGUS_FAIR_DT_SIZE (see options/datatype_options.h), then we constrain:
590      *   (DT_SYGUS_BOUND m n) <=> (v <= n)
591      * for all asserted fairness literals. Then, if we are enforcing fairness
592      * based on the maximum size, we assert:
593      *   (DT_SIZE e) <= v
594      * for all enumerators e.
595      */
596     Node getOrMkMeasureValue(std::vector<Node>& lemmas);
597     /** get or make the active measure value
598      *
599      * The active measure value av is an integer variable that corresponds to
600      * the (symbolic) value of the sum of enumerators that are yet to be
601      * registered. This is to enforce the "sum of measures" strategy. For
602      * example, if we are using the fairness strategy SYGUS_FAIR_DT_SIZE,
603      * then initially av is equal to the measure value v, and the constraints
604      *   (DT_SYGUS_BOUND m n) <=> (v <= n)
605      * are added as before. When an enumerator e is registered, we add the
606      * lemma:
607      *   av = (DT_SIZE e) + av'
608      * and update the active measure value to av'. This ensures that the sum
609      * of sizes of active enumerators is at most n.
610      *
611      * If the flag mkNew is set to true, then we return a fresh variable and
612      * update the active measure value.
613      */
614     Node getOrMkActiveMeasureValue(std::vector<Node>& lemmas,
615                                    bool mkNew = false);
616     /** Returns the s^th fairness literal for this measure term. */
617     Node mkLiteral(unsigned s) override;
618     /** identify */
identify()619     std::string identify() const override
620     {
621       return std::string("sygus_enum_size");
622     }
623 
624    private:
625     /** the measure value */
626     Node d_measure_value;
627     /** the sygus measure value */
628     Node d_measure_value_active;
629   };
630   /** the above information for each registered measure term */
631   std::map<Node, std::unique_ptr<SygusSizeDecisionStrategy>> d_szinfo;
632   /** map from enumerators (anchors) to their associated measure term */
633   std::map< Node, Node > d_anchor_to_measure_term;
634   /** map from enumerators (anchors) to their active guard*/
635   std::map< Node, Node > d_anchor_to_active_guard;
636   /** map from enumerators (anchors) to a decision stratregy for that guard */
637   std::map<Node, std::unique_ptr<DecisionStrategy>> d_anchor_to_ag_strategy;
638   /** generic measure term
639    *
640    * This is a global term that is used as the measure term for all sygus
641    * enumerators that do not have active guards. This class enforces that
642    * all enumerators have size at most n, where n is the minimal integer
643    * such that (DT_SYGUS_BOUND d_generic_measure_term n) is asserted.
644    */
645   Node d_generic_measure_term;
646   /**
647    * This increments the current search size for measure term m. This may
648    * cause lemmas to be added to lemmas based on the fact that symmetry
649    * breaking lemmas are now relevant for new search terms, see discussion
650    * of how search size affects which lemmas are relevant above
651    * addSymBreakLemmasFor.
652    */
653   void incrementCurrentSearchSize( Node m, std::vector< Node >& lemmas );
654   /**
655    * Notify this class that we are currently searching for terms of size at
656    * most s as model values for measure term m. Literal exp corresponds to the
657    * explanation of why the measure term has size at most n. This calls
658    * incrementSearchSize above, until the total number of times we have called
659    * incrementSearchSize so far is at least s.
660    */
661   void notifySearchSize( Node m, unsigned s, Node exp, std::vector< Node >& lemmas );
662   /** Allocates a SygusSizeDecisionStrategy object in d_szinfo. */
663   void registerMeasureTerm( Node m );
664   /**
665    * Return the current search size for arbitrary term n. This is the current
666    * search size of the anchor of n.
667    */
668   unsigned getSearchSizeFor( Node n );
669   /** return the current search size for enumerator (anchor) e */
670   unsigned getSearchSizeForAnchor(Node e);
671   /** Get the current search size for measure term m in this SAT context. */
672   unsigned getSearchSizeForMeasureTerm(Node m);
673   /** get current template
674    *
675    * For debugging. This returns a term that corresponds to the current
676    * inferred shape of n. For example, if the testers
677    *   is-C1( n ) and is-C2( n.1 )
678    * have been asserted where C1 and C2 are binary constructors, then this
679    * method may return a term of the form:
680    *   C1( C2( x1, x2 ), x3 )
681    * for fresh variables x1, x2, x3. The map var_count maintains the variable
682    * count for generating these fresh variables.
683    */
684   Node getCurrentTemplate( Node n, std::map< TypeNode, int >& var_count );
685   //----------------------end search size information
686   /** check value
687    *
688    * This is called when we have a model assignment vn for n, where n is
689    * a selector chain applied to an enumerator (a search term). This function
690    * ensures that testers have been asserted for each subterm of vn. This is
691    * critical for ensuring that the proper steps have been taken by this class
692    * regarding whether or not vn is a legal value for n (not greater than the
693    * current search size and not a value that can be blocked by symmetry
694    * breaking).
695    *
696    * For example, if vn = +( x(), x() ), then we ensure that the testers
697    *   is-+( n ), is-x( n.1 ), is-x( n.2 )
698    * have been asserted to this class. If a tester is not asserted for some
699    * relevant selector chain S( n ) of n, then we add a lemma L for that
700    * selector chain to lemmas, where L is the "splitting lemma" for S( n ), that
701    * states that the top symbol of S( n ) must be one of the constructors of
702    * its type.
703    *
704    * Notice that this function is a sanity check. Typically, it should be the
705    * case that testers are asserted for all subterms of vn, and hence this
706    * method should not ever add anything to lemmas. However, due to its
707    * importance, we check this regardless.
708    */
709   bool checkValue(Node n, Node vn, int ind, std::vector<Node>& lemmas);
710   /**
711    * Get the current SAT status of the guard g.
712    * In particular, this returns 1 if g is asserted true, -1 if it is asserted
713    * false, and 0 if it is not asserted.
714    */
715   int getGuardStatus( Node g );
716 };
717 
718 }
719 }
720 }
721 
722 #endif
723 
724