From: Andrew Reynolds Date: Sat, 21 Apr 2018 12:01:59 +0000 (-0500) Subject: Improve sygus sampling for strings (#1802) X-Git-Tag: cvc5-1.0.0~5130 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=28e9077fad9d5c61c61a1762e7cf021c226cb9c2;p=cvc5.git Improve sygus sampling for strings (#1802) --- diff --git a/src/theory/quantifiers/sygus_sampler.cpp b/src/theory/quantifiers/sygus_sampler.cpp index 18e13fd59..757256fc3 100644 --- a/src/theory/quantifiers/sygus_sampler.cpp +++ b/src/theory/quantifiers/sygus_sampler.cpp @@ -84,7 +84,9 @@ void SygusSampler::initialize(TypeNode tn, d_vars.clear(); d_rvalue_cindices.clear(); d_rvalue_null_cindices.clear(); + d_rstring_alphabet.clear(); d_var_sygus_types.clear(); + d_const_sygus_types.clear(); d_vars.insert(d_vars.end(), vars.begin(), vars.end()); std::map type_to_type_id; unsigned type_id_counter = 0; @@ -521,13 +523,63 @@ Node SygusSampler::getRandomValue(TypeNode tn) } else if (tn.isString() || tn.isInteger()) { + // if string, determine the alphabet + if (tn.isString() && d_rstring_alphabet.empty()) + { + Trace("sygus-sample-str-alpha") + << "Setting string alphabet..." << std::endl; + std::unordered_set alphas; + for (const std::pair >& c : + d_const_sygus_types) + { + if (c.first.getType().isString()) + { + Trace("sygus-sample-str-alpha") + << "...have constant " << c.first << std::endl; + Assert(c.first.isConst()); + std::vector svec = c.first.getConst().getVec(); + for (unsigned ch : svec) + { + alphas.insert(ch); + } + } + } + // can limit to 1 extra characters beyond those in the grammar (2 if + // there are none in the grammar) + unsigned num_fresh_char = alphas.empty() ? 2 : 1; + unsigned fresh_char = 0; + for (unsigned i = 0; i < num_fresh_char; i++) + { + while (alphas.find(fresh_char) != alphas.end()) + { + fresh_char++; + } + alphas.insert(fresh_char); + } + Trace("sygus-sample-str-alpha") + << "Sygus sampler: limit strings alphabet to : " << std::endl + << " "; + for (unsigned ch : alphas) + { + d_rstring_alphabet.push_back(ch); + Trace("sygus-sample-str-alpha") + << " \"" << String::convertUnsignedIntToChar(ch) << "\""; + } + Trace("sygus-sample-str-alpha") << std::endl; + } + std::vector vec; double ext_freq = .5; - unsigned base = 10; + unsigned base = tn.isString() ? d_rstring_alphabet.size() : 10; while (Random::getRandom().pickWithProb(ext_freq)) { // add a digit - vec.push_back(Random::getRandom().pick(0, base)); + unsigned digit = Random::getRandom().pick(0, base - 1); + if (tn.isString()) + { + digit = d_rstring_alphabet[digit]; + } + vec.push_back(digit); } if (tn.isString()) { @@ -680,6 +732,10 @@ void SygusSampler::registerSygusType(TypeNode tn) if (dtc.getNumArgs() == 0) { d_rvalue_null_cindices[tn].push_back(i); + if (sop.isConst()) + { + d_const_sygus_types[sop].push_back(tn); + } } } // recurse on all subfields diff --git a/src/theory/quantifiers/sygus_sampler.h b/src/theory/quantifiers/sygus_sampler.h index a66e7ee21..b741b60d4 100644 --- a/src/theory/quantifiers/sygus_sampler.h +++ b/src/theory/quantifiers/sygus_sampler.h @@ -335,8 +335,12 @@ class SygusSampler : public LazyTrieEvaluator std::map > d_rvalue_cindices; /** map from sygus types to non-variable nullary constructors */ std::map > d_rvalue_null_cindices; + /** the random string alphabet */ + std::vector d_rstring_alphabet; /** map from variables to sygus types that include them */ std::map > d_var_sygus_types; + /** map from constants to sygus types that include them */ + std::map > d_const_sygus_types; /** register sygus type, intializes the above two data structures */ void registerSygusType(TypeNode tn); };