summaryrefslogtreecommitdiff
path: root/src/theory/quantifiers/sygus/sygus_invariance.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/theory/quantifiers/sygus/sygus_invariance.h')
-rw-r--r--src/theory/quantifiers/sygus/sygus_invariance.h276
1 files changed, 276 insertions, 0 deletions
diff --git a/src/theory/quantifiers/sygus/sygus_invariance.h b/src/theory/quantifiers/sygus/sygus_invariance.h
new file mode 100644
index 000000000..a43e38719
--- /dev/null
+++ b/src/theory/quantifiers/sygus/sygus_invariance.h
@@ -0,0 +1,276 @@
+/********************* */
+/*! \file sygus_invariance.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2017 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief sygus invariance tests
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__QUANTIFIERS__SYGUS_INVARIANCE_H
+#define __CVC4__THEORY__QUANTIFIERS__SYGUS_INVARIANCE_H
+
+#include <unordered_map>
+#include <vector>
+
+#include "expr/node.h"
+
+namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+
+class TermDbSygus;
+class CegConjecture;
+
+/* SygusInvarianceTest
+*
+* This class is the standard interface for term generalization
+* in SyGuS. Its interface is a single function is_variant,
+* which is a virtual condition for SyGuS terms.
+*
+* The common use case of invariance tests is when constructing
+* minimal explanations for refinement lemmas in the
+* counterexample-guided inductive synthesis (CEGIS) loop.
+* See sygus_explain.h for more details.
+*/
+class SygusInvarianceTest
+{
+ public:
+ virtual ~SygusInvarianceTest() {}
+
+ /** Is nvn invariant with respect to this test ?
+ *
+ * - nvn is the term to check whether it is invariant.
+ * - x is a variable such that the previous call to
+ * is_invariant (if any) was with term nvn_prev, and
+ * nvn is equal to nvn_prev with some subterm
+ * position replaced by x. This is typically used
+ * for debugging only.
+ */
+ bool is_invariant(TermDbSygus* tds, Node nvn, Node x)
+ {
+ if (invariant(tds, nvn, x))
+ {
+ d_update_nvn = nvn;
+ return true;
+ }
+ return false;
+ }
+ /** get updated term */
+ Node getUpdatedTerm() { return d_update_nvn; }
+ /** set updated term */
+ void setUpdatedTerm(Node n) { d_update_nvn = n; }
+ protected:
+ /** result of the node that satisfies this invariant */
+ Node d_update_nvn;
+ /** check whether nvn[ x ] is invariant */
+ virtual bool invariant(TermDbSygus* tds, Node nvn, Node x) = 0;
+};
+
+/** EquivSygusInvarianceTest
+*
+* This class tests whether a term evaluates via evaluation
+* operators in the deep embedding (Section 4 of Reynolds
+* et al. CAV 2015) to fixed term d_result.
+*
+* For example, consider a SyGuS evaluation function eval
+* for a synthesis conjecture with arguments x and y.
+* Notice that the term t = (mult x y) is such that:
+* eval( t, 0, 1 ) ----> 0
+* This test is invariant on the content of the second
+* argument of t, noting that:
+* eval( (mult x _), 0, 1 ) ----> 0
+* as well, via a call to EvalSygusInvarianceTest::invariant.
+*
+* Another example, t = ite( gt( x, y ), x, y ) is such that:
+* eval( t, 2, 3 ) ----> 3
+* This test is invariant on the second child of t, noting:
+* eval( ite( gt( x, y ), _, y ), 2, 3 ) ----> 3
+*/
+class EvalSygusInvarianceTest : public SygusInvarianceTest
+{
+ public:
+ EvalSygusInvarianceTest() {}
+
+ /** initialize this invariance test
+ * This sets d_conj/d_var/d_result, where
+ * we are checking whether:
+ * d_conj { d_var -> n } ----> d_result.
+ * for terms n.
+ */
+ void init(Node conj, Node var, Node res);
+
+ /** do evaluate with unfolding, using the cache of this class */
+ Node doEvaluateWithUnfolding(TermDbSygus* tds, Node n);
+
+ protected:
+ /** does d_conj{ d_var -> nvn } still rewrite to d_result? */
+ bool invariant(TermDbSygus* tds, Node nvn, Node x);
+
+ private:
+ /** the formula we are evaluating */
+ Node d_conj;
+ /** the variable */
+ TNode d_var;
+ /** the result of the evaluation */
+ Node d_result;
+ /** cache of n -> the simplified form of eval( n ) */
+ std::unordered_map<Node, Node, NodeHashFunction> d_visited;
+};
+
+/** EquivSygusInvarianceTest
+*
+* This class tests whether a builtin version of a
+* sygus term is equivalent up to rewriting to a RHS value bvr.
+*
+* For example,
+*
+* ite( t>0, 0, 0 ) + s*0 ----> 0
+*
+* This test is invariant on the condition t>0 and s, since:
+*
+* ite( _, 0, 0 ) + _*0 ----> 0
+*
+* for any values of _.
+*
+* It also manages the case where the rewriting is invariant
+* wrt a finite set of examples occurring in the conjecture.
+* (EX1) : For example if our input examples are:
+* (x,y,z) = (3,2,4), (5,2,6), (3,2,1)
+* On these examples, we have:
+*
+* ite( x>y, z, 0) ---> 4,6,1
+*
+* which is invariant on the second argument:
+*
+* ite( x>y, z, _) ---> 4,6,1
+*
+* For details, see Reynolds et al SYNT 2017.
+*/
+class EquivSygusInvarianceTest : public SygusInvarianceTest
+{
+ public:
+ EquivSygusInvarianceTest() : d_conj(nullptr) {}
+
+ /** initialize this invariance test
+ * tn is the sygus type for e
+ * aconj/e are used for conjecture-specific symmetry breaking
+ * bvr is the builtin version of the right hand side of the rewrite that we
+ * are checking for invariance
+ */
+ void init(
+ TermDbSygus* tds, TypeNode tn, CegConjecture* aconj, Node e, Node bvr);
+
+ protected:
+ /** checks whether the analog of nvn still rewrites to d_bvr */
+ bool invariant(TermDbSygus* tds, Node nvn, Node x);
+
+ private:
+ /** the conjecture associated with the enumerator d_enum */
+ CegConjecture* d_conj;
+ /** the enumerator associated with the term for which this test is for */
+ Node d_enum;
+ /** the RHS of the evaluation */
+ Node d_bvr;
+ /** the result of the examples
+ * In (EX1), this is (4,6,1)
+ */
+ std::vector<Node> d_exo;
+};
+
+/** DivByZeroSygusInvarianceTest
+ *
+ * This class tests whether a sygus term involves
+ * division by zero.
+ *
+ * For example the test for:
+ * ( x + ( y/0 )*2 )
+ * is invariant on the contents of _ below:
+ * ( _ + ( _/0 )*_ )
+ */
+class DivByZeroSygusInvarianceTest : public SygusInvarianceTest
+{
+ public:
+ DivByZeroSygusInvarianceTest() {}
+
+ protected:
+ /** checks whether nvn involves division by zero. */
+ bool invariant(TermDbSygus* tds, Node nvn, Node x);
+};
+
+/** NegContainsSygusInvarianceTest
+*
+* This class is used to construct a minimal shape of a term that cannot
+* be contained in at least one output of an I/O pair.
+*
+* Say our PBE conjecture is:
+*
+* exists f.
+* f( "abc" ) = "abc abc" ^
+* f( "de" ) = "de de"
+*
+* Then, this class is used when there is a candidate solution t[x1]
+* such that either:
+* contains( "abc abc", t["abc"] ) ---> false or
+* contains( "de de", t["de"] ) ---> false
+*
+* It is used to determine whether certain generalizations of t[x1]
+* are still sufficient to falsify one of the above containments.
+*
+* For example:
+*
+* The test for str.++( x1, "d" ) is invariant on its first argument
+* ...since contains( "abc abc", str.++( _, "d" ) ) ---> false
+* The test for str.replace( "de", x1, "b" ) is invariant on its third argument
+* ...since contains( "abc abc", str.replace( "de", "abc", _ ) ) ---> false
+*/
+class NegContainsSygusInvarianceTest : public SygusInvarianceTest
+{
+ public:
+ NegContainsSygusInvarianceTest() : d_conj(nullptr) {}
+
+ /** initialize this invariance test
+ * cpbe is the conjecture utility.
+ * e is the enumerator which we are reasoning about (associated with a synth
+ * fun).
+ * exo is the list of outputs of the PBE conjecture.
+ * ncind is the set of possible indices of the PBE conjecture to check
+ * invariance of non-containment.
+ * For example, in the above example, when t[x1] = "ab", then this
+ * has the index 1 since contains("de de", "ab") ---> false but not
+ * the index 0 since contains("abc abc","ab") ---> true.
+ */
+ void init(CegConjecture* conj,
+ Node e,
+ std::vector<Node>& exo,
+ std::vector<unsigned>& ncind);
+
+ protected:
+ /** checks if contains( out_i, nvn[in_i] ) --> false for some I/O pair i. */
+ bool invariant(TermDbSygus* tds, Node nvn, Node x);
+
+ private:
+ /** The enumerator whose value we are considering in this invariance test */
+ Node d_enum;
+ /** The output examples for the enumerator */
+ std::vector<Node> d_exo;
+ /** The set of I/O pair indices i such that
+ * contains( out_i, nvn[in_i] ) ---> false
+ */
+ std::vector<unsigned> d_neg_con_indices;
+ /** reference to the conjecture associated with this test */
+ CegConjecture* d_conj;
+};
+
+} /* CVC4::theory::quantifiers namespace */
+} /* CVC4::theory namespace */
+} /* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__QUANTIFIERS__SYGUS_INVARIANCE_H */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback