summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2020-03-23 17:12:56 -0500
committerGitHub <noreply@github.com>2020-03-23 17:12:56 -0500
commit591b704fa2e02adf2f192c3480e7b0393ed5daf9 (patch)
tree4b6904e299caaa39ce04319c930235703bb163d8 /src
parentdf7333de4436d846da70857e61cda411d22d02ba (diff)
Infer when sygus operators are equivalent to builtin kinds (#4140)
The V2 parser always turns sygus operators into lambdas for consistency. This PR ensures that we nevertheless infer when a sygus operator is equivalent to a builtin operator, e.g. (lambda x y. (+ x y)) is equivalent to +. The main reason this is required is to ensure that solution reconstruction heuristics work optimally when we make the switch SyGuS V1 -> V2 (see 5 failing benchmarks due to --cegqi-si=all on #4136).
Diffstat (limited to 'src')
-rw-r--r--src/theory/quantifiers/sygus/type_info.cpp39
1 files changed, 29 insertions, 10 deletions
diff --git a/src/theory/quantifiers/sygus/type_info.cpp b/src/theory/quantifiers/sygus/type_info.cpp
index a17a60927..7235fd65c 100644
--- a/src/theory/quantifiers/sygus/type_info.cpp
+++ b/src/theory/quantifiers/sygus/type_info.cpp
@@ -97,17 +97,11 @@ void SygusTypeInfo::initialize(TermDbSygus* tds, TypeNode tn)
Node sop = dt[i].getSygusOp();
Assert(!sop.isNull());
Trace("sygus-db") << " Operator #" << i << " : " << sop;
+ Kind builtinKind = UNDEFINED_KIND;
if (sop.getKind() == kind::BUILTIN)
{
- Kind sk = NodeManager::operatorToKind(sop);
- Trace("sygus-db") << ", kind = " << sk;
- d_kinds[sk] = i;
- d_arg_kind[i] = sk;
- if (sk == ITE)
- {
- // mark that this type has an ITE
- d_hasIte = true;
- }
+ builtinKind = NodeManager::operatorToKind(sop);
+ Trace("sygus-db") << ", kind = " << builtinKind;
}
else if (sop.isConst() && dt[i].getNumArgs() == 0)
{
@@ -128,7 +122,32 @@ void SygusTypeInfo::initialize(TermDbSygus* tds, TypeNode tn)
<< "In sygus datatype " << dt.getName()
<< ", argument to a lambda constructor is not " << lat << std::endl;
}
- if (sop[0].getKind() == ITE)
+ // See if it is a builtin kind, possible if the operator is of the form:
+ // lambda x1 ... xn. f( x1, ..., xn ) and f is not a parameterized kind
+ // (e.g. APPLY_UF is a parameterized kind).
+ if (sop[1].getMetaKind() != kind::metakind::PARAMETERIZED)
+ {
+ size_t nchild = sop[0].getNumChildren();
+ if (nchild == sop[1].getNumChildren())
+ {
+ builtinKind = sop[1].getKind();
+ for (size_t j = 0; j < nchild; j++)
+ {
+ if (sop[0][j] != sop[1][j])
+ {
+ // arguments not in order
+ builtinKind = UNDEFINED_KIND;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (builtinKind != UNDEFINED_KIND)
+ {
+ d_kinds[builtinKind] = i;
+ d_arg_kind[i] = builtinKind;
+ if (builtinKind == ITE)
{
// mark that this type has an ITE
d_hasIte = true;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback