summaryrefslogtreecommitdiff
path: root/src/theory/quantifiers/ce_guided_pbe.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/theory/quantifiers/ce_guided_pbe.h')
-rw-r--r--src/theory/quantifiers/ce_guided_pbe.h319
1 files changed, 189 insertions, 130 deletions
diff --git a/src/theory/quantifiers/ce_guided_pbe.h b/src/theory/quantifiers/ce_guided_pbe.h
index e4c252194..ca0190dc0 100644
--- a/src/theory/quantifiers/ce_guided_pbe.h
+++ b/src/theory/quantifiers/ce_guided_pbe.h
@@ -35,7 +35,7 @@ class CegEntailmentInfer;
* that are in Programming-By-Examples (PBE) form.
*
* [EX#1] An example of a synthesis conjecture in PBE form is :
-* exists f. forall x.
+* exists f. forall x.
* ( x = 0 => f( x ) = 2 ) ^ ( x = 5 => f( x ) = 7 ) ^ ( x = 6 => f( x ) = 8 )
*
* We say that the above conjecture has I/O examples (0)->2, (5)->7, (6)->8.
@@ -45,79 +45,104 @@ class CegEntailmentInfer;
* (1) Infers whether the input conjecture is in PBE form or not.
* (2) Based on this information and on the syntactic restrictions, it
* devises a strategy for enumerating terms and construction solutions,
-* which is inspired by Alur et al. "Scaling Enumerative Program Synthesis
-* via Divide and Conquer" TACAS 2017. In particular, it may consider strategies
-* for constructing decision trees when the grammar permits ITEs and a
-* strategy for divide-and-conquer string synthesis when the grammar permits
-* string concatenation. This is stored in a set of data structures within
-* d_cinfo.
-* (3) It makes (possibly multiple) calls to
+* which is inspired by Alur et al. "Scaling Enumerative Program Synthesis
+* via Divide and Conquer" TACAS 2017. In particular, it may consider
+* strategies for constructing decision trees when the grammar permits ITEs
+* and a strategy for divide-and-conquer string synthesis when the grammar
+* permits string concatenation. This is stored in a set of data structures
+* within d_cinfo.
+* (3) It makes (possibly multiple) calls to
* TermDatabaseSygus::registerMeasuredTerm(...) based
* on the strategy, which inform the rest of the system to enumerate values
-* of particular types in the grammar through use of fresh variables which
+* of particular types in the grammar through use of fresh variables which
* we call "enumerators".
*
* Points (1)-(3) happen within a call to CegConjecturePbe::initialize(...).
*
-* Notice that each enumerator is associated with a single function-to-synthesize,
+* Notice that each enumerator is associated with a single
+* function-to-synthesize,
* but a function-to-sythesize may be mapped to multiple enumerators.
* Some public functions of this class expect an enumerator as input, which we
-* map to a function-to-synthesize via getSynthFunctionForEnumerator.
+* map to a function-to-synthesize via TermDatabaseSygus::getSynthFunFor(e).
*
* An enumerator is initially "active" but may become inactive if the enumeration
-* exhausts all possible values in the datatype corresponding to syntactic restrictions
+* exhausts all possible values in the datatype corresponding to syntactic
+* restrictions
* for it. The search may continue unless all enumerators become inactive.
*
-* (4) During search, the extension of quantifier-free datatypes procedure for SyGuS
-* datatypes may ask this class whether current candidates can be discarded based on
-* inferring when two candidate solutions are equivalent up to examples.
-* For example, the candidate solutions:
-* f = \x ite( x<0, x+1, x ) and f = \x x
-* are equivalent up to examples on the above conjecture, since they have the same
-* value on the points x = 0,5,6. Hence, we need only consider one of them.
-* The interface for querying this is CegConjecturePbe::addSearchVal(...).
+* (4) During search, the extension of quantifier-free datatypes procedure for
+* SyGuS datatypes may ask this class whether current candidates can be
+* discarded based on
+* inferring when two candidate solutions are equivalent up to examples.
+* For example, the candidate solutions:
+* f = \x ite( x<0, x+1, x ) and f = \x x
+* are equivalent up to examples on the above conjecture, since they have the
+* same value on the points x = 0,5,6. Hence, we need only consider one of
+* them. The interface for querying this is
+* CegConjecturePbe::addSearchVal(...).
* For details, see Reynolds et al. SYNT 2017.
-*
-* (5) When the extension of quantifier-free datatypes procedure for SyGuS datatypes
-* terminates with a model, the parent of this class calls
-* CegConjecturePbe::getCandidateList(...), where this class returns the list of
-* active enumerators.
-* (6) The parent class subsequently calls CegConjecturePbe::constructValues(...), which
-* informs this class that new values have been enumerated for active enumerators,
-* as indicated by the current model. This call also requests that based on these
-* newly enumerated values, whether this class is now able to construct a solution
-* based on the high-level strategy (stored in d_c_info).
*
-* This class is not designed to work in incremental mode, since there is no way to
+* (5) When the extension of quantifier-free datatypes procedure for SyGuS
+* datatypes terminates with a model, the parent of this class calls
+* CegConjecturePbe::getCandidateList(...), where this class returns the list
+* of active enumerators.
+* (6) The parent class subsequently calls
+* CegConjecturePbe::constructValues(...), which
+* informs this class that new values have been enumerated for active
+* enumerators, as indicated by the current model. This call also requests
+* that based on these
+* newly enumerated values, whether this class is now able to construct a
+* solution based on the high-level strategy (stored in d_c_info).
+*
+* This class is not designed to work in incremental mode, since there is no way
+* to
* specify incremental problems in SyguS.
*
*/
class CegConjecturePbe {
-public:
- CegConjecturePbe( QuantifiersEngine * qe, CegConjecture * p );
+ public:
+ CegConjecturePbe(QuantifiersEngine* qe, CegConjecture* p);
~CegConjecturePbe();
-
- /** initialize this class */
- void initialize( Node n, std::vector< Node >& candidates, std::vector< Node >& lemmas );
+
+ /** initialize this class
+ *
+ * n is the "base instantiation" of the deep-embedding version of
+ * the synthesis conjecture under "candidates".
+ * (see CegConjecture::d_base_inst)
+ *
+ * This function may add lemmas to the vector lemmas corresponding
+ * to initial lemmas regarding static analysis of enumerators it
+ * introduced. For example, we may say that the top-level symbol
+ * of an enumerator is not ITE if it is being used to construct
+ * return values for decision trees.
+ */
+ void initialize(Node n,
+ std::vector<Node>& candidates,
+ std::vector<Node>& lemmas);
/** get candidate list
- * Adds all active enumerators associated with functions-to-synthesize in candidates to clist.
+ * Adds all active enumerators associated with functions-to-synthesize in
+ * candidates to clist.
*/
- void getCandidateList( std::vector< Node >& candidates, std::vector< Node >& clist );
- /** construct candidates
- * (1) Indicates that the list of enumerators in "enums" currently have model values "enum_values".
- * (2) Asks whether based on these new enumerated values, we can construct a solution for
- * the functions-to-synthesize in "candidates". If so, this function returns "true" and
+ void getCandidateList(std::vector<Node>& candidates,
+ std::vector<Node>& clist);
+ /** construct candidates
+ * (1) Indicates that the list of enumerators in "enums" currently have model
+ * values "enum_values".
+ * (2) Asks whether based on these new enumerated values, we can construct a
+ * solution for
+ * the functions-to-synthesize in "candidates". If so, this function
+ * returns "true" and
* adds solutions for candidates into "candidate_values".
- * During this class, this class may add auxiliary lemmas to "lems", which the caller
- * should send on the output channel via lemma(...).
+ * During this class, this class may add auxiliary lemmas to "lems", which the
+ * caller should send on the output channel via lemma(...).
*/
- bool constructCandidates( std::vector< Node >& enums, std::vector< Node >& enum_values,
- std::vector< Node >& candidates, std::vector< Node >& candidate_values,
- std::vector< Node >& lems );
+ bool constructCandidates(std::vector<Node>& enums,
+ std::vector<Node>& enum_values,
+ std::vector<Node>& candidates,
+ std::vector<Node>& candidate_values,
+ std::vector<Node>& lems);
/** is PBE enabled for any enumerator? */
bool isPbe() { return d_is_pbe; }
- /** get candidate for enumerator */
- Node getSynthFunctionForEnumerator(Node e);
/** is the enumerator e associated with I/O example pairs? */
bool hasExamples(Node e);
/** get number of I/O example pairs for enumerator e */
@@ -127,33 +152,38 @@ public:
void getExample(Node e, unsigned i, std::vector<Node>& ex);
/** get the output value of the i^th I/O example for enumerator e */
Node getExampleOut(Node e, unsigned i);
-
+
/** add the search val
- * This function is called by the extension of quantifier-free datatypes procedure
- * for SyGuS datatypes when we are considering a value of enumerator e of sygus
- * type tn whose analog in the signature of builtin theory is bvr.
- *
- * For example, bvr = x + 1 when e is the datatype value Plus( x(), One() ) and
+ * This function is called by the extension of quantifier-free datatypes
+ * procedure for SyGuS datatypes when we are considering a value of
+ * enumerator e of sygus type tn whose analog in the signature of builtin
+ * theory is bvr.
+ *
+ * For example, bvr = x + 1 when e is the datatype value Plus( x(), One() ) and
* tn is a sygus datatype that encodes a subsignature of the integers.
*
* This returns either:
- * - A SyGuS term whose analog is equivalent to bvr up to examples, in the above example,
- * it may return a term t of the form Plus( One(), x() ), such that this function was
- * previously called with t as input.
+ * - A SyGuS term whose analog is equivalent to bvr up to examples, in the
+ * above example,
+ * it may return a term t of the form Plus( One(), x() ), such that this
+ * function was previously called with t as input.
* - e, indicating that no previous terms are equivalent to e up to examples.
*/
Node addSearchVal(TypeNode tn, Node e, Node bvr);
/** evaluate builtin
- * This returns the evaluation of bn on the i^th example for the function-to-synthesis
- * associated with enumerator e. If there are not at least i examples, it returns
- * the rewritten form of bn.
- * For example, if bn = x+5, e is an enumerator for f in the above example [EX#1], then
+ * This returns the evaluation of bn on the i^th example for the
+ * function-to-synthesis
+ * associated with enumerator e. If there are not at least i examples, it
+ * returns the rewritten form of bn.
+ * For example, if bn = x+5, e is an enumerator for f in the above example
+ * [EX#1], then
* evaluateBuiltin( tn, bn, e, 0 ) = 7
* evaluateBuiltin( tn, bn, e, 1 ) = 9
* evaluateBuiltin( tn, bn, e, 2 ) = 10
*/
- Node evaluateBuiltin(TypeNode tn, Node bn, Node e, unsigned i);
-private:
+ Node evaluateBuiltin(TypeNode tn, Node bn, Node e, unsigned i);
+
+ private:
/** quantifiers engine associated with this class */
QuantifiersEngine* d_qe;
/** sygus term database of d_qe */
@@ -162,7 +192,8 @@ private:
Node d_true;
Node d_false;
/** parent conjecture
- * This is the data structure that contains global information about the conjecture.
+ * This is the data structure that contains global information about the
+ * conjecture.
*/
CegConjecture* d_parent;
/** is this a PBE conjecture for any function? */
@@ -180,7 +211,8 @@ private:
* exists f. forall x. ( x = 0 => f( x ) > 2 )
* another example is:
* exists f. forall x. ( ( x = 0 => f( x ) = 2 ) V ( x = 3 => f( x ) = 3 ) )
- * since the formula is not a conjunction (the example values are not entailed).
+ * since the formula is not a conjunction (the example values are not
+ * entailed).
* However, the domain of f in both cases is finite, which can be used for
* search space pruning.
*/
@@ -191,26 +223,20 @@ private:
/** for each candidate variable (function-to-synthesize), output of I/O
* examples */
std::map< Node, std::vector< Node > > d_examples_out;
- /** the list of example terms
- * For the example [EX#1] above, this is f( 0 ), f( 5 ), f( 6 )
+ /** the list of example terms
+ * For the example [EX#1] above, this is f( 0 ), f( 5 ), f( 6 )
*/
std::map< Node, std::vector< Node > > d_examples_term;
- /** map from enumerators to candidate varaibles (function-to-synthesize). An
- * enumerator may not be equivalent
- * to the candidate variable it maps so in synthesis-through-unification
- * approaches (e.g. decision tree construction).
- */
- std::map<Node, Node> d_enum_to_candidate;
- /** collect the PBE examples in n
+ /** collect the PBE examples in n
* This is called on the input conjecture, and will populate the above vectors.
* hasPol/pol denote the polarity of n in the conjecture.
*/
void collectExamples( Node n, std::map< Node, bool >& visited, bool hasPol, bool pol );
-
+
//--------------------------------- PBE search values
/** this class is an index of candidate solutions for PBE synthesis */
class PbeTrie {
- public:
+ public:
PbeTrie() {}
~PbeTrie() {}
Node d_lazy_child;
@@ -218,7 +244,8 @@ private:
void clear() { d_children.clear(); }
Node addPbeExample(TypeNode etn, Node e, Node b, CegConjecturePbe* cpbe,
unsigned index, unsigned ntotal);
- private:
+
+ private:
Node addPbeExampleEval(TypeNode etn, Node e, Node b, std::vector<Node>& ex,
CegConjecturePbe* cpbe, unsigned index,
unsigned ntotal);
@@ -231,9 +258,9 @@ private:
*/
std::map<Node, std::map<TypeNode, PbeTrie> > d_pbe_trie;
//--------------------------------- end PBE search values
-
+
// -------------------------------- decision tree learning
- //index filter
+ // index filter
class IndexFilter {
public:
IndexFilter(){}
@@ -243,7 +270,7 @@ private:
unsigned next( unsigned i );
void clear() { d_next.clear(); }
bool isEq( std::vector< Node >& vs, Node v );
- };
+ };
// subsumption trie
class SubsumeTrie {
public:
@@ -265,22 +292,37 @@ private:
d_term = Node::null();
d_children.clear();
}
- private:
+
+ private:
/** the term at this node */
Node d_term;
/** the children nodes of this trie */
- std::map< Node, SubsumeTrie > d_children;
+ std::map<Node, SubsumeTrie> d_children;
/** helper function for above functions */
- Node addTermInternal( CegConjecturePbe * pbe, Node t, std::vector< Node >& vals, bool pol, std::vector< Node >& subsumed, bool spol, IndexFilter * f,
- unsigned index, int status, bool checkExistsOnly, bool checkSubsume );
+ Node addTermInternal(CegConjecturePbe* pbe,
+ Node t,
+ std::vector<Node>& vals,
+ bool pol,
+ std::vector<Node>& subsumed,
+ bool spol,
+ IndexFilter* f,
+ unsigned index,
+ int status,
+ bool checkExistsOnly,
+ bool checkSubsume);
/** helper function for above functions */
- void getLeavesInternal( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol, std::map< int, std::vector< Node > >& v, IndexFilter * f,
- unsigned index, int status );
+ void getLeavesInternal(CegConjecturePbe* pbe,
+ std::vector<Node>& vals,
+ bool pol,
+ std::map<int, std::vector<Node> >& v,
+ IndexFilter* f,
+ unsigned index,
+ int status);
};
// -------------------------------- end decision tree learning
-
+
//------------------------------ representation of a enumeration strategy
-
+
/** roles for enumerators */
enum {
enum_io,
@@ -289,36 +331,39 @@ private:
enum_any,
};
/** print the role with Trace c. */
- static void print_role( const char * c, unsigned r );
+ static void print_role(const char* c, unsigned r);
/** strategies for SyGuS datatype types */
- enum {
+ enum
+ {
strat_ITE,
strat_CONCAT,
strat_ID,
- };
+ };
/** print the strategy with Trace c. */
- static void print_strat( const char * c, unsigned s );
-
+ static void print_strat(const char* c, unsigned s);
+
/** information about an enumerator */
class EnumInfo {
public:
EnumInfo() : d_role( enum_io ){}
- /** initialize this class
- * c is the parent function-to-synthesize
+ /** initialize this class
+ * c is the parent function-to-synthesize
* role is the "role" the enumerator plays in the high-level strategy,
* which is one of enum_* above.
*/
- void initialize( Node c, unsigned role ){
+ void initialize(Node c, unsigned role)
+ {
d_parent_candidate = c;
d_role = role;
}
bool isTemplated() { return !d_template.isNull(); }
- void addEnumValue( CegConjecturePbe * pbe, Node v, std::vector< Node >& results );
- void setSolved( Node slv );
+ void addEnumValue(CegConjecturePbe* pbe,
+ Node v,
+ std::vector<Node>& results);
+ void setSolved(Node slv);
bool isSolved() { return !d_enum_solved.isNull(); }
Node getSolved() { return d_enum_solved; }
unsigned getRole() { return d_role; }
-
Node d_parent_candidate;
// for template
Node d_template;
@@ -335,16 +380,17 @@ private:
std::vector< Node > d_enum_subsume;
std::map< Node, unsigned > d_enum_val_to_index;
SubsumeTrie d_term_trie;
- private:
- /** whether an enumerated value for this conjecture has solved the entire conjecture */
+
+ private:
+ /** whether an enumerated value for this conjecture has solved the entire
+ * conjecture */
Node d_enum_solved;
/** the role of this enumerator (one of enum_* above). */
unsigned d_role;
};
/** maps enumerators to the information above */
std::map< Node, EnumInfo > d_einfo;
-
-
+
class CandidateInfo;
/** represents a strategy for a SyGuS datatype type */
class EnumTypeInfoStrat {
@@ -354,8 +400,7 @@ private:
std::vector< TypeNode > d_csol_cts;
std::vector< Node > d_cenum;
};
-
-
+
/** stores enumerators and strategies for a SyGuS datatype type */
class EnumTypeInfo {
public:
@@ -368,9 +413,9 @@ private:
std::map< Node, EnumTypeInfoStrat > d_strat;
bool isSolved( CegConjecturePbe * pbe );
};
-
-
- /** stores strategy and enumeration information for a function-to-synthesize */
+
+ /** stores strategy and enumeration information for a function-to-synthesize
+ */
class CandidateInfo {
public:
CandidateInfo() : d_check_sol( false ), d_cond_count( 0 ){}
@@ -380,7 +425,8 @@ private:
* of solutions.
*/
TypeNode d_root;
- /** Information for each SyGuS datatype type occurring in a field of d_root */
+ /** Information for each SyGuS datatype type occurring in a field of d_root
+ */
std::map< TypeNode, EnumTypeInfo > d_tinfo;
/** list of all enumerators for the function-to-synthesize */
std::vector< Node > d_esym_list;
@@ -396,24 +442,31 @@ private:
};
/** maps a function-to-synthesize to the above information */
std::map< Node, CandidateInfo > d_cinfo;
-
+
//------------------------------ representation of an enumeration strategy
/** add enumerated value */
void addEnumeratedValue( Node x, Node v, std::vector< Node >& lems );
bool getExplanationForEnumeratorExclude( Node c, Node x, Node v, std::vector< Node >& results, EnumInfo& ei, std::vector< Node >& exp );
-
+
//------------------------------ strategy registration
- void collectEnumeratorTypes( Node c, TypeNode tn, unsigned enum_role );
- void registerEnumerator( Node et, Node c, TypeNode tn, unsigned enum_role, bool inSearch );
- void staticLearnRedundantOps( Node c, std::vector< Node >& lemmas );
- void staticLearnRedundantOps( Node c, Node e, std::map< Node, bool >& visited, std::vector< Node >& redundant,
- std::vector< Node >& lemmas, int ind );
+ void collectEnumeratorTypes(Node c, TypeNode tn, unsigned enum_role);
+ void registerEnumerator(
+ Node et, Node c, TypeNode tn, unsigned enum_role, bool inSearch);
+ void staticLearnRedundantOps(Node c, std::vector<Node>& lemmas);
+ void staticLearnRedundantOps(Node c,
+ Node e,
+ std::map<Node, bool>& visited,
+ std::vector<Node>& redundant,
+ std::vector<Node>& lemmas,
+ int ind);
/** register candidate conditional */
- bool inferTemplate( unsigned k, Node n, std::map< Node, unsigned >& templ_var_index, std::map< unsigned, unsigned >& templ_injection );
- //------------------------------ end strategy registration
-
-
+ bool inferTemplate(unsigned k,
+ Node n,
+ std::map<Node, unsigned>& templ_var_index,
+ std::map<unsigned, unsigned>& templ_injection);
+ //------------------------------ end strategy registration
+
//------------------------------ constructing solutions
class UnifContext {
public:
@@ -453,16 +506,22 @@ private:
* in context x, where ind is the term depth of the context.
*/
Node constructSolution( Node c, Node e, UnifContext& x, int ind );
- /** Heuristically choose the best solved term from solved in context x, currently return the first. */
+ /** Heuristically choose the best solved term from solved in context x,
+ * currently return the first. */
Node constructBestSolvedTerm( std::vector< Node >& solved, UnifContext& x );
- /** Heuristically choose the best solved string term from solved in context x, currently return the first. */
+ /** Heuristically choose the best solved string term from solved in context
+ * x, currently return the first. */
Node constructBestStringSolvedTerm( std::vector< Node >& solved, UnifContext& x );
- /** heuristically choose the best solved conditional term from solved in context x, currently random */
+ /** heuristically choose the best solved conditional term from solved in
+ * context x, currently random */
Node constructBestSolvedConditional( std::vector< Node >& solved, UnifContext& x );
- /** heuristically choose the best conditional term from conds in context x, currently random */
+ /** heuristically choose the best conditional term from conds in context x,
+ * currently random */
Node constructBestConditional( std::vector< Node >& conds, UnifContext& x );
- /** heuristically choose the best string to concatenate from strs to the solution in context x, currently random
- * incr stores the vector of indices that are incremented by this solution in example outputs.
+ /** heuristically choose the best string to concatenate from strs to the
+ * solution in context x, currently random
+ * incr stores the vector of indices that are incremented by this solution in
+ * example outputs.
* total_inc[x] is the sum of incr[x] for each x in strs.
*/
Node constructBestStringToConcat( std::vector< Node > strs,
@@ -470,13 +529,13 @@ private:
std::map< Node, std::vector< unsigned > > incr,
UnifContext& x );
//------------------------------ end constructing solutions
-
- /** get guard status
+
+ /** get guard status
* Returns 1 if g is asserted true in the SAT solver.
* Returns -1 if g is asserted false in the SAT solver.
* Returns 0 otherwise.
*/
- int getGuardStatus( Node g );
+ int getGuardStatus(Node g);
};
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback