diff options
Diffstat (limited to 'src')
714 files changed, 12977 insertions, 10018 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index cd7491c6a..45e5c6627 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -55,7 +55,6 @@ libcvc4_la_SOURCES = \ context/context.h \ context/context_mm.cpp \ context/context_mm.h \ - context/stacking_vector.h \ decision/decision_attributes.h \ decision/decision_engine.cpp \ decision/decision_engine.h \ @@ -357,6 +356,8 @@ libcvc4_la_SOURCES = \ theory/quantifiers/ce_guided_single_inv.h \ theory/quantifiers/ce_guided_single_inv_ei.cpp \ theory/quantifiers/ce_guided_single_inv_ei.h \ + theory/quantifiers/ce_guided_pbe.cpp \ + theory/quantifiers/ce_guided_pbe.h \ theory/quantifiers/ce_guided_single_inv_sol.cpp \ theory/quantifiers/ce_guided_single_inv_sol.h \ theory/quantifiers/ceg_instantiator.cpp \ @@ -415,6 +416,8 @@ libcvc4_la_SOURCES = \ theory/quantifiers/symmetry_breaking.h \ theory/quantifiers/term_database.cpp \ theory/quantifiers/term_database.h \ + theory/quantifiers/term_database_sygus.cpp \ + theory/quantifiers/term_database_sygus.h \ theory/quantifiers/theory_quantifiers.cpp \ theory/quantifiers/theory_quantifiers.h \ theory/quantifiers/theory_quantifiers_type_rules.h \ diff --git a/src/base/Makefile.am b/src/base/Makefile.am index bf919cd81..491baaa90 100644 --- a/src/base/Makefile.am +++ b/src/base/Makefile.am @@ -26,9 +26,7 @@ libbase_la_SOURCES = \ listener.h \ modal_exception.h \ output.cpp \ - output.h \ - ptr_closer.h - + output.h BUILT_SOURCES = \ diff --git a/src/base/configuration.cpp b/src/base/configuration.cpp index db19469fd..90e560962 100644 --- a/src/base/configuration.cpp +++ b/src/base/configuration.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Francois Bobot, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/configuration.h b/src/base/configuration.h index 5d499174f..9a6abdb53 100644 --- a/src/base/configuration.h +++ b/src/base/configuration.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Francois Bobot ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/configuration_private.h b/src/base/configuration_private.h index f0ef1a795..93133be24 100644 --- a/src/base/configuration_private.h +++ b/src/base/configuration_private.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Christopher L. Conway, ACSYS ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -149,8 +149,9 @@ This is CVC4 version " CVC4_RELEASE_STRING ) + \ )) + "\n\ compiled with " + ::CVC4::Configuration::getCompiler() + "\n\ on " + ::CVC4::Configuration::getCompiledDateTime() + "\n\n\ -Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014\n\ - New York University and The University of Iowa\n\n" + \ +Copyright (c) 2009-2017\n\ +by the authors and their institutional affiliations listed at \n\ +http://cvc4.cs.stanford.edu/authors\n\n" + \ ( IS_GPL_BUILD ? "\ This build of CVC4 uses GPLed libraries, and is thus covered by the GNU\n\ General Public License (GPL) version 3. Versions of CVC4 are available\n\ diff --git a/src/base/cvc4_assert.cpp b/src/base/cvc4_assert.cpp index 9d578dc07..c122667f3 100644 --- a/src/base/cvc4_assert.cpp +++ b/src/base/cvc4_assert.cpp @@ -2,9 +2,9 @@ /*! \file cvc4_assert.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/cvc4_assert.h b/src/base/cvc4_assert.h index de557330b..d4942f47c 100644 --- a/src/base/cvc4_assert.h +++ b/src/base/cvc4_assert.h @@ -2,9 +2,9 @@ /*! \file cvc4_assert.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/exception.cpp b/src/base/exception.cpp index 4f62f68db..7df050726 100644 --- a/src/base/exception.cpp +++ b/src/base/exception.cpp @@ -2,9 +2,9 @@ /*! \file exception.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/exception.h b/src/base/exception.h index 8f3016e4e..1ce2ae757 100644 --- a/src/base/exception.h +++ b/src/base/exception.h @@ -2,9 +2,9 @@ /*! \file exception.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/listener.cpp b/src/base/listener.cpp index 1f7c6158b..c63630581 100644 --- a/src/base/listener.cpp +++ b/src/base/listener.cpp @@ -2,9 +2,9 @@ /*! \file listener.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/listener.h b/src/base/listener.h index 724935ae7..208dcd14e 100644 --- a/src/base/listener.h +++ b/src/base/listener.h @@ -2,9 +2,9 @@ /*! \file listener.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/modal_exception.h b/src/base/modal_exception.h index c662da2c8..fc1b8ac9e 100644 --- a/src/base/modal_exception.h +++ b/src/base/modal_exception.h @@ -2,9 +2,9 @@ /*! \file modal_exception.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/output.cpp b/src/base/output.cpp index 1d4525701..b89e5cff5 100644 --- a/src/base/output.cpp +++ b/src/base/output.cpp @@ -2,9 +2,9 @@ /*! \file output.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/output.h b/src/base/output.h index 30b5c8ea5..cdc0ac27f 100644 --- a/src/base/output.h +++ b/src/base/output.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/base/ptr_closer.h b/src/base/ptr_closer.h deleted file mode 100644 index 9c40eee4b..000000000 --- a/src/base/ptr_closer.h +++ /dev/null @@ -1,73 +0,0 @@ -/********************* */ -/*! \file ptr_closer.h - ** \verbatim - ** Top contributors (to current version): - ** Tim King - ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 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 A class to close owned pointers in the destructor. - ** - ** A class to close owned pointers in the destructor. - **/ - -#include "cvc4_public.h" - -#ifndef __CVC4__PTR_CLOSER_H -#define __CVC4__PTR_CLOSER_H - -namespace CVC4 { - -/** - * A class to close owned pointers in the destructor. This plays a similar role - * to unique_ptr, but without move semantics. This is designed to overcome the - * lack of having unique_ptr in C++05. - * - * This is a variant of unique_ptr that is not designed for move semantics. - * These are appropriate to own pointer allocations on the stack that should be - * deleted when an exception is thrown. These should be used with care within - * heap based data structures, and never as the return value of a function. - */ -template <class T> -class PtrCloser { - public: - PtrCloser() : d_pointer(NULL) {} - explicit PtrCloser(T* pointer) : d_pointer(pointer) {} - ~PtrCloser() { delete d_pointer; } - - /** Deletes the currently owned copy and takes ownership of pointer. */ - void reset(T* pointer = NULL) { - delete d_pointer; - d_pointer = pointer; - } - - /** Gives up ownership of the pointer to the caller. */ - T* release() { - T* copy = d_pointer; - d_pointer = NULL; - return copy; - } - - /** Returns the pointer. */ - T* get() const { return d_pointer; } - - /** Returns the pointer. Undefined if the pointer is null. */ - T* operator->() const { return d_pointer; } - - /** Returns true if the pointer is not-null. */ - operator bool() const { return d_pointer != NULL; } - - private: - PtrCloser(const PtrCloser*) CVC4_UNDEFINED; - PtrCloser& operator=(const PtrCloser&) CVC4_UNDEFINED; - - /** An owned pointer object allocated by `new`. Or NULL. */ - T* d_pointer; -}; /* class PtrCloser */ - -} /* CVC4 namespace */ - -#endif /* __CVC4__PTR_CLOSER_H */ diff --git a/src/base/tls.h.in b/src/base/tls.h.in index a61eb79be..c66aef767 100644 --- a/src/base/tls.h.in +++ b/src/base/tls.h.in @@ -2,9 +2,9 @@ /*! \file tls.h.in ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, ACSYS, Tim King + ** Morgan Deters, ACSYS, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/bindings/java_iterator_adapter.h b/src/bindings/java_iterator_adapter.h index 2688f9520..79cb8a7eb 100644 --- a/src/bindings/java_iterator_adapter.h +++ b/src/bindings/java_iterator_adapter.h @@ -2,9 +2,9 @@ /*! \file java_iterator_adapter.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/bindings/java_stream_adapters.h b/src/bindings/java_stream_adapters.h index 12f8713a3..4d78d8658 100644 --- a/src/bindings/java_stream_adapters.h +++ b/src/bindings/java_stream_adapters.h @@ -2,9 +2,9 @@ /*! \file java_stream_adapters.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/bindings/swig.h b/src/bindings/swig.h index 7d8f7494e..f73ddd9bb 100644 --- a/src/bindings/swig.h +++ b/src/bindings/swig.h @@ -2,9 +2,9 @@ /*! \file swig.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/compat/cvc3_compat.cpp b/src/compat/cvc3_compat.cpp index 4f4101d7e..ffb299394 100644 --- a/src/compat/cvc3_compat.cpp +++ b/src/compat/cvc3_compat.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -21,22 +21,17 @@ #include <iosfwd> #include <iterator> #include <sstream> -#include <string> #include "base/exception.h" #include "base/output.h" #include "expr/expr_iomanip.h" #include "expr/kind.h" -#include "expr/predicate.h" #include "options/options.h" #include "options/set_language.h" #include "parser/parser.h" #include "parser/parser_builder.h" #include "smt/command.h" #include "util/bitvector.h" -#include "util/hash.h" -#include "util/integer.h" -#include "util/rational.h" #include "util/sexpr.h" #include "util/subrange_bound.h" @@ -61,22 +56,22 @@ namespace CVC3 { // ExprManager-to-ExprManager import). static std::map<CVC4::ExprManager*, ValidityChecker*> s_validityCheckers; -static std::hash_map<Type, Expr, CVC4::TypeHashFunction> s_typeToExpr; -static std::hash_map<Expr, Type, CVC4::ExprHashFunction> s_exprToType; +static std::unordered_map<Type, Expr, CVC4::TypeHashFunction> s_typeToExpr; +static std::unordered_map<Expr, Type, CVC4::ExprHashFunction> s_exprToType; static bool typeHasExpr(const Type& t) { - std::hash_map<Type, Expr, CVC4::TypeHashFunction>::const_iterator i = s_typeToExpr.find(t); + std::unordered_map<Type, Expr, CVC4::TypeHashFunction>::const_iterator i = s_typeToExpr.find(t); return i != s_typeToExpr.end(); } static Expr typeToExpr(const Type& t) { - std::hash_map<Type, Expr, CVC4::TypeHashFunction>::const_iterator i = s_typeToExpr.find(t); + std::unordered_map<Type, Expr, CVC4::TypeHashFunction>::const_iterator i = s_typeToExpr.find(t); assert(i != s_typeToExpr.end()); return (*i).second; } static Type exprToType(const Expr& e) { - std::hash_map<Expr, Type, CVC4::ExprHashFunction>::const_iterator i = s_exprToType.find(e); + std::unordered_map<Expr, Type, CVC4::ExprHashFunction>::const_iterator i = s_exprToType.find(e); assert(i != s_exprToType.end()); return (*i).second; } @@ -312,8 +307,8 @@ Expr Expr::substExpr(const std::vector<Expr>& oldTerms, } Expr Expr::substExpr(const ExprHashMap<Expr>& oldToNew) const { - const hash_map<CVC4::Expr, CVC4::Expr, CVC4::ExprHashFunction>& o2n = - *reinterpret_cast<const hash_map<CVC4::Expr, CVC4::Expr, CVC4::ExprHashFunction>*>(&oldToNew); + const unordered_map<CVC4::Expr, CVC4::Expr, CVC4::ExprHashFunction>& o2n = + *reinterpret_cast<const unordered_map<CVC4::Expr, CVC4::Expr, CVC4::ExprHashFunction>*>(&oldToNew); return Expr(substitute(o2n)); } @@ -925,13 +920,16 @@ void CLFlags::setFlag(const std::string& name, } void ValidityChecker::setUpOptions(CVC4::Options& options, const CLFlags& clflags) { + // Note: SIMPLIFICATION_MODE_INCREMENTAL, which was used + // for CVC3 compatibility, is not supported by CVC4 + // anymore. + // always incremental and model-producing in CVC3 compatibility mode // also incrementally-simplifying and interactive d_smt->setOption("incremental", string("true")); // disable this option by default for now, because datatype models // are broken [MGD 10/4/2012] //d_smt->setOption("produce-models", string("true")); - d_smt->setOption("simplification-mode", string("incremental")); d_smt->setOption("interactive-mode", string("true"));// support SmtEngine::getAssertions() d_smt->setOption("statistics", string(clflags["stats"].getBool() ? "true" : "false")); @@ -1257,6 +1255,7 @@ Type ValidityChecker::intType() { } Type ValidityChecker::subrangeType(const Expr& l, const Expr& r) { +/* bool noLowerBound = l.getType().isString() && l.getConst<CVC4::String>() == "_NEGINF"; bool noUpperBound = r.getType().isString() && r.getConst<CVC4::String>() == "_POSINF"; CompatCheckArgument(noLowerBound || (l.getKind() == CVC4::kind::CONST_RATIONAL && l.getConst<Rational>().isIntegral()), l); @@ -1264,10 +1263,12 @@ Type ValidityChecker::subrangeType(const Expr& l, const Expr& r) { CVC4::SubrangeBound bl = noLowerBound ? CVC4::SubrangeBound() : CVC4::SubrangeBound(l.getConst<Rational>().getNumerator()); CVC4::SubrangeBound br = noUpperBound ? CVC4::SubrangeBound() : CVC4::SubrangeBound(r.getConst<Rational>().getNumerator()); return d_em->mkSubrangeType(CVC4::SubrangeBounds(bl, br)); + */ + Unimplemented("Subrange types not supported by CVC4 (sorry!)"); } Type ValidityChecker::subtypeType(const Expr& pred, const Expr& witness) { - Unimplemented("Predicate subtyping not supported by CVC4 yet (sorry!)"); + Unimplemented("Predicate subtyping not supported by CVC4 (sorry!)"); /* if(witness.isNull()) { return d_em->mkPredicateSubtype(pred); @@ -1833,7 +1834,7 @@ Expr ValidityChecker::recSelectExpr(const Expr& record, const std::string& field Type t = record.getType(); const CVC4::Datatype& dt = ((CVC4::DatatypeType)t).getDatatype(); unsigned index = CVC4::Datatype::indexOf( dt[0].getSelector(field) ); - return d_em->mkExpr(CVC4::kind::APPLY_SELECTOR_TOTAL, dt[0][index].getSelector(), record); + return d_em->mkExpr(CVC4::kind::APPLY_SELECTOR_TOTAL, dt[0].getSelectorInternal( t, index ), record); } Expr ValidityChecker::recUpdateExpr(const Expr& record, const std::string& field, @@ -2236,8 +2237,9 @@ Expr ValidityChecker::tupleExpr(const std::vector<Expr>& exprs) { Expr ValidityChecker::tupleSelectExpr(const Expr& tuple, int index) { CompatCheckArgument(index >= 0 && index < ((CVC4::DatatypeType)tuple.getType()).getTupleLength(), "invalid index in tuple select"); - const CVC4::Datatype& dt = ((CVC4::DatatypeType)tuple.getType()).getDatatype(); - return d_em->mkExpr(CVC4::kind::APPLY_SELECTOR_TOTAL, dt[0][index].getSelector(), tuple); + Type t = tuple.getType(); + const CVC4::Datatype& dt = ((CVC4::DatatypeType)t).getDatatype(); + return d_em->mkExpr(CVC4::kind::APPLY_SELECTOR_TOTAL, dt[0].getSelectorInternal( t, index ), tuple); } Expr ValidityChecker::tupleUpdateExpr(const Expr& tuple, int index, @@ -2262,7 +2264,8 @@ Expr ValidityChecker::datatypeSelExpr(const std::string& selector, const Expr& a const CVC4::Datatype& dt = *(*i).second.first; string constructor = (*i).second.second; const CVC4::DatatypeConstructor& ctor = dt[constructor]; - return d_em->mkExpr(CVC4::kind::APPLY_SELECTOR, ctor.getSelector(selector), arg); + unsigned sindex = CVC4::Datatype::indexOf( ctor.getSelector(selector) ); + return d_em->mkExpr(CVC4::kind::APPLY_SELECTOR, ctor.getSelectorInternal( arg.getType(), sindex ), arg); } Expr ValidityChecker::datatypeTestExpr(const std::string& constructor, const Expr& arg) { diff --git a/src/compat/cvc3_compat.h b/src/compat/cvc3_compat.h index d51670985..25e3ae32f 100644 --- a/src/compat/cvc3_compat.h +++ b/src/compat/cvc3_compat.h @@ -2,9 +2,9 @@ /*! \file cvc3_compat.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Francois Bobot + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -49,7 +49,10 @@ #define _cvc3__include__formula_value_h_ #include <stdlib.h> + #include <map> +#include <string> +#include <unordered_map> #include <utility> #include "base/exception.h" @@ -58,7 +61,6 @@ #include "expr/type.h" #include "parser/parser.h" #include "smt/smt_engine.h" -#include "util/hash.h" #include "util/integer.h" #include "util/rational.h" @@ -267,7 +269,7 @@ class CVC4_PUBLIC ExprMap : public std::map<Expr, T> { };/* class ExprMap<T> */ template <class T> -class CVC4_PUBLIC ExprHashMap : public std::hash_map<Expr, T, CVC4::ExprHashFunction> { +class CVC4_PUBLIC ExprHashMap : public std::unordered_map<Expr, T, CVC4::ExprHashFunction> { public: void insert(Expr a, Expr b); };/* class ExprHashMap<T> */ @@ -521,8 +523,8 @@ class CVC4_PUBLIC ValidityChecker { friend class Type; // to reach in to d_exprTypeMapRemove - typedef std::hash_map<std::string, const CVC4::Datatype*, CVC4::StringHashFunction> ConstructorMap; - typedef std::hash_map<std::string, std::pair<const CVC4::Datatype*, std::string>, CVC4::StringHashFunction> SelectorMap; + typedef std::unordered_map<std::string, const CVC4::Datatype*> ConstructorMap; + typedef std::unordered_map<std::string, std::pair<const CVC4::Datatype*, std::string>> SelectorMap; ConstructorMap d_constructors; SelectorMap d_selectors; diff --git a/src/context/backtrackable.h b/src/context/backtrackable.h index 131fabd7c..f91a2039d 100644 --- a/src/context/backtrackable.h +++ b/src/context/backtrackable.h @@ -2,9 +2,9 @@ /*! \file backtrackable.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cdchunk_list.h b/src/context/cdchunk_list.h index e75f4de4d..d13c6ab90 100644 --- a/src/context/cdchunk_list.h +++ b/src/context/cdchunk_list.h @@ -2,9 +2,9 @@ /*! \file cdchunk_list.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Clark Barrett + ** Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cddense_set.h b/src/context/cddense_set.h index edc5ea558..547747b59 100644 --- a/src/context/cddense_set.h +++ b/src/context/cddense_set.h @@ -2,9 +2,9 @@ /*! \file cddense_set.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cdhashmap.h b/src/context/cdhashmap.h index 0a6c400a7..b6024b65d 100644 --- a/src/context/cdhashmap.h +++ b/src/context/cdhashmap.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -15,7 +15,7 @@ ** which must be saved and restored as contexts are pushed and ** popped. Requires that operator= be defined for the data class, ** and operator== for the key class. For key types that don't have a - ** __gnu_cxx::hash<>, you should provide an explicit HashFcn. + ** std::hash<>, you should provide an explicit HashFcn. ** ** See also: ** CDInsertHashMap : An "insert-once" CD hash map. @@ -58,36 +58,23 @@ ** its CDOhash_map object memory freed. Here, the CDOhash_map is restored ** to a "NULL-map" state (see above), signaling it to remove ** itself from the map completely and put itself on a "trash - ** list" for the map. + ** list" for its scope. ** - ** Third, you might obliterate() the key. This calls the CDOhash_map - ** destructor, which calls destroy(), which does a successive - ** restore() until level 0. If the key was in the map since - ** level 0, the restore() won't remove it, so in that case - ** obliterate() removes it from the map and frees the CDOhash_map's - ** memory. - ** - ** Fourth, you might delete the cdhashmap(calling CDHashMap::~CDHashMap()). + ** Third, you might delete the cdhashmap(calling CDHashMap::~CDHashMap()). ** This first calls destroy(), as per ContextObj contract, but ** cdhashmapdoesn't save/restore itself, so that does nothing at the - ** CDHashMap-level. Then it empties the trash. Then, for each - ** element in the map, it marks it as being "part of a complete - ** map destruction", which essentially short-circuits + ** CDHashMap-level. Then, for each element in the map, it marks it as being + ** "part of a complete map destruction", which essentially short-circuits ** CDOhash_map::restore() (see CDOhash_map::restore()), then deallocates - ** it. Finally it asserts that the trash is empty (which it - ** should be, since restore() was short-circuited). + ** it. ** - ** Fifth, you might clear() the CDHashMap. This does exactly the + ** Fourth, you might clear() the CDHashMap. This does exactly the ** same as CDHashMap::~CDHashMap(), except that it doesn't call destroy() ** on itself. ** - ** CDHashMap::emptyTrash() simply goes through and calls - ** ->deleteSelf() on all elements in the trash. ** ContextObj::deleteSelf() calls the CDOhash_map destructor, then ** frees the memory associated to the CDOhash_map. CDOhash_map::~CDOhash_map() - ** calls destroy(), which restores as much as possible. (Note, - ** though, that since objects placed on the trash have already - ** restored to the fullest extent possible, it does nothing.) + ** calls destroy(), which restores as much as possible. **/ #include "cvc4_private.h" @@ -95,8 +82,9 @@ #ifndef __CVC4__CONTEXT__CDHASHMAP_H #define __CVC4__CONTEXT__CDHASHMAP_H -#include <ext/hash_map> +#include <functional> #include <iterator> +#include <unordered_map> #include <vector> #include "base/cvc4_assert.h" @@ -108,7 +96,7 @@ namespace context { // Auxiliary class: almost the same as CDO (see cdo.h) -template <class Key, class Data, class HashFcn = __gnu_cxx::hash<Key> > +template <class Key, class Data, class HashFcn = std::hash<Key> > class CDOhash_map : public ContextObj { friend class CDHashMap<Key, Data, HashFcn>; @@ -157,7 +145,7 @@ class CDOhash_map : public ContextObj { } else { Debug("gc") << "CDHashMap<> trash push_back " << this << std::endl; //this->deleteSelf(); - d_map->d_trash.push_back(this); + enqueueToGarbageCollect(); } } else { d_data = p->d_data; @@ -281,7 +269,7 @@ template <class Key, class Data, class HashFcn> class CDHashMap : public ContextObj { typedef CDOhash_map<Key, Data, HashFcn> Element; - typedef __gnu_cxx::hash_map<Key, Element*, HashFcn> table_type; + typedef std::unordered_map<Key, Element*, HashFcn> table_type; friend class CDOhash_map<Key, Data, HashFcn>; @@ -290,8 +278,6 @@ class CDHashMap : public ContextObj { Element* d_first; Context* d_context; - std::vector<Element*> d_trash; - // Nothing to save; the elements take care of themselves virtual ContextObj* save(ContextMemoryManager* pCMM) { Unreachable(); @@ -302,75 +288,38 @@ class CDHashMap : public ContextObj { Unreachable(); } - void emptyTrash() { - //FIXME multithreading - for(typename std::vector<Element*>::iterator i = d_trash.begin(); - i != d_trash.end(); - ++i) { - Debug("gc") << "emptyTrash(): " << *i << std::endl; - (*i)->deleteSelf(); - } - d_trash.clear(); - } - // no copy or assignment CDHashMap(const CDHashMap&) CVC4_UNDEFINED; CDHashMap& operator=(const CDHashMap&) CVC4_UNDEFINED; public: - - CDHashMap(Context* context) : - ContextObj(context), - d_map(), - d_first(NULL), - d_context(context), - d_trash() { - } + CDHashMap(Context* context) + : ContextObj(context), d_map(), d_first(NULL), d_context(context) {} ~CDHashMap() { - Debug("gc") << "cdhashmap" << this - << " disappearing, destroying..." << std::endl; + Debug("gc") << "cdhashmap" << this << " disappearing, destroying..." + << std::endl; destroy(); - Debug("gc") << "cdhashmap" << this - << " disappearing, done destroying" << std::endl; - - Debug("gc") << "cdhashmap" << this << " gone, emptying trash" << std::endl; - emptyTrash(); - Debug("gc") << "done emptying trash for " << this << std::endl; - - for(typename table_type::iterator i = d_map.begin(); - i != d_map.end(); - ++i) { - // mark it as being a destruction (short-circuit restore()) - (*i).second->d_map = NULL; - if(!(*i).second->d_noTrash) { - (*i).second->deleteSelf(); - } - } - d_map.clear(); - d_first = NULL; - - Assert(d_trash.empty()); + Debug("gc") << "cdhashmap" << this << " disappearing, done destroying" + << std::endl; + clear(); } - void clear() throw(AssertionException) { - Debug("gc") << "clearing cdhashmap" << this << ", emptying trash" << std::endl; - emptyTrash(); + void clear() { + Debug("gc") << "clearing cdhashmap" << this << ", emptying trash" + << std::endl; Debug("gc") << "done emptying trash for " << this << std::endl; - for(typename table_type::iterator i = d_map.begin(); - i != d_map.end(); - ++i) { + for (auto& key_element_pair : d_map) { // mark it as being a destruction (short-circuit restore()) - (*i).second->d_map = NULL; - if(!(*i).second->d_noTrash) { - (*i).second->deleteSelf(); + Element* element = key_element_pair.second; + element->d_map = nullptr; + if (!element->d_noTrash) { + element->deleteSelf(); } } d_map.clear(); - d_first = NULL; - - Assert(d_trash.empty()); + d_first = nullptr; } // The usual operators of map @@ -389,8 +338,6 @@ public: // If a key is not present, a new object is created and inserted Element& operator[](const Key& k) { - emptyTrash(); - typename table_type::iterator i = d_map.find(k); Element* obj; @@ -404,8 +351,6 @@ public: } bool insert(const Key& k, const Data& d) { - emptyTrash(); - typename table_type::iterator i = d_map.find(k); if(i == d_map.end()) {// create new object @@ -443,8 +388,6 @@ public: * insertAtContextLevelZero() a key that already is in the map. */ void insertAtContextLevelZero(const Key& k, const Data& d) { - emptyTrash(); - AlwaysAssert(d_map.find(k) == d_map.end()); Element* obj = new(true) Element(d_context, this, k, d, @@ -454,43 +397,6 @@ public: // FIXME: no erase(), too much hassle to implement efficiently... - /** - * "Obliterating" is kind of like erasing, except it's not - * backtrackable; the key is permanently removed from the map. - * (Naturally, it can be re-added as a new element.) - */ - void obliterate(const Key& k) { - typename table_type::iterator i = d_map.find(k); - if(i != d_map.end()) { - Debug("gc") << "key " << k << " obliterated" << std::endl; - // Restore this object to level 0. If it was inserted after level 0, - // nothing else to do as restore will put it in the trash. - (*i).second->destroy(); - - // Check if object was inserted at level 0: in that case, still have - // to do some work. - typename table_type::iterator j = d_map.find(k); - if(j != d_map.end()) { - Element* elt = (*j).second; - if(d_first == elt) { - if(elt->d_next == elt) { - Assert(elt->d_prev == elt); - d_first = NULL; - } else { - d_first = elt->d_next; - } - } - elt->d_prev->d_next = elt->d_next; - elt->d_next->d_prev = elt->d_prev; - d_map.erase(j);//FIXME multithreading - Debug("gc") << "key " << k << " obliterated zero-scope: " << elt << std::endl; - if(!elt->d_noTrash) { - elt->deleteSelf(); - } - } - } - } - class iterator { const Element* d_it; @@ -566,10 +472,6 @@ public: } } - iterator find(const Key& k) { - emptyTrash(); - return const_cast<const CDHashMap*>(this)->find(k); - } };/* class CDHashMap<> */ diff --git a/src/context/cdhashmap_forward.h b/src/context/cdhashmap_forward.h index b8a361dbb..a8fbc5ee2 100644 --- a/src/context/cdhashmap_forward.h +++ b/src/context/cdhashmap_forward.h @@ -2,9 +2,9 @@ /*! \file cdhashmap_forward.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Dejan Jovanovic + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -26,15 +26,14 @@ #ifndef __CVC4__CONTEXT__CDHASHMAP_FORWARD_H #define __CVC4__CONTEXT__CDHASHMAP_FORWARD_H +#include <functional> + /// \cond internals -namespace __gnu_cxx { - template <class Key> struct hash; -}/* __gnu_cxx namespace */ namespace CVC4 { namespace context { - template <class Key, class Data, class HashFcn = __gnu_cxx::hash<Key> > + template <class Key, class Data, class HashFcn = std::hash<Key> > class CDHashMap; }/* CVC4::context namespace */ }/* CVC4 namespace */ diff --git a/src/context/cdhashset.h b/src/context/cdhashset.h index 8c450f1ab..dd71370a8 100644 --- a/src/context/cdhashset.h +++ b/src/context/cdhashset.h @@ -2,9 +2,9 @@ /*! \file cdhashset.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Kshitij Bansal + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cdhashset_forward.h b/src/context/cdhashset_forward.h index 06ea9c471..ed665ce1b 100644 --- a/src/context/cdhashset_forward.h +++ b/src/context/cdhashset_forward.h @@ -2,9 +2,9 @@ /*! \file cdhashset_forward.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Dejan Jovanovic + ** Morgan Deters, Paul Meng, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cdinsert_hashmap.h b/src/context/cdinsert_hashmap.h index e901e9413..db679c1f7 100644 --- a/src/context/cdinsert_hashmap.h +++ b/src/context/cdinsert_hashmap.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -33,9 +33,9 @@ #include "cvc4_private.h" -#include <boost/static_assert.hpp> #include <deque> -#include <ext/hash_map> +#include <functional> +#include <unordered_map> #include <utility> #include "base/cvc4_assert.h" @@ -51,14 +51,14 @@ namespace CVC4 { namespace context { -template <class Key, class Data, class HashFcn = __gnu_cxx::hash<Key> > +template <class Key, class Data, class HashFcn = std::hash<Key> > class InsertHashMap { private: typedef std::deque<Key> KeyVec; /** A list of the keys in the map maintained as a stack. */ KeyVec d_keys; - typedef __gnu_cxx::hash_map<Key, Data, HashFcn> HashMap; + typedef std::unordered_map<Key, Data, HashFcn> HashMap; /** The hash_map used for element lookup. */ HashMap d_hashMap; @@ -383,9 +383,8 @@ public: } };/* class CDInsertHashMap<> */ - template <class Data, class HashFcn> -class CDInsertHashMap <TNode, Data, HashFcn > : public ContextObj { +class CDInsertHashMap<TNode, Data, HashFcn> : public ContextObj { /* CDInsertHashMap is challenging to get working with TNode. * Consider using CDHashMap<TNode,...> instead. * @@ -397,7 +396,8 @@ class CDInsertHashMap <TNode, Data, HashFcn > : public ContextObj { * hashed. Getting the order right with a guarantee is too hard. */ - BOOST_STATIC_ASSERT(sizeof(Data) == 0); + static_assert(sizeof(Data) == 0, + "Cannot create a CDInsertHashMap with TNode keys"); }; }/* CVC4::context namespace */ diff --git a/src/context/cdinsert_hashmap_forward.h b/src/context/cdinsert_hashmap_forward.h index 5bc6e8fda..05501f1a2 100644 --- a/src/context/cdinsert_hashmap_forward.h +++ b/src/context/cdinsert_hashmap_forward.h @@ -2,9 +2,9 @@ /*! \file cdinsert_hashmap_forward.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cdlist.h b/src/context/cdlist.h index 47667cc8d..3dab675c3 100644 --- a/src/context/cdlist.h +++ b/src/context/cdlist.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Francois Bobot ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,6 @@ #ifndef __CVC4__CONTEXT__CDLIST_H #define __CVC4__CONTEXT__CDLIST_H -#include <boost/static_assert.hpp> #include <iterator> #include <memory> #include <string> @@ -417,21 +416,21 @@ public: } };/* class CDList<> */ - template <class T, class CleanUp> -class CDList <T, CleanUp, ContextMemoryAllocator<T> > : public ContextObj { +class CDList<T, CleanUp, ContextMemoryAllocator<T> > : public ContextObj { /* CDList is incompatible for use with a ContextMemoryAllocator. * Consider using CDChunkList<T> instead. * * Explanation: - * If ContextMemoryAllocator is used and d_list grows at a deeper context level - * the reallocated will be reallocated in a context memory region that can be - * destroyed on pop. To support this, a full copy of d_list would have to be made. - * As this is unacceptable for performance in other situations, we do not do - * this. + * If ContextMemoryAllocator is used and d_list grows at a deeper context + * level the reallocated will be reallocated in a context memory region that + * can be destroyed on pop. To support this, a full copy of d_list would have + * to be made. As this is unacceptable for performance in other situations, we + * do not do this. */ - BOOST_STATIC_ASSERT(sizeof(T) == 0); + static_assert(sizeof(T) == 0, + "Cannot create a CDList with a ContextMemoryAllocator."); }; }/* CVC4::context namespace */ diff --git a/src/context/cdlist_forward.h b/src/context/cdlist_forward.h index 101117c23..49a077349 100644 --- a/src/context/cdlist_forward.h +++ b/src/context/cdlist_forward.h @@ -2,9 +2,9 @@ /*! \file cdlist_forward.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cdmaybe.h b/src/context/cdmaybe.h index 458a124ad..3263c61ee 100644 --- a/src/context/cdmaybe.h +++ b/src/context/cdmaybe.h @@ -2,9 +2,9 @@ /*! \file cdmaybe.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cdo.h b/src/context/cdo.h index 21465181c..3142fe8ef 100644 --- a/src/context/cdo.h +++ b/src/context/cdo.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Francois Bobot ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cdqueue.h b/src/context/cdqueue.h index 5aa890d53..1df985b48 100644 --- a/src/context/cdqueue.h +++ b/src/context/cdqueue.h @@ -2,9 +2,9 @@ /*! \file cdqueue.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Francois Bobot, Morgan Deters + ** Tim King, Paul Meng, Francois Bobot ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cdtrail_hashmap.h b/src/context/cdtrail_hashmap.h index 90816d542..e64c51c65 100644 --- a/src/context/cdtrail_hashmap.h +++ b/src/context/cdtrail_hashmap.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -44,9 +44,9 @@ #pragma once -#include <boost/static_assert.hpp> -#include <ext/hash_map> #include <deque> +#include <functional> +#include <unordered_map> #include <utility> #include "base/cvc4_assert.h" @@ -59,7 +59,7 @@ namespace CVC4 { namespace context { -template <class Key, class Data, class HashFcn = __gnu_cxx::hash<Key> > +template <class Key, class Data, class HashFcn = std::hash<Key> > class TrailHashMap { public: /** A pair of Key and Data that mirrors hash_map::value_type. */ @@ -93,7 +93,7 @@ private: KDTVec d_kdts; - typedef __gnu_cxx::hash_map<Key, size_t, HashFcn> PositionMap; + typedef std::unordered_map<Key, size_t, HashFcn> PositionMap; typedef typename PositionMap::iterator PM_iterator; typedef typename PositionMap::const_iterator PM_const_iterator; @@ -551,7 +551,7 @@ public: };/* class CDTrailHashMap<> */ template <class Data, class HashFcn> -class CDTrailHashMap <TNode, Data, HashFcn > : public ContextObj { +class CDTrailHashMap<TNode, Data, HashFcn> : public ContextObj { /* CDTrailHashMap is challenging to get working with TNode. * Consider using CDHashMap<TNode,...> instead. * @@ -563,7 +563,8 @@ class CDTrailHashMap <TNode, Data, HashFcn > : public ContextObj { * hashed. Getting the order right with a guarantee is too hard. */ - BOOST_STATIC_ASSERT(sizeof(Data) == 0); + static_assert(sizeof(Data) == 0, + "Cannot create a CDTrailHashMap with TNode keys"); }; }/* CVC4::context namespace */ diff --git a/src/context/cdtrail_hashmap_forward.h b/src/context/cdtrail_hashmap_forward.h index 926c85872..970f2758c 100644 --- a/src/context/cdtrail_hashmap_forward.h +++ b/src/context/cdtrail_hashmap_forward.h @@ -2,9 +2,9 @@ /*! \file cdtrail_hashmap_forward.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -25,14 +25,11 @@ #pragma once -namespace __gnu_cxx { - template <class Key> struct hash; -}/* __gnu_cxx namespace */ +#include <functional> namespace CVC4 { namespace context { - template <class Key, class Data, class HashFcn = __gnu_cxx::hash<Key> > + template <class Key, class Data, class HashFcn = std::hash<Key> > class CDTrailHashMap; }/* CVC4::context namespace */ }/* CVC4 namespace */ - diff --git a/src/context/cdtrail_queue.h b/src/context/cdtrail_queue.h index 825557f36..d709ccbcb 100644 --- a/src/context/cdtrail_queue.h +++ b/src/context/cdtrail_queue.h @@ -2,9 +2,9 @@ /*! \file cdtrail_queue.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/cdvector.h b/src/context/cdvector.h index 2449d78b0..2ff745b60 100644 --- a/src/context/cdvector.h +++ b/src/context/cdvector.h @@ -2,9 +2,9 @@ /*! \file cdvector.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/context.cpp b/src/context/context.cpp index 8f151ad08..66d6a6542 100644 --- a/src/context/context.cpp +++ b/src/context/context.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Clark Barrett, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -296,6 +296,10 @@ ContextObj::ContextObj(bool allocatedInCMM, Context* pContext) : d_pScope->addToChain(this); } +void ContextObj::enqueueToGarbageCollect() { + Assert(d_pScope != NULL); + d_pScope->enqueueToGarbageCollect(this); +} ContextNotifyObj::ContextNotifyObj(Context* pContext, bool preNotify) { if(preNotify) { @@ -354,6 +358,29 @@ std::ostream& operator<<(std::ostream& out, return out << " --> NULL"; } +Scope::~Scope() { + // Call restore() method on each ContextObj object in the list. + // Note that it is the responsibility of restore() to return the + // next item in the list. + while (d_pContextObjList != NULL) { + d_pContextObjList = d_pContextObjList->restoreAndContinue(); + } + + if (d_garbage) { + while (!d_garbage->empty()) { + ContextObj* obj = d_garbage->back(); + d_garbage->pop_back(); + obj->deleteSelf(); + } + } +} + +void Scope::enqueueToGarbageCollect(ContextObj* obj) { + if (!d_garbage) { + d_garbage.reset(new std::vector<ContextObj*>); + } + d_garbage->push_back(obj); +} } /* CVC4::context namespace */ } /* CVC4 namespace */ diff --git a/src/context/context.h b/src/context/context.h index f7707bdec..92eb10441 100644 --- a/src/context/context.h +++ b/src/context/context.h @@ -2,9 +2,9 @@ /*! \file context.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Clark Barrett, Dejan Jovanovic + ** Morgan Deters, Clark Barrett, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,12 +19,13 @@ #ifndef __CVC4__CONTEXT__CONTEXT_H #define __CVC4__CONTEXT__CONTEXT_H -#include <iostream> #include <cstdlib> #include <cstring> -#include <vector> +#include <iostream> +#include <memory> #include <new> #include <typeinfo> +#include <vector> #include "base/cvc4_assert.h" #include "base/output.h" @@ -257,6 +258,14 @@ class Scope { */ ContextObj* d_pContextObjList; + /** + * A list of ContextObj to be garbage collected before the destruction of this + * scope. deleteSelf() will be called on each element during ~Scope(). + * + * This is either nullptr or list owned by this scope. + */ + std::unique_ptr<std::vector<ContextObj*>> d_garbage; + friend std::ostream& operator<<(std::ostream&, const Scope&) throw(AssertionException); @@ -266,54 +275,60 @@ public: * Constructor: Create a new Scope; set the level and the previous Scope * if any. */ - Scope(Context* pContext, ContextMemoryManager* pCMM, int level) throw() : - d_pContext(pContext), - d_pCMM(pCMM), - d_level(level), - d_pContextObjList(NULL) { + Scope(Context* pContext, ContextMemoryManager* pCMM, int level) throw() + : d_pContext(pContext), + d_pCMM(pCMM), + d_level(level), + d_pContextObjList(nullptr), + d_garbage() {} + + /** + * Destructor: Clears out all of the garbage and restore all of the objects + * in ContextObjList. + */ + ~Scope(); + + /** + * Get the Context for this Scope + */ + Context* getContext() const throw() { return d_pContext; } + + /** + * Get the ContextMemoryManager for this Scope + */ + ContextMemoryManager* getCMM() const throw() { return d_pCMM; } + + /** + * Get the level of the current Scope + */ + int getLevel() const throw() { return d_level; } + + /** + * Return true iff this Scope is the current top Scope + */ + bool isCurrent() const throw() { return this == d_pContext->getTopScope(); } + + /** + * When a ContextObj object is modified for the first time in this + * Scope, it should call this method to add itself to the list of + * objects that will need to be restored. Defined inline below. + */ + void addToChain(ContextObj* pContextObj) throw(AssertionException); + + /** + * Overload operator new for use with ContextMemoryManager to allow + * creation of new Scope objects in the current memory region. + */ + static void* operator new(size_t size, ContextMemoryManager* pCMM) { + Trace("context_mm") << "Scope::new " << size << " in " << pCMM << std::endl; + return pCMM->newData(size); } /** - * Destructor: Restore all of the objects in ContextObjList. Defined inline - * below. - */ - ~Scope(); - - /** - * Get the Context for this Scope - */ - Context* getContext() const throw() { return d_pContext; } - - /** - * Get the ContextMemoryManager for this Scope + * Enqueues a ContextObj to be garbage collected via a call to deleteSelf() + * during the destruction of this scope. */ - ContextMemoryManager* getCMM() const throw() { return d_pCMM; } - - /** - * Get the level of the current Scope - */ - int getLevel() const throw() { return d_level; } - - /** - * Return true iff this Scope is the current top Scope - */ - bool isCurrent() const throw() { return this == d_pContext->getTopScope(); } - - /** - * When a ContextObj object is modified for the first time in this - * Scope, it should call this method to add itself to the list of - * objects that will need to be restored. Defined inline below. - */ - void addToChain(ContextObj* pContextObj) throw(AssertionException); - - /** - * Overload operator new for use with ContextMemoryManager to allow - * creation of new Scope objects in the current memory region. - */ - static void* operator new(size_t size, ContextMemoryManager* pCMM) { - Trace("context_mm") << "Scope::new " << size << " in " << pCMM << std::endl; - return pCMM->newData(size); - } + void enqueueToGarbageCollect(ContextObj* obj); /** * Overload operator delete for Scope objects allocated using @@ -647,6 +662,12 @@ public: ::operator delete(this); } + /** + * Use this to enqueue calling deleteSelf() at the time of the destruction of + * the enclosing Scope. + */ + void enqueueToGarbageCollect(); + };/* class ContextObj */ /** @@ -725,15 +746,6 @@ inline void ContextObj::makeSaveRestorePoint() throw(AssertionException) { update(); } -inline Scope::~Scope() { - // Call restore() method on each ContextObj object in the list. - // Note that it is the responsibility of restore() to return the - // next item in the list. - while(d_pContextObjList != NULL) { - d_pContextObjList = d_pContextObjList->restoreAndContinue(); - } -} - inline void Scope::addToChain(ContextObj* pContextObj) throw(AssertionException) { if(d_pContextObjList != NULL) { diff --git a/src/context/context_mm.cpp b/src/context/context_mm.cpp index ac7d7f8cf..f0f6ebc42 100644 --- a/src/context/context_mm.cpp +++ b/src/context/context_mm.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Clark Barrett, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/context_mm.h b/src/context/context_mm.h index 673fb9098..974135e3e 100644 --- a/src/context/context_mm.h +++ b/src/context/context_mm.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Clark Barrett, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/context/stacking_vector.h b/src/context/stacking_vector.h deleted file mode 100644 index 4b482c9b0..000000000 --- a/src/context/stacking_vector.h +++ /dev/null @@ -1,114 +0,0 @@ -/********************* */ -/*! \file stacking_vector.h - ** \verbatim - ** Top contributors (to current version): - ** Morgan Deters, Tim King, Dejan Jovanovic - ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 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 Backtrackable vector using an undo stack - ** - ** Backtrackable vector using an undo stack rather than storing items in - ** a CDVector<>. - **/ - -#include "cvc4_private.h" - -#ifndef __CVC4__CONTEXT__STACKING_VECTOR_H -#define __CVC4__CONTEXT__STACKING_VECTOR_H - -#include <utility> -#include <vector> - -#include "context/cdo.h" - -namespace CVC4 { -namespace context { - -template <class T> -class StackingVector : context::ContextNotifyObj { - /** Our underlying map type. */ - typedef std::vector<T> VectorType; - - /** Our map of indices to their values. */ - VectorType d_map; - - /** Our undo stack for changes made to d_map. */ - std::vector<std::pair<size_t, T> > d_trace; - - /** Our current offset in the d_trace stack (context-dependent). */ - context::CDO<size_t> d_offset; - -public: - typedef typename VectorType::const_iterator const_iterator; - - StackingVector(context::Context* ctxt) : - context::ContextNotifyObj(ctxt), - d_offset(ctxt, 0) { - } - - ~StackingVector() { } - - /** - * Return a value from the vector. If n is not a key in - * the map, this function returns a default-constructed T. - */ - T operator[](size_t n) const { - return n < d_map.size() ? d_map[n] : T(); - } - //T& operator[](ArgType n) { return d_map[n]; }// not permitted--bypasses set() logic - - /** - * Set the value in the key-value map for Node n to newValue. - */ - void set(size_t n, const T& newValue); - - /** - * Return the current size of the vector. Note that once a certain - * size is achieved, the size never goes down again, although the - * elements off the old end of the vector will be replaced with - * default-constructed T values. - */ - size_t size() const { - return d_map.size(); - } - - /** - * Called by the Context when a pop occurs. Cancels everything to the - * current context level. Overrides ContextNotifyObj::notify(). - */ - void contextNotifyPop(); - -};/* class StackingVector<> */ - -template <class T> -void StackingVector<T>::set(size_t n, const T& newValue) { - Trace("sv") << "SV setting " << n << " : " << newValue << " @ " << d_trace.size() << std::endl; - if(n >= d_map.size()) { - d_map.resize(n + 1); - } - T& ref = d_map[n]; - d_trace.push_back(std::make_pair(n, T(ref))); - d_offset = d_trace.size(); - ref = newValue; -} - -template <class T> -void StackingVector<T>::contextNotifyPop() { - Trace("sv") << "SV cancelling : " << d_offset << " < " << d_trace.size() << " ?" << std::endl; - while(d_offset < d_trace.size()) { - std::pair<size_t, T> p = d_trace.back(); - Trace("sv") << "SV cancelling: " << p.first << " back to " << p.second << std::endl; - d_map[p.first] = p.second; - d_trace.pop_back(); - } - Trace("sv") << "SV cancelling finished." << std::endl; -} - -}/* CVC4::context namespace */ -}/* CVC4 namespace */ - -#endif /*__CVC4__CONTEXT__STACKING_VECTOR_H */ diff --git a/src/cvc4.i b/src/cvc4.i index c950bb4c4..4768e2344 100644 --- a/src/cvc4.i +++ b/src/cvc4.i @@ -11,7 +11,7 @@ namespace std { class istream; class ostream; template <class T> class set {}; - template <class K, class V, class H> class hash_map {}; + template <class K, class V, class H> class unordered_map {}; } %{ @@ -41,7 +41,7 @@ namespace CVC4 {} using namespace CVC4; #include <cassert> -#include <ext/hash_map> +#include <unordered_map> #include <iosfwd> #include <set> #include <string> @@ -86,7 +86,7 @@ std::set<JavaInputStreamAdapter*> CVC4::JavaInputStreamAdapter::s_adapters; %template(vectorPairStringType) std::vector< std::pair< std::string, CVC4::Type > >; %template(pairStringType) std::pair< std::string, CVC4::Type >; %template(setOfType) std::set< CVC4::Type >; -%template(hashmapExpr) std::hash_map< CVC4::Expr, CVC4::Expr, CVC4::ExprHashFunction >; +%template(hashmapExpr) std::unordered_map< CVC4::Expr, CVC4::Expr, CVC4::ExprHashFunction >; // This is unfortunate, but seems to be necessary; if we leave NULL // defined, swig will expand it to "(void*) 0", and some of swig's @@ -335,7 +335,6 @@ std::set<JavaInputStreamAdapter*> CVC4::JavaInputStreamAdapter::s_adapters; %include "expr/ascription_type.i" %include "expr/emptyset.i" %include "expr/datatype.i" -%include "expr/predicate.i" %include "expr/record.i" %include "proof/unsat_core.i" diff --git a/src/decision/decision_attributes.h b/src/decision/decision_attributes.h index cc2c766e3..9774ced9a 100644 --- a/src/decision/decision_attributes.h +++ b/src/decision/decision_attributes.h @@ -2,9 +2,9 @@ /*! \file decision_attributes.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King, Morgan Deters + ** Kshitij Bansal, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/decision/decision_engine.cpp b/src/decision/decision_engine.cpp index 71e4f4ec3..909f2f3ef 100644 --- a/src/decision/decision_engine.cpp +++ b/src/decision/decision_engine.cpp @@ -2,9 +2,9 @@ /*! \file decision_engine.cpp ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King, Morgan Deters + ** Kshitij Bansal, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/decision/decision_engine.h b/src/decision/decision_engine.h index 66293d7ad..3d906d81d 100644 --- a/src/decision/decision_engine.h +++ b/src/decision/decision_engine.h @@ -2,9 +2,9 @@ /*! \file decision_engine.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King, Morgan Deters + ** Kshitij Bansal, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/decision/decision_strategy.h b/src/decision/decision_strategy.h index 5c3b01bef..25334b777 100644 --- a/src/decision/decision_strategy.h +++ b/src/decision/decision_strategy.h @@ -2,9 +2,9 @@ /*! \file decision_strategy.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Morgan Deters, Tim King + ** Kshitij Bansal, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/decision/justification_heuristic.cpp b/src/decision/justification_heuristic.cpp index ded2cad15..d0d2b39c9 100644 --- a/src/decision/justification_heuristic.cpp +++ b/src/decision/justification_heuristic.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Kshitij Bansal, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/decision/justification_heuristic.h b/src/decision/justification_heuristic.h index c03bba0c0..70fecb871 100644 --- a/src/decision/justification_heuristic.h +++ b/src/decision/justification_heuristic.h @@ -2,9 +2,9 @@ /*! \file justification_heuristic.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King, Morgan Deters + ** Kshitij Bansal, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -23,6 +23,8 @@ #ifndef __CVC4__DECISION__JUSTIFICATION_HEURISTIC #define __CVC4__DECISION__JUSTIFICATION_HEURISTIC +#include <unordered_set> + #include "context/cdhashmap.h" #include "context/cdhashset.h" #include "context/cdlist.h" @@ -78,13 +80,13 @@ class JustificationHeuristic : public ITEDecisionStrategy { * splitter. Can happen when exploring assertion corresponding to a * term-ITE. */ - hash_set<TNode,TNodeHashFunction> d_visited; + std::unordered_set<TNode,TNodeHashFunction> d_visited; /** * Set to track visited nodes in a dfs search done in computeITE * function */ - hash_set<TNode,TNodeHashFunction> d_visitedComputeITE; + std::unordered_set<TNode,TNodeHashFunction> d_visitedComputeITE; /** current decision for the recursive call */ SatLiteral d_curDecision; @@ -177,7 +179,6 @@ private: };/* class JustificationHeuristic */ }/* namespace decision */ - }/* namespace CVC4 */ #endif /* __CVC4__DECISION__JUSTIFICATION_HEURISTIC */ diff --git a/src/expr/Makefile.am b/src/expr/Makefile.am index e45c765c0..2400468a2 100644 --- a/src/expr/Makefile.am +++ b/src/expr/Makefile.am @@ -26,7 +26,6 @@ libexpr_la_SOURCES = \ attribute.cpp \ attribute_internals.h \ attribute_unique_id.h \ - convenience_node_builders.h \ chain.h \ emptyset.cpp \ emptyset.h \ @@ -61,8 +60,6 @@ libexpr_la_SOURCES = \ variable_type_map.h \ datatype.h \ datatype.cpp \ - predicate.h \ - predicate.cpp \ record.cpp \ record.h \ uninterpreted_constant.cpp \ @@ -103,7 +100,6 @@ EXTRA_DIST = \ kind.i \ expr.i \ record.i \ - predicate.i \ variable_type_map.i \ uninterpreted_constant.i diff --git a/src/expr/array.h b/src/expr/array.h index cf050e077..98abfcacf 100644 --- a/src/expr/array.h +++ b/src/expr/array.h @@ -2,9 +2,9 @@ /*! \file array.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/array_store_all.cpp b/src/expr/array_store_all.cpp index 05710a636..4bad04f79 100644 --- a/src/expr/array_store_all.cpp +++ b/src/expr/array_store_all.cpp @@ -2,9 +2,9 @@ /*! \file array_store_all.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/array_store_all.h b/src/expr/array_store_all.h index 0a9c8344a..c8474dfa1 100644 --- a/src/expr/array_store_all.h +++ b/src/expr/array_store_all.h @@ -2,9 +2,9 @@ /*! \file array_store_all.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/ascription_type.h b/src/expr/ascription_type.h index 46d2871ff..ce6401cd5 100644 --- a/src/expr/ascription_type.h +++ b/src/expr/ascription_type.h @@ -2,9 +2,9 @@ /*! \file ascription_type.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/attribute.cpp b/src/expr/attribute.cpp index 3cf242988..f221c7c7e 100644 --- a/src/expr/attribute.cpp +++ b/src/expr/attribute.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -13,12 +13,12 @@ ** ** AttributeManager implementation. **/ +#include "expr/attribute.h" + #include <utility> #include "base/output.h" -#include "expr/attribute.h" #include "expr/node_value.h" -#include "smt/smt_engine.h" using namespace std; @@ -26,15 +26,6 @@ namespace CVC4 { namespace expr { namespace attr { -SmtAttributes::SmtAttributes(context::Context* ctxt) : - d_cdbools(ctxt), - d_cdints(ctxt), - d_cdtnodes(ctxt), - d_cdnodes(ctxt), - d_cdstrings(ctxt), - d_cdptrs(ctxt) { -} - AttributeManager::AttributeManager() : d_inGarbageCollection(false) {} @@ -43,15 +34,6 @@ bool AttributeManager::inGarbageCollection() const { return d_inGarbageCollection; } -SmtAttributes& AttributeManager::getSmtAttributes(SmtEngine* smt) { - Assert(smt != NULL); - return *smt->d_smtAttributes; -} - -const SmtAttributes& AttributeManager::getSmtAttributes(SmtEngine* smt) const { - return *smt->d_smtAttributes; -} - void AttributeManager::debugHook(int debugFlag) { /* DO NOT CHECK IN ANY CODE INTO THE DEBUG HOOKS! * debugHook() is an empty function for the purpose of debugging @@ -71,17 +53,6 @@ void AttributeManager::deleteAllAttributes(NodeValue* nv) { deleteFromTable(d_ptrs, nv); } -void SmtAttributes::deleteAllAttributes(TNode n) { - NodeValue* nv = n.d_nv; - - d_cdbools.erase(nv); - deleteFromTable(d_cdints, nv); - deleteFromTable(d_cdtnodes, nv); - deleteFromTable(d_cdnodes, nv); - deleteFromTable(d_cdstrings, nv); - deleteFromTable(d_cdptrs, nv); -} - void AttributeManager::deleteAllAttributes() { d_bools.clear(); deleteAllFromTable(d_ints); diff --git a/src/expr/attribute.h b/src/expr/attribute.h index 13bedeaf8..5aea4a4d1 100644 --- a/src/expr/attribute.h +++ b/src/expr/attribute.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,6 @@ * attributes and nodes due to template use */ #include "expr/node.h" #include "expr/type_node.h" -#include "context/context.h" #ifndef __CVC4__EXPR__ATTRIBUTE_H #define __CVC4__EXPR__ATTRIBUTE_H @@ -35,45 +34,11 @@ #undef CVC4_ATTRIBUTE_H__INCLUDING__ATTRIBUTE_INTERNALS_H namespace CVC4 { - -class SmtEngine; - -namespace smt { - extern CVC4_THREADLOCAL(SmtEngine*) s_smtEngine_current; -}/* CVC4::smt namespace */ - namespace expr { namespace attr { // ATTRIBUTE MANAGER =========================================================== -struct SmtAttributes { - SmtAttributes(context::Context*); - - // IF YOU ADD ANY TABLES, don't forget to add them also to the - // implementation of deleteAllAttributes(). - - /** Underlying hash table for context-dependent boolean-valued attributes */ - CDAttrHash<bool> d_cdbools; - /** Underlying hash table for context-dependent integral-valued attributes */ - CDAttrHash<uint64_t> d_cdints; - /** Underlying hash table for context-dependent node-valued attributes */ - CDAttrHash<TNode> d_cdtnodes; - /** Underlying hash table for context-dependent node-valued attributes */ - CDAttrHash<Node> d_cdnodes; - /** Underlying hash table for context-dependent string-valued attributes */ - CDAttrHash<std::string> d_cdstrings; - /** Underlying hash table for context-dependent pointer-valued attributes */ - CDAttrHash<void*> d_cdptrs; - - /** Delete all attributes of given node */ - void deleteAllAttributes(TNode n); - - template <class T> - void deleteFromTable(CDAttrHash<T>& table, NodeValue* nv); - -};/* struct SmtAttributes */ - /** * A container for the main attribute tables of the system. There's a * one-to-one NodeManager : AttributeManager correspondence. @@ -103,9 +68,6 @@ class AttributeManager { void clearDeleteAllAttributesBuffer(); - SmtAttributes& getSmtAttributes(SmtEngine*); - const SmtAttributes& getSmtAttributes(SmtEngine*) const; - public: /** Construct an attribute manager. */ @@ -239,10 +201,10 @@ template <> struct getTable<bool, false> { static const AttrTableId id = AttrTableBool; typedef AttrHash<bool> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { + static inline table_type& get(AttributeManager& am) { return am.d_bools; } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { + static inline const table_type& get(const AttributeManager& am) { return am.d_bools; } }; @@ -252,10 +214,10 @@ template <> struct getTable<uint64_t, false> { static const AttrTableId id = AttrTableUInt64; typedef AttrHash<uint64_t> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { + static inline table_type& get(AttributeManager& am) { return am.d_ints; } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { + static inline const table_type& get(const AttributeManager& am) { return am.d_ints; } }; @@ -265,10 +227,10 @@ template <> struct getTable<TNode, false> { static const AttrTableId id = AttrTableTNode; typedef AttrHash<TNode> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { + static inline table_type& get(AttributeManager& am) { return am.d_tnodes; } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { + static inline const table_type& get(const AttributeManager& am) { return am.d_tnodes; } }; @@ -278,10 +240,10 @@ template <> struct getTable<Node, false> { static const AttrTableId id = AttrTableNode; typedef AttrHash<Node> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { + static inline table_type& get(AttributeManager& am) { return am.d_nodes; } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { + static inline const table_type& get(const AttributeManager& am) { return am.d_nodes; } }; @@ -291,10 +253,10 @@ template <> struct getTable<TypeNode, false> { static const AttrTableId id = AttrTableTypeNode; typedef AttrHash<TypeNode> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { + static inline table_type& get(AttributeManager& am) { return am.d_types; } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { + static inline const table_type& get(const AttributeManager& am) { return am.d_types; } }; @@ -304,10 +266,10 @@ template <> struct getTable<std::string, false> { static const AttrTableId id = AttrTableString; typedef AttrHash<std::string> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { + static inline table_type& get(AttributeManager& am) { return am.d_strings; } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { + static inline const table_type& get(const AttributeManager& am) { return am.d_strings; } }; @@ -317,10 +279,10 @@ template <class T> struct getTable<T*, false> { static const AttrTableId id = AttrTablePointer; typedef AttrHash<void*> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { + static inline table_type& get(AttributeManager& am) { return am.d_ptrs; } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { + static inline const table_type& get(const AttributeManager& am) { return am.d_ptrs; } }; @@ -330,105 +292,14 @@ template <class T> struct getTable<const T*, false> { static const AttrTableId id = AttrTablePointer; typedef AttrHash<void*> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { + static inline table_type& get(AttributeManager& am) { return am.d_ptrs; } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { + static inline const table_type& get(const AttributeManager& am) { return am.d_ptrs; } }; -/** Access the "d_cdbools" member of AttributeManager. */ -template <> -struct getTable<bool, true> { - static const AttrTableId id = AttrTableCDBool; - typedef CDAttrHash<bool> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdbools; - } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdbools; - } -}; - -/** Access the "d_cdints" member of AttributeManager. */ -template <> -struct getTable<uint64_t, true> { - static const AttrTableId id = AttrTableCDUInt64; - typedef CDAttrHash<uint64_t> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdints; - } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdints; - } -}; - -/** Access the "d_tnodes" member of AttributeManager. */ -template <> -struct getTable<TNode, true> { - static const AttrTableId id = AttrTableCDTNode; - typedef CDAttrHash<TNode> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdtnodes; - } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdtnodes; - } -}; - -/** Access the "d_cdnodes" member of AttributeManager. */ -template <> -struct getTable<Node, true> { - static const AttrTableId id = AttrTableCDNode; - typedef CDAttrHash<Node> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdnodes; - } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdnodes; - } -}; - -/** Access the "d_cdstrings" member of AttributeManager. */ -template <> -struct getTable<std::string, true> { - static const AttrTableId id = AttrTableCDString; - typedef CDAttrHash<std::string> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdstrings; - } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdstrings; - } -}; - -/** Access the "d_cdptrs" member of AttributeManager. */ -template <class T> -struct getTable<T*, true> { - static const AttrTableId id = AttrTableCDPointer; - typedef CDAttrHash<void*> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdptrs; - } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdptrs; - } -}; - -/** Access the "d_cdptrs" member of AttributeManager. */ -template <class T> -struct getTable<const T*, true> { - static const AttrTableId id = AttrTableCDPointer; - typedef CDAttrHash<void*> table_type; - static inline table_type& get(AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdptrs; - } - static inline const table_type& get(const AttributeManager& am, SmtEngine* smt) { - return am.getSmtAttributes(smt).d_cdptrs; - } -}; - }/* CVC4::expr::attr namespace */ // ATTRIBUTE MANAGER IMPLEMENTATIONS =========================================== @@ -445,7 +316,7 @@ AttributeManager::getAttribute(NodeValue* nv, const AttrKind&) const { table_type table_type; const table_type& ah = - getTable<value_type, AttrKind::context_dependent>::get(*this, smt::s_smtEngine_current); + getTable<value_type, AttrKind::context_dependent>::get(*this); typename table_type::const_iterator i = ah.find(std::make_pair(AttrKind::getId(), nv)); @@ -488,7 +359,7 @@ struct HasAttribute<true, AttrKind> { table_type; const table_type& ah = - getTable<value_type, AttrKind::context_dependent>::get(*am, smt::s_smtEngine_current); + getTable<value_type, AttrKind::context_dependent>::get(*am); typename table_type::const_iterator i = ah.find(std::make_pair(AttrKind::getId(), nv)); @@ -516,7 +387,7 @@ struct HasAttribute<false, AttrKind> { table_type table_type; const table_type& ah = - getTable<value_type, AttrKind::context_dependent>::get(*am, smt::s_smtEngine_current); + getTable<value_type, AttrKind::context_dependent>::get(*am); typename table_type::const_iterator i = ah.find(std::make_pair(AttrKind::getId(), nv)); @@ -536,7 +407,7 @@ struct HasAttribute<false, AttrKind> { table_type table_type; const table_type& ah = - getTable<value_type, AttrKind::context_dependent>::get(*am, smt::s_smtEngine_current); + getTable<value_type, AttrKind::context_dependent>::get(*am); typename table_type::const_iterator i = ah.find(std::make_pair(AttrKind::getId(), nv)); @@ -576,7 +447,7 @@ AttributeManager::setAttribute(NodeValue* nv, table_type table_type; table_type& ah = - getTable<value_type, AttrKind::context_dependent>::get(*this, smt::s_smtEngine_current); + getTable<value_type, AttrKind::context_dependent>::get(*this); ah[std::make_pair(AttrKind::getId(), nv)] = mapping::convert(value); } @@ -606,17 +477,6 @@ inline void AttributeManager::deleteFromTable(AttrHash<T>& table, } /** - * Obliterate a NodeValue from a (context-dependent) attribute table. - */ -template <class T> -inline void SmtAttributes::deleteFromTable(CDAttrHash<T>& table, - NodeValue* nv) { - for(unsigned id = 0; id < attr::LastAttributeId<T, true>::getId(); ++id) { - table.obliterate(std::make_pair(id, nv)); - } -} - -/** * Remove all attributes from the table calling the cleanup function * if one is defined. */ diff --git a/src/expr/attribute_internals.h b/src/expr/attribute_internals.h index 60d2069e7..37c7b6a0b 100644 --- a/src/expr/attribute_internals.h +++ b/src/expr/attribute_internals.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -23,9 +23,7 @@ #ifndef __CVC4__EXPR__ATTRIBUTE_INTERNALS_H #define __CVC4__EXPR__ATTRIBUTE_INTERNALS_H -#include <ext/hash_map> - -#include "context/cdhashmap.h" +#include <unordered_map> namespace CVC4 { namespace expr { @@ -152,7 +150,7 @@ namespace attr { */ template <class value_type> class AttrHash : - public __gnu_cxx::hash_map<std::pair<uint64_t, NodeValue*>, + public std::unordered_map<std::pair<uint64_t, NodeValue*>, value_type, AttrHashFunction> { };/* class AttrHash<> */ @@ -163,12 +161,12 @@ class AttrHash : */ template <> class AttrHash<bool> : - protected __gnu_cxx::hash_map<NodeValue*, + protected std::unordered_map<NodeValue*, uint64_t, AttrBoolHashFunction> { /** A "super" type, like in Java, for easy reference below. */ - typedef __gnu_cxx::hash_map<NodeValue*, uint64_t, AttrBoolHashFunction> super; + typedef std::unordered_map<NodeValue*, uint64_t, AttrBoolHashFunction> super; /** * BitAccessor allows us to return a bit "by reference." Of course, @@ -368,217 +366,6 @@ public: } };/* class AttrHash<bool> */ -/** - * A "CDAttrHash<value_type>"---the hash table underlying - * attributes---is simply a context-dependent mapping of - * pair<unique-attribute-id, Node> to value_type using our specialized - * hash function for these pairs. - */ -template <class value_type> -class CDAttrHash : - public context::CDHashMap<std::pair<uint64_t, NodeValue*>, - value_type, - AttrHashFunction> { -public: - CDAttrHash(context::Context* ctxt) : - context::CDHashMap<std::pair<uint64_t, NodeValue*>, - value_type, - AttrHashFunction>(ctxt) { - } -};/* class CDAttrHash<> */ - -/** - * In the case of Boolean-valued attributes we have a special - * "CDAttrHash<bool>" to pack bits together in words. - */ -template <> -class CDAttrHash<bool> : - protected context::CDHashMap<NodeValue*, - uint64_t, - AttrBoolHashFunction> { - - /** A "super" type, like in Java, for easy reference below. */ - typedef context::CDHashMap<NodeValue*, uint64_t, AttrBoolHashFunction> super; - - /** - * BitAccessor allows us to return a bit "by reference." Of course, - * we don't require bit-addressibility supported by the system, we - * do it with a complex type. - */ - class BitAccessor { - - super& d_map; - - NodeValue* d_key; - - uint64_t d_word; - - unsigned d_bit; - - public: - - BitAccessor(super& map, NodeValue* key, uint64_t word, unsigned bit) : - d_map(map), - d_key(key), - d_word(word), - d_bit(bit) { - /* - Debug.printf("cdboolattr", - "CDAttrHash<bool>::BitAccessor(%p, %p, %016llx, %u)\n", - &map, key, (unsigned long long) word, bit); - */ - } - - BitAccessor& operator=(bool b) { - if(b) { - // set the bit - d_word |= (1 << d_bit); - d_map.insert(d_key, d_word); - /* - Debug.printf("cdboolattr", - "CDAttrHash<bool>::BitAccessor::set(%p, %p, %016llx, %u)\n", - &d_map, d_key, (unsigned long long) d_word, d_bit); - */ - } else { - // clear the bit - d_word &= ~(1 << d_bit); - d_map.insert(d_key, d_word); - /* - Debug.printf("cdboolattr", - "CDAttrHash<bool>::BitAccessor::clr(%p, %p, %016llx, %u)\n", - &d_map, d_key, (unsigned long long) d_word, d_bit); - */ - } - - return *this; - } - - operator bool() const { - /* - Debug.printf("cdboolattr", - "CDAttrHash<bool>::BitAccessor::toBool(%p, %p, %016llx, %u)\n", - &d_map, d_key, (unsigned long long) d_word, d_bit); - */ - return (d_word & (1 << d_bit)) ? true : false; - } - };/* class CDAttrHash<bool>::BitAccessor */ - - /** - * A (somewhat degenerate) const_iterator over boolean-valued - * attributes. This const_iterator doesn't support anything except - * comparison and dereference. It's intended just for the result of - * find() on the table. - */ - class ConstBitIterator { - - const std::pair<NodeValue* const, uint64_t> d_entry; - - unsigned d_bit; - - public: - - ConstBitIterator() : - d_entry(), - d_bit(0) { - } - - ConstBitIterator(const std::pair<NodeValue* const, uint64_t>& entry, - unsigned bit) : - d_entry(entry), - d_bit(bit) { - } - - std::pair<NodeValue* const, bool> operator*() { - return std::make_pair(d_entry.first, - (d_entry.second & (1 << d_bit)) ? true : false); - } - - bool operator==(const ConstBitIterator& b) { - return d_entry == b.d_entry && d_bit == b.d_bit; - } - };/* class CDAttrHash<bool>::ConstBitIterator */ - - /* remove non-permitted operations */ - CDAttrHash(const CDAttrHash<bool>&) CVC4_UNDEFINED; - CDAttrHash<bool>& operator=(const CDAttrHash<bool>&) CVC4_UNDEFINED; - -public: - - CDAttrHash(context::Context* context) : super(context) { } - - typedef std::pair<uint64_t, NodeValue*> key_type; - typedef bool data_type; - typedef std::pair<const key_type, data_type> value_type; - - /** an iterator type; see above for limitations */ - typedef ConstBitIterator iterator; - /** a const_iterator type; see above for limitations */ - typedef ConstBitIterator const_iterator; - - /** - * Find the boolean value in the hash table. Returns something == - * end() if not found. - */ - ConstBitIterator find(const std::pair<uint64_t, NodeValue*>& k) const { - super::const_iterator i = super::find(k.second); - if(i == super::end()) { - return ConstBitIterator(); - } - /* - Debug.printf("cdboolattr", - "underlying word at address looks like 0x%016llx, bit is %u\n", - (unsigned long long)((*i).second), - unsigned(k.first)); - */ - return ConstBitIterator(*i, k.first); - } - - /** The "off the end" const_iterator */ - ConstBitIterator end() const { - return ConstBitIterator(); - } - - /** - * Access the hash table using the underlying operator[]. Inserts - * the key into the table (associated to default value) if it's not - * already there. - */ - BitAccessor operator[](const std::pair<uint64_t, NodeValue*>& k) { - uint64_t word = super::operator[](k.second); - return BitAccessor(*this, k.second, word, k.first); - } - - /** - * Delete all flags from the given node. Simply calls superclass's - * obliterate(). Note this removes all attributes at all context - * levels for this NodeValue! This is important when the NodeValue - * is no longer referenced and is being collected, but otherwise - * it probably isn't useful to do this. - */ - void erase(NodeValue* nv) { - super::obliterate(nv); - } - - /** - * Clear the hash table. This simply exposes the protected superclass - * version of clear() to clients. - */ - void clear() { - super::clear(); - } - - /** Is the hash table empty? */ - bool empty() const { - return super::empty(); - } - - /** This is currently very misleading! */ - size_t size() const { - return super::size(); - } - -};/* class CDAttrHash<bool> */ - }/* CVC4::expr::attr namespace */ // ATTRIBUTE CLEANUP FUNCTIONS ================================================= @@ -853,17 +640,6 @@ public: };/* class Attribute<..., bool, ...> */ /** - * This is a context-dependent attribute kind (the only difference - * between CDAttribute<> and Attribute<> (with the fourth argument - * "true") is that you cannot supply a cleanup function (a no-op one - * is used). - */ -template <class T, - class value_type> -struct CDAttribute : - public Attribute<T, value_type, attr::NullCleanupStrategy, true> {}; - -/** * This is a managed attribute kind (the only difference between * ManagedAttribute<> and Attribute<> is the default cleanup function * and the fact that ManagedAttributes cannot be context-dependent). diff --git a/src/expr/attribute_unique_id.h b/src/expr/attribute_unique_id.h index 4875bdf50..3c09ba4c4 100644 --- a/src/expr/attribute_unique_id.h +++ b/src/expr/attribute_unique_id.h @@ -2,9 +2,9 @@ /*! \file attribute_unique_id.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/chain.h b/src/expr/chain.h index 703aa76ed..755835953 100644 --- a/src/expr/chain.h +++ b/src/expr/chain.h @@ -2,9 +2,9 @@ /*! \file chain.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/convenience_node_builders.h b/src/expr/convenience_node_builders.h deleted file mode 100644 index 611a88e6f..000000000 --- a/src/expr/convenience_node_builders.h +++ /dev/null @@ -1,399 +0,0 @@ -/********************* */ -/*! \file convenience_node_builders.h - ** \verbatim - ** Top contributors (to current version): - ** Morgan Deters, Tim King - ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 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 Convenience node builders. - ** - ** These are convenience node builders for building AND, OR, PLUS, - ** and MULT expressions. - ** - ** \todo These should be moved into theory code (say, - ** src/theory/booleans/node_builders.h and - ** src/theory/arith/node_builders.h), but for now they're here - ** because their design requires CVC4::NodeBuilder to friend them. - **/ - -// TODO: add templatized NodeTemplate<ref_count> to all these inlines -// for 'const [T]Node&' arguments? Technically a lot of time is spent -// in the TNode conversion and copy constructor, but this should be -// optimized into a simple pointer copy (?) -// TODO: double-check this. - -#include "cvc4_private.h" - -#ifndef __CVC4__CONVENIENCE_NODE_BUILDERS_H -#define __CVC4__CONVENIENCE_NODE_BUILDERS_H - -#include "expr/node_builder.h" - -namespace CVC4 { - -class AndNodeBuilder { -public: - NodeBuilder<> d_eb; - - inline AndNodeBuilder(const NodeBuilder<>& eb) : d_eb(eb) { - d_eb.collapseTo(kind::AND); - } - - inline AndNodeBuilder(TNode a, TNode b) : d_eb(kind::AND) { - d_eb << a << b; - } - - template <bool rc> - inline AndNodeBuilder& operator&&(const NodeTemplate<rc>&); - - template <bool rc> - inline OrNodeBuilder operator||(const NodeTemplate<rc>&); - - inline operator NodeBuilder<>() { return d_eb; } - inline operator Node() { return d_eb; } - -};/* class AndNodeBuilder */ - -class OrNodeBuilder { -public: - NodeBuilder<> d_eb; - - inline OrNodeBuilder(const NodeBuilder<>& eb) : d_eb(eb) { - d_eb.collapseTo(kind::OR); - } - - inline OrNodeBuilder(TNode a, TNode b) : d_eb(kind::OR) { - d_eb << a << b; - } - - template <bool rc> - inline AndNodeBuilder operator&&(const NodeTemplate<rc>&); - - template <bool rc> - inline OrNodeBuilder& operator||(const NodeTemplate<rc>&); - - inline operator NodeBuilder<>() { return d_eb; } - inline operator Node() { return d_eb; } - -};/* class OrNodeBuilder */ - -class PlusNodeBuilder { -public: - NodeBuilder<> d_eb; - - inline PlusNodeBuilder(const NodeBuilder<>& eb) : d_eb(eb) { - d_eb.collapseTo(kind::PLUS); - } - - inline PlusNodeBuilder(TNode a, TNode b) : d_eb(kind::PLUS) { - d_eb << a << b; - } - - template <bool rc> - inline PlusNodeBuilder& operator+(const NodeTemplate<rc>&); - - template <bool rc> - inline PlusNodeBuilder& operator-(const NodeTemplate<rc>&); - - template <bool rc> - inline MultNodeBuilder operator*(const NodeTemplate<rc>&); - - inline operator NodeBuilder<>() { return d_eb; } - inline operator Node() { return d_eb; } - -};/* class PlusNodeBuilder */ - -class MultNodeBuilder { -public: - NodeBuilder<> d_eb; - - inline MultNodeBuilder(const NodeBuilder<>& eb) : d_eb(eb) { - d_eb.collapseTo(kind::MULT); - } - - inline MultNodeBuilder(TNode a, TNode b) : d_eb(kind::MULT) { - d_eb << a << b; - } - - template <bool rc> - inline PlusNodeBuilder operator+(const NodeTemplate<rc>&); - - template <bool rc> - inline PlusNodeBuilder operator-(const NodeTemplate<rc>&); - - template <bool rc> - inline MultNodeBuilder& operator*(const NodeTemplate<rc>&); - - inline operator NodeBuilder<>() { return d_eb; } - inline operator Node() { return d_eb; } - -};/* class MultNodeBuilder */ - -template <unsigned nchild_thresh> -inline NodeBuilder<nchild_thresh>& NodeBuilder<nchild_thresh>::operator&=(TNode e) { - return collapseTo(kind::AND).append(e); -} - -template <unsigned nchild_thresh> -inline NodeBuilder<nchild_thresh>& NodeBuilder<nchild_thresh>::operator|=(TNode e) { - return collapseTo(kind::OR).append(e); -} - -template <unsigned nchild_thresh> -inline NodeBuilder<nchild_thresh>& NodeBuilder<nchild_thresh>::operator+=(TNode e) { - return collapseTo(kind::PLUS).append(e); -} - -template <unsigned nchild_thresh> -inline NodeBuilder<nchild_thresh>& NodeBuilder<nchild_thresh>::operator-=(TNode e) { - return collapseTo(kind::PLUS). - append(NodeManager::currentNM()->mkNode(kind::UMINUS, e)); -} - -template <unsigned nchild_thresh> -inline NodeBuilder<nchild_thresh>& NodeBuilder<nchild_thresh>::operator*=(TNode e) { - return collapseTo(kind::MULT).append(e); -} - -template <bool rc> -inline AndNodeBuilder& AndNodeBuilder::operator&&(const NodeTemplate<rc>& n) { - d_eb.append(n); - return *this; -} - -template <bool rc> -inline OrNodeBuilder AndNodeBuilder::operator||(const NodeTemplate<rc>& n) { - return OrNodeBuilder(Node(d_eb), n); -} - -inline AndNodeBuilder& operator&&(AndNodeBuilder& a, - const AndNodeBuilder& b) { - return a && Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline AndNodeBuilder& operator&&(AndNodeBuilder& a, - const OrNodeBuilder& b) { - return a && Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline OrNodeBuilder operator||(AndNodeBuilder& a, - const AndNodeBuilder& b) { - return a || Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline OrNodeBuilder operator||(AndNodeBuilder& a, - const OrNodeBuilder& b) { - return a || Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline AndNodeBuilder OrNodeBuilder::operator&&(const NodeTemplate<rc>& n) { - return AndNodeBuilder(Node(d_eb), n); -} - -template <bool rc> -inline OrNodeBuilder& OrNodeBuilder::operator||(const NodeTemplate<rc>& n) { - d_eb.append(n); - return *this; -} - -inline AndNodeBuilder operator&&(OrNodeBuilder& a, - const AndNodeBuilder& b) { - return a && Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline AndNodeBuilder operator&&(OrNodeBuilder& a, - const OrNodeBuilder& b) { - return a && Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline OrNodeBuilder& operator||(OrNodeBuilder& a, - const AndNodeBuilder& b) { - return a || Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline OrNodeBuilder& operator||(OrNodeBuilder& a, - const OrNodeBuilder& b) { - return a || Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline PlusNodeBuilder& PlusNodeBuilder::operator+(const NodeTemplate<rc>& n) { - d_eb.append(n); - return *this; -} - -template <bool rc> -inline PlusNodeBuilder& PlusNodeBuilder::operator-(const NodeTemplate<rc>& n) { - d_eb.append(NodeManager::currentNM()->mkNode(kind::UMINUS, n)); - return *this; -} - -template <bool rc> -inline MultNodeBuilder PlusNodeBuilder::operator*(const NodeTemplate<rc>& n) { - return MultNodeBuilder(Node(d_eb), n); -} - -inline PlusNodeBuilder& operator+(PlusNodeBuilder& a, - const PlusNodeBuilder& b) { - return a + Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline PlusNodeBuilder& operator+(PlusNodeBuilder& a, - const MultNodeBuilder& b) { - return a + Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline PlusNodeBuilder& operator-(PlusNodeBuilder&a, - const PlusNodeBuilder& b) { - return a - Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline PlusNodeBuilder& operator-(PlusNodeBuilder& a, - const MultNodeBuilder& b) { - return a - Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline MultNodeBuilder operator*(PlusNodeBuilder& a, - const PlusNodeBuilder& b) { - return a * Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline MultNodeBuilder operator*(PlusNodeBuilder& a, - const MultNodeBuilder& b) { - return a * Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline PlusNodeBuilder MultNodeBuilder::operator+(const NodeTemplate<rc>& n) { - return PlusNodeBuilder(Node(d_eb), n); -} - -template <bool rc> -inline PlusNodeBuilder MultNodeBuilder::operator-(const NodeTemplate<rc>& n) { - return PlusNodeBuilder(Node(d_eb), - NodeManager::currentNM()->mkNode(kind::UMINUS, n)); -} - -template <bool rc> -inline MultNodeBuilder& MultNodeBuilder::operator*(const NodeTemplate<rc>& n) { - d_eb.append(n); - return *this; -} - -inline PlusNodeBuilder operator+(MultNodeBuilder& a, - const PlusNodeBuilder& b) { - return a + Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline PlusNodeBuilder operator+(MultNodeBuilder& a, - const MultNodeBuilder& b) { - return a + Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline PlusNodeBuilder operator-(MultNodeBuilder& a, - const PlusNodeBuilder& b) { - return a - Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline PlusNodeBuilder operator-(MultNodeBuilder& a, - const MultNodeBuilder& b) { - return a - Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline MultNodeBuilder& operator*(MultNodeBuilder& a, - const PlusNodeBuilder& b) { - return a * Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} -inline MultNodeBuilder& operator*(MultNodeBuilder& a, - const MultNodeBuilder& b) { - return a * Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc1, bool rc2> -inline AndNodeBuilder operator&&(const NodeTemplate<rc1>& a, - const NodeTemplate<rc2>& b) { - return AndNodeBuilder(a, b); -} - -template <bool rc1, bool rc2> -inline OrNodeBuilder operator||(const NodeTemplate<rc1>& a, - const NodeTemplate<rc2>& b) { - return OrNodeBuilder(a, b); -} - -template <bool rc1, bool rc2> -inline PlusNodeBuilder operator+(const NodeTemplate<rc1>& a, - const NodeTemplate<rc2>& b) { - return PlusNodeBuilder(a, b); -} - -template <bool rc1, bool rc2> -inline PlusNodeBuilder operator-(const NodeTemplate<rc1>& a, - const NodeTemplate<rc2>& b) { - return PlusNodeBuilder(a, NodeManager::currentNM()->mkNode(kind::UMINUS, b)); -} - -template <bool rc1, bool rc2> -inline MultNodeBuilder operator*(const NodeTemplate<rc1>& a, - const NodeTemplate<rc2>& b) { - return MultNodeBuilder(a, b); -} - -template <bool rc> -inline AndNodeBuilder operator&&(const NodeTemplate<rc>& a, - const AndNodeBuilder& b) { - return a && Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline AndNodeBuilder operator&&(const NodeTemplate<rc>& a, - const OrNodeBuilder& b) { - return a && Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline OrNodeBuilder operator||(const NodeTemplate<rc>& a, - const AndNodeBuilder& b) { - return a || Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline OrNodeBuilder operator||(const NodeTemplate<rc>& a, - const OrNodeBuilder& b) { - return a || Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline PlusNodeBuilder operator+(const NodeTemplate<rc>& a, - const PlusNodeBuilder& b) { - return a + Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline PlusNodeBuilder operator+(const NodeTemplate<rc>& a, - const MultNodeBuilder& b) { - return a + Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline PlusNodeBuilder operator-(const NodeTemplate<rc>& a, - const PlusNodeBuilder& b) { - return a - Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline PlusNodeBuilder operator-(const NodeTemplate<rc>& a, - const MultNodeBuilder& b) { - return a - Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline MultNodeBuilder operator*(const NodeTemplate<rc>& a, - const PlusNodeBuilder& b) { - return a * Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline MultNodeBuilder operator*(const NodeTemplate<rc>& a, - const MultNodeBuilder& b) { - return a * Node(const_cast<NodeBuilder<>&>(b.d_eb)); -} - -template <bool rc> -inline NodeTemplate<true> operator-(const NodeTemplate<rc>& a) { - return NodeManager::currentNM()->mkNode(kind::UMINUS, a); -} - -}/* CVC4 namespace */ - -#endif /* __CVC4__CONVENIENCE_NODE_BUILDERS_H */ diff --git a/src/expr/datatype.cpp b/src/expr/datatype.cpp index f80961cf8..4f1fc82b1 100644 --- a/src/expr/datatype.cpp +++ b/src/expr/datatype.cpp @@ -2,9 +2,9 @@ /*! \file datatype.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -28,6 +28,7 @@ #include "expr/node_manager.h" #include "expr/type.h" #include "options/set_language.h" +#include "options/datatypes_options.h" using namespace std; @@ -161,7 +162,7 @@ void Datatype::resolve(ExprManager* em, evalType.push_back(TypeNode::fromType(d_sygus_type)); TypeNode eval_func_type = nm->mkFunctionType(evalType); d_sygus_eval = nm->mkSkolem(name, eval_func_type, "sygus evaluation function").toExpr(); - } + } } void Datatype::addConstructor(const DatatypeConstructor& c) { @@ -180,6 +181,41 @@ void Datatype::setSygus( Type st, Expr bvl, bool allow_const, bool allow_all ){ d_sygus_allow_all = allow_all; } +void Datatype::addSygusConstructor( CVC4::Expr op, std::string& cname, std::vector< CVC4::Type >& cargs, + CVC4::Expr& let_body, std::vector< CVC4::Expr >& let_args, unsigned let_num_input_args ) { + Debug("dt-sygus") << "--> Add constructor " << cname << " to " << getName() << std::endl; + if( !let_body.isNull() ){ + Debug("dt-sygus") << " let body = " << let_body << ", args = " << let_args.size() << "," << let_num_input_args << std::endl; + //TODO : remove arguments not occurring in body + //if this is a self identity function, ignore + if( let_args.size()==0 && let_args[0]==let_body ){ + Debug("dt-sygus") << " identity function " << cargs[0] << " to " << getName() << std::endl; + //TODO + } + } + std::string name = getName() + "_" + cname; + std::string testerId("is-"); + testerId.append(name); + //checkDeclaration(name, CHECK_UNDECLARED, SYM_VARIABLE); + //checkDeclaration(testerId, CHECK_UNDECLARED, SYM_VARIABLE); + CVC4::DatatypeConstructor c(name, testerId ); + c.setSygus( op, let_body, let_args, let_num_input_args ); + for( unsigned j=0; j<cargs.size(); j++ ){ + Debug("parser-sygus-debug") << " arg " << j << " : " << cargs[j] << std::endl; + std::stringstream sname; + sname << name << "_" << j; + c.addArg(sname.str(), cargs[j]); + } + addConstructor(c); +} + +void Datatype::addSygusConstructor( CVC4::Expr op, std::string& cname, std::vector< CVC4::Type >& cargs ) { + CVC4::Expr let_body; + std::vector< CVC4::Expr > let_args; + unsigned let_num_input_args = 0; + addSygusConstructor( op, cname, cargs, let_body, let_args, let_num_input_args ); +} + void Datatype::setTuple() { PrettyCheckArgument(!d_resolved, this, "cannot set tuple to a finalized Datatype"); d_isTuple = true; @@ -584,6 +620,30 @@ const DatatypeConstructor& Datatype::operator[](std::string name) const { IllegalArgument(name, "No such constructor `%s' of datatype `%s'", name.c_str(), d_name.c_str()); } + +Expr Datatype::getSharedSelector( Type dtt, Type t, unsigned index ) const{ + PrettyCheckArgument(isResolved(), this, "this datatype is not yet resolved"); + std::map< Type, std::map< Type, std::map< unsigned, Expr > > >::iterator itd = d_shared_sel.find( dtt ); + if( itd!=d_shared_sel.end() ){ + std::map< Type, std::map< unsigned, Expr > >::iterator its = itd->second.find( t ); + if( its!=itd->second.end() ){ + std::map< unsigned, Expr >::iterator it = its->second.find( index ); + if( it!=its->second.end() ){ + return it->second; + } + } + } + //make the shared selector + Expr s; + NodeManager* nm = NodeManager::fromExprManager( d_self.getExprManager() ); + std::stringstream ss; + ss << "sel_" << index; + s = nm->mkSkolem(ss.str(), nm->mkSelectorType(TypeNode::fromType(dtt), TypeNode::fromType(t)), "is a shared selector", NodeManager::SKOLEM_NO_NOTIFY).toExpr(); + d_shared_sel[dtt][t][index] = s; + Trace("dt-shared-sel") << "Made " << s << " of type " << dtt << " -> " << t << std::endl; + return s; +} + Expr Datatype::getConstructor(std::string name) const { return (*this)[name].getConstructor(); } @@ -797,6 +857,7 @@ Expr DatatypeConstructor::getConstructor() const { Type DatatypeConstructor::getSpecializedConstructorType(Type returnType) const { PrettyCheckArgument(isResolved(), this, "this datatype constructor is not yet resolved"); + PrettyCheckArgument(returnType.isDatatype(), this, "cannot get specialized constructor type for non-datatype type"); ExprManagerScope ems(d_constructor); const Datatype& dt = Datatype::datatypeOf(d_constructor); PrettyCheckArgument(dt.isParametric(), this, "this datatype constructor is not parametric"); @@ -1011,6 +1072,30 @@ Expr DatatypeConstructor::computeGroundTerm( Type t, std::vector< Type >& proces return groundTerm; } +void DatatypeConstructor::computeSharedSelectors( Type domainType ) const { + if( d_shared_selectors[domainType].size()<getNumArgs() ){ + TypeNode ctype; + if( DatatypeType(domainType).isParametric() ){ + ctype = TypeNode::fromType( getSpecializedConstructorType( domainType ) ); + }else{ + ctype = TypeNode::fromType( d_constructor.getType() ); + } + Assert( ctype.isConstructor() ); + Assert( ctype.getNumChildren()-1==getNumArgs() ); + //compute the shared selectors + const Datatype& dt = Datatype::datatypeOf(d_constructor); + std::map< TypeNode, unsigned > counter; + for( unsigned j=0; j<ctype.getNumChildren()-1; j++ ){ + TypeNode t = ctype[j]; + Expr ss = dt.getSharedSelector( domainType, t.toType(), counter[t] ); + d_shared_selectors[domainType].push_back( ss ); + Assert( d_shared_selector_index[domainType].find( ss )==d_shared_selector_index[domainType].end() ); + d_shared_selector_index[domainType][ss] = j; + counter[t]++; + } + } +} + const DatatypeConstructorArg& DatatypeConstructor::operator[](size_t index) const { PrettyCheckArgument(index < getNumArgs(), index, "index out of bounds"); @@ -1069,6 +1154,37 @@ Expr DatatypeConstructorArg::getSelector() const { return d_selector; } +Expr DatatypeConstructor::getSelectorInternal( Type domainType, size_t index ) const { + PrettyCheckArgument(isResolved(), this, "cannot get an internal selector for an unresolved datatype constructor"); + PrettyCheckArgument(index < getNumArgs(), index, "index out of bounds"); + if( options::dtSharedSelectors() ){ + computeSharedSelectors( domainType ); + Assert( d_shared_selectors[domainType].size()==getNumArgs() ); + return d_shared_selectors[domainType][index]; + }else{ + return d_args[index].getSelector(); + } +} + +int DatatypeConstructor::getSelectorIndexInternal( Expr sel ) const { + PrettyCheckArgument(isResolved(), this, "cannot get an internal selector index for an unresolved datatype constructor"); + if( options::dtSharedSelectors() ){ + Assert( sel.getType().isSelector() ); + Type domainType = ((SelectorType)sel.getType()).getDomain(); + computeSharedSelectors( domainType ); + std::map< Expr, unsigned >::iterator its = d_shared_selector_index[domainType].find( sel ); + if( its!=d_shared_selector_index[domainType].end() ){ + return (int)its->second; + } + }else{ + unsigned sindex = Datatype::indexOf(sel); + if( getNumArgs() > sindex && d_args[sindex].getSelector() == sel ){ + return (int)sindex; + } + } + return -1; +} + Expr DatatypeConstructorArg::getConstructor() const { PrettyCheckArgument(isResolved(), this, "cannot get a associated constructor for argument of an unresolved datatype constructor"); diff --git a/src/expr/datatype.h b/src/expr/datatype.h index 88c72ea59..27057ca99 100644 --- a/src/expr/datatype.h +++ b/src/expr/datatype.h @@ -2,9 +2,9 @@ /*! \file datatype.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Morgan Deters, Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,6 +20,7 @@ #ifndef __CVC4__DATATYPE_H #define __CVC4__DATATYPE_H +#include <functional> #include <iostream> #include <string> #include <vector> @@ -197,6 +198,10 @@ private: Expr d_sygus_let_body; std::vector< Expr > d_sygus_let_args; unsigned d_sygus_num_let_input_args; + + /** shared selectors */ + mutable std::map< Type, std::vector< Expr > > d_shared_selectors; + mutable std::map< Type, std::map< Expr, unsigned > > d_shared_selector_index; void resolve(ExprManager* em, DatatypeType self, const std::map<std::string, DatatypeType>& resolutions, @@ -226,6 +231,8 @@ private: bool computeWellFounded( std::vector< Type >& processing ) const throw(IllegalArgumentException); /** compute ground term */ Expr computeGroundTerm( Type t, std::vector< Type >& processing, std::map< Type, Expr >& gt ) const throw(IllegalArgumentException); + /** compute shared selectors */ + void computeSharedSelectors( Type domainType ) const; public: /** * Create a new Datatype constructor with the given name for the @@ -378,6 +385,17 @@ public: */ Expr getSelector(std::string name) const; + + /** + * Get the internal selector for a constructor argument. + */ + Expr getSelectorInternal( Type domainType, size_t index ) const; + + /** + * Get the index for the selector + */ + int getSelectorIndexInternal( Expr sel ) const; + /** * Get whether this datatype involves an external type. If so, * then we will pose additional requirements for sharing. @@ -506,6 +524,8 @@ private: mutable int d_well_founded; // ground term for this datatype mutable std::map< Type, Expr > d_ground_term; + // shared selectors + mutable std::map< Type, std::map< Type, std::map< unsigned, Expr > > > d_shared_sel; /** * Datatypes refer to themselves, recursively, and we have a @@ -549,7 +569,9 @@ private: /** compute whether this datatype is well-founded */ bool computeWellFounded( std::vector< Type >& processing ) const throw(IllegalArgumentException); /** compute ground term */ - Expr computeGroundTerm( Type t, std::vector< Type >& processing ) const throw(IllegalArgumentException); + Expr computeGroundTerm( Type t, std::vector< Type >& processing ) const throw(IllegalArgumentException); + /** Get the shared selector */ + Expr getSharedSelector( Type dtt, Type t, unsigned index ) const; public: /** Create a new Datatype of the given name. */ @@ -575,7 +597,11 @@ public: * allow_const : whether all constants are (implicitly) included in the grammar */ void setSygus( Type st, Expr bvl, bool allow_const, bool allow_all ); - + /** add sygus constructor */ + void addSygusConstructor( CVC4::Expr op, std::string& cname, std::vector< CVC4::Type >& cargs ); + void addSygusConstructor( CVC4::Expr op, std::string& cname, std::vector< CVC4::Type >& cargs, + CVC4::Expr& let_body, std::vector< CVC4::Expr >& let_args, unsigned let_num_input_args ); + /** set tuple */ void setTuple(); @@ -726,7 +752,7 @@ public: * similarly-named constructors, the first is returned. */ const DatatypeConstructor& operator[](std::string name) const; - + /** * Get the constructor operator for the named constructor. * This is a linear search through the constructors, so in @@ -763,16 +789,16 @@ public: */ struct CVC4_PUBLIC DatatypeHashFunction { inline size_t operator()(const Datatype& dt) const { - return StringHashFunction()(dt.getName()); + return std::hash<std::string>()(dt.getName()); } inline size_t operator()(const Datatype* dt) const { - return StringHashFunction()(dt->getName()); + return std::hash<std::string>()(dt->getName()); } inline size_t operator()(const DatatypeConstructor& dtc) const { - return StringHashFunction()(dtc.getName()); + return std::hash<std::string>()(dtc.getName()); } inline size_t operator()(const DatatypeConstructor* dtc) const { - return StringHashFunction()(dtc->getName()); + return std::hash<std::string>()(dtc->getName()); } };/* struct DatatypeHashFunction */ diff --git a/src/expr/emptyset.cpp b/src/expr/emptyset.cpp index 23e6df7dc..42560fa11 100644 --- a/src/expr/emptyset.cpp +++ b/src/expr/emptyset.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Kshitij Bansal, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/emptyset.h b/src/expr/emptyset.h index a606951f0..8cb2bbf41 100644 --- a/src/expr/emptyset.h +++ b/src/expr/emptyset.h @@ -2,9 +2,9 @@ /*! \file emptyset.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Kshitij Bansal, Morgan Deters + ** Kshitij Bansal, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/expr.i b/src/expr/expr.i index 49cb24321..93a0cbe99 100644 --- a/src/expr/expr.i +++ b/src/expr/expr.i @@ -153,7 +153,6 @@ namespace CVC4 { %template(getConstDatatypeIndexConstant) CVC4::Expr::getConst<CVC4::DatatypeIndexConstant>; %template(getConstRational) CVC4::Expr::getConst<CVC4::Rational>; %template(getConstBitVector) CVC4::Expr::getConst<CVC4::BitVector>; -%template(getConstPredicate) CVC4::Expr::getConst<CVC4::Predicate>; %template(getConstString) CVC4::Expr::getConst<CVC4::String>; %template(getConstRegExp) CVC4::Expr::getConst<CVC4::RegExp>; %template(getConstEmptySet) CVC4::Expr::getConst<CVC4::EmptySet>; diff --git a/src/expr/expr_iomanip.cpp b/src/expr/expr_iomanip.cpp index 1d6df2a4e..abb401e45 100644 --- a/src/expr/expr_iomanip.cpp +++ b/src/expr/expr_iomanip.cpp @@ -2,9 +2,9 @@ /*! \file expr_iomanip.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/expr_iomanip.h b/src/expr/expr_iomanip.h index 94e2b46ea..02135529a 100644 --- a/src/expr/expr_iomanip.h +++ b/src/expr/expr_iomanip.h @@ -2,9 +2,9 @@ /*! \file expr_iomanip.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/expr_manager.i b/src/expr/expr_manager.i index f8bb55523..b8f8d5da9 100644 --- a/src/expr/expr_manager.i +++ b/src/expr/expr_manager.i @@ -70,7 +70,6 @@ %template(mkConst) CVC4::ExprManager::mkConst<CVC4::RecordUpdate>; %template(mkConst) CVC4::ExprManager::mkConst<CVC4::Rational>; %template(mkConst) CVC4::ExprManager::mkConst<CVC4::BitVector>; -%template(mkConst) CVC4::ExprManager::mkConst<CVC4::Predicate>; %template(mkConst) CVC4::ExprManager::mkConst<CVC4::EmptySet>; %template(mkConst) CVC4::ExprManager::mkConst<CVC4::String>; %template(mkConst) CVC4::ExprManager::mkConst<CVC4::RegExp>; diff --git a/src/expr/expr_manager_scope.h b/src/expr/expr_manager_scope.h index cd4c274e5..58a8612ce 100644 --- a/src/expr/expr_manager_scope.h +++ b/src/expr/expr_manager_scope.h @@ -2,9 +2,9 @@ /*! \file expr_manager_scope.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/expr_manager_template.cpp b/src/expr/expr_manager_template.cpp index cb8ad710f..d6249d6fd 100644 --- a/src/expr/expr_manager_template.cpp +++ b/src/expr/expr_manager_template.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -842,43 +842,6 @@ SortConstructorType ExprManager::mkSortConstructor(const std::string& name, new TypeNode(d_nodeManager->mkSortConstructor(name, arity)))); } -/* - not in release 1.0 -Type ExprManager::mkPredicateSubtype(Expr lambda) - throw(TypeCheckingException) { - NodeManagerScope nms(d_nodeManager); - try { - return PredicateSubtype(Type(d_nodeManager, - new TypeNode(d_nodeManager->mkPredicateSubtype(lambda)))); - } catch (const TypeCheckingExceptionPrivate& e) { - throw TypeCheckingException(this, &e); - } -} -*/ - -/* - not in release 1.0 -Type ExprManager::mkPredicateSubtype(Expr lambda, Expr witness) - throw(TypeCheckingException) { - NodeManagerScope nms(d_nodeManager); - try { - return PredicateSubtype(Type(d_nodeManager, - new TypeNode(d_nodeManager->mkPredicateSubtype(lambda, witness)))); - } catch (const TypeCheckingExceptionPrivate& e) { - throw TypeCheckingException(this, &e); - } -} -*/ - -Type ExprManager::mkSubrangeType(const SubrangeBounds& bounds) - throw(TypeCheckingException) { - NodeManagerScope nms(d_nodeManager); - try { - return SubrangeType(Type(d_nodeManager, - new TypeNode(d_nodeManager->mkSubrangeType(bounds)))); - } catch (const TypeCheckingExceptionPrivate& e) { - throw TypeCheckingException(this, &e); - } -} - /** * Get the type for the given Expr and optionally do type checking. * @@ -1062,8 +1025,6 @@ TypeNode exportTypeInternal(TypeNode n, NodeManager* from, NodeManager* to, Expr return to->mkTypeConst(n.getConst<TypeConstant>()); } else if(n.getKind() == kind::BITVECTOR_TYPE) { return to->mkBitVectorType(n.getConst<BitVectorSize>()); - } else if(n.getKind() == kind::SUBRANGE_TYPE) { - return to->mkSubrangeType(n.getSubrangeBounds()); } Type from_t = from->toType(n); Type& to_t = vmap.d_typeMap[from_t]; diff --git a/src/expr/expr_manager_template.h b/src/expr/expr_manager_template.h index 07ace173c..8719d8ef4 100644 --- a/src/expr/expr_manager_template.h +++ b/src/expr/expr_manager_template.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -461,8 +461,8 @@ public: /** * Make an integer subrange type as defined by the argument. */ - Type mkSubrangeType(const SubrangeBounds& bounds) - throw(TypeCheckingException); + //Type mkSubrangeType(const SubrangeBounds& bounds) + // throw(TypeCheckingException); /** Get the type of an expression */ Type getType(Expr e, bool check = false) diff --git a/src/expr/expr_stream.h b/src/expr/expr_stream.h index d3dbd2902..5a17711d0 100644 --- a/src/expr/expr_stream.h +++ b/src/expr/expr_stream.h @@ -2,9 +2,9 @@ /*! \file expr_stream.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/expr_template.cpp b/src/expr/expr_template.cpp index 806650e57..b0611ccbb 100644 --- a/src/expr/expr_template.cpp +++ b/src/expr/expr_template.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Kshitij Bansal, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -115,7 +115,7 @@ static Node exportConstant(TNode n, NodeManager* to, ExprManagerMapCollection& v class ExportPrivate { private: - typedef std::hash_map <NodeTemplate<false>, NodeTemplate<true>, TNodeHashFunction> ExportCache; + typedef std::unordered_map <NodeTemplate<false>, NodeTemplate<true>, TNodeHashFunction> ExportCache; ExprManager* from; ExprManager* to; ExprManagerMapCollection& vmap; @@ -393,7 +393,7 @@ static inline NodePairIteratorAdaptor<Iterator> mkNodePairIteratorAdaptor(Iterat return NodePairIteratorAdaptor<Iterator>(i); } -Expr Expr::substitute(const std::hash_map<Expr, Expr, ExprHashFunction> map) const { +Expr Expr::substitute(const std::unordered_map<Expr, Expr, ExprHashFunction> map) const { ExprManagerScope ems(*this); return Expr(d_exprManager, new Node(d_node->substitute(mkNodePairIteratorAdaptor(map.begin()), mkNodePairIteratorAdaptor(map.end())))); } diff --git a/src/expr/expr_template.h b/src/expr/expr_template.h index 5c3f89e9c..d2ad45dee 100644 --- a/src/expr/expr_template.h +++ b/src/expr/expr_template.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -29,8 +29,8 @@ ${includes} #include <stdint.h> #include <iostream> #include <iterator> - #include <string> +#include <unordered_map> #include "base/exception.h" #include "options/language.h" @@ -433,7 +433,7 @@ public: /** * Substitute pairs of (ex,replacement) from the given map. */ - Expr substitute(const std::hash_map<Expr, Expr, ExprHashFunction> map) const; + Expr substitute(const std::unordered_map<Expr, Expr, ExprHashFunction> map) const; /** * Returns the string representation of the expression. diff --git a/src/expr/kind_map.h b/src/expr/kind_map.h index 6858f8ab9..a7ee7322a 100644 --- a/src/expr/kind_map.h +++ b/src/expr/kind_map.h @@ -2,9 +2,9 @@ /*! \file kind_map.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Tim King + ** Dejan Jovanovic, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/kind_template.h b/src/expr/kind_template.h index 440d6b586..d8c96ffa1 100644 --- a/src/expr/kind_template.h +++ b/src/expr/kind_template.h @@ -2,9 +2,9 @@ /*! \file kind_template.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Morgan Deters, Dejan Jovanovic, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/matcher.h b/src/expr/matcher.h index 308ad06df..5c5adb621 100644 --- a/src/expr/matcher.h +++ b/src/expr/matcher.h @@ -2,9 +2,9 @@ /*! \file matcher.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Morgan Deters, Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/metakind_template.h b/src/expr/metakind_template.h index 2dcf24b09..b2e88c1ff 100644 --- a/src/expr/metakind_template.h +++ b/src/expr/metakind_template.h @@ -2,9 +2,9 @@ /*! \file metakind_template.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/node.cpp b/src/expr/node.cpp index 793b6af97..0c844f92d 100644 --- a/src/expr/node.cpp +++ b/src/expr/node.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -22,6 +22,8 @@ #include "base/output.h" #include "expr/attribute.h" +#include "theory/quantifiers/term_database.h" + using namespace std; @@ -111,6 +113,15 @@ bool NodeTemplate<ref_count>::hasBoundVar() { for(iterator i = begin(); i != end() && !hasBv; ++i) { hasBv = (*i).hasBoundVar(); } + if( !hasBv ){ + //FIXME : this is a hack to handle synthesis conjectures + // the issue is that we represent second-order quantification in synthesis conjectures via a Node: + // exists x forall y P[f,y], where x is a dummy variable that maps to f through attribute SygusSynthFunVarListAttributeId + // when asked whether a node has a bound variable, we want to treat f as if it were a bound (second-order) variable. -AJR + if( getKind()==kind::APPLY_UF && getOperator().hasAttribute(theory::SygusSynthFunVarListAttribute()) ){ + hasBv = true; + } + } } setAttribute(HasBoundVarAttr(), hasBv); setAttribute(HasBoundVarComputedAttr(), true); diff --git a/src/expr/node.h b/src/expr/node.h index bd1b5e63c..7a8bafe38 100644 --- a/src/expr/node.h +++ b/src/expr/node.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -22,13 +22,16 @@ #ifndef __CVC4__NODE_H #define __CVC4__NODE_H -#include <vector> -#include <string> -#include <iostream> -#include <utility> +#include <stdint.h> + #include <algorithm> #include <functional> -#include <stdint.h> +#include <iostream> +#include <string> +#include <unordered_map> +#include <unordered_set> +#include <utility> +#include <vector> #include "base/configuration.h" #include "base/cvc4_assert.h" @@ -42,7 +45,6 @@ #include "options/language.h" #include "options/set_language.h" #include "util/utility.h" -#include "util/hash.h" namespace CVC4 { @@ -243,7 +245,7 @@ public: * member function with a similar signature. */ Node substitute(TNode node, TNode replacement, - std::hash_map<TNode, TNode, TNodeHashFunction>& cache) const; + std::unordered_map<TNode, TNode, TNodeHashFunction>& cache) const; /** * Cache-aware, recursive version of substitute() used by the public @@ -252,7 +254,7 @@ public: template <class Iterator1, class Iterator2> Node substitute(Iterator1 nodesBegin, Iterator1 nodesEnd, Iterator2 replacementsBegin, Iterator2 replacementsEnd, - std::hash_map<TNode, TNode, TNodeHashFunction>& cache) const; + std::unordered_map<TNode, TNode, TNodeHashFunction>& cache) const; /** * Cache-aware, recursive version of substitute() used by the public @@ -260,7 +262,7 @@ public: */ template <class Iterator> Node substitute(Iterator substitutionsBegin, Iterator substitutionsEnd, - std::hash_map<TNode, TNode, TNodeHashFunction>& cache) const; + std::unordered_map<TNode, TNode, TNodeHashFunction>& cache) const; /** Default constructor, makes a null expression. */ NodeTemplate() : d_nv(&expr::NodeValue::null()) { } @@ -943,8 +945,6 @@ inline std::ostream& operator<<(std::ostream& out, }/* CVC4 namespace */ -#include <ext/hash_map> - //#include "expr/attribute.h" #include "expr/node_manager.h" #include "expr/type_checker.h" @@ -1296,14 +1296,14 @@ NodeTemplate<ref_count>::substitute(TNode node, TNode replacement) const { if (node == *this) { return replacement; } - std::hash_map<TNode, TNode, TNodeHashFunction> cache; + std::unordered_map<TNode, TNode, TNodeHashFunction> cache; return substitute(node, replacement, cache); } template <bool ref_count> Node NodeTemplate<ref_count>::substitute(TNode node, TNode replacement, - std::hash_map<TNode, TNode, TNodeHashFunction>& cache) const { + std::unordered_map<TNode, TNode, TNodeHashFunction>& cache) const { Assert(node != *this); if (getNumChildren() == 0) { @@ -1311,7 +1311,7 @@ NodeTemplate<ref_count>::substitute(TNode node, TNode replacement, } // in cache? - typename std::hash_map<TNode, TNode, TNodeHashFunction>::const_iterator i = cache.find(*this); + typename std::unordered_map<TNode, TNode, TNodeHashFunction>::const_iterator i = cache.find(*this); if(i != cache.end()) { return (*i).second; } @@ -1351,7 +1351,7 @@ NodeTemplate<ref_count>::substitute(Iterator1 nodesBegin, Iterator1 nodesEnd, Iterator2 replacementsBegin, Iterator2 replacementsEnd) const { - std::hash_map<TNode, TNode, TNodeHashFunction> cache; + std::unordered_map<TNode, TNode, TNodeHashFunction> cache; return substitute(nodesBegin, nodesEnd, replacementsBegin, replacementsEnd, cache); } @@ -1363,9 +1363,9 @@ NodeTemplate<ref_count>::substitute(Iterator1 nodesBegin, Iterator1 nodesEnd, Iterator2 replacementsBegin, Iterator2 replacementsEnd, - std::hash_map<TNode, TNode, TNodeHashFunction>& cache) const { + std::unordered_map<TNode, TNode, TNodeHashFunction>& cache) const { // in cache? - typename std::hash_map<TNode, TNode, TNodeHashFunction>::const_iterator i = cache.find(*this); + typename std::unordered_map<TNode, TNode, TNodeHashFunction>::const_iterator i = cache.find(*this); if(i != cache.end()) { return (*i).second; } @@ -1410,7 +1410,7 @@ template <class Iterator> inline Node NodeTemplate<ref_count>::substitute(Iterator substitutionsBegin, Iterator substitutionsEnd) const { - std::hash_map<TNode, TNode, TNodeHashFunction> cache; + std::unordered_map<TNode, TNode, TNodeHashFunction> cache; return substitute(substitutionsBegin, substitutionsEnd, cache); } @@ -1419,9 +1419,9 @@ template <class Iterator> Node NodeTemplate<ref_count>::substitute(Iterator substitutionsBegin, Iterator substitutionsEnd, - std::hash_map<TNode, TNode, TNodeHashFunction>& cache) const { + std::unordered_map<TNode, TNode, TNodeHashFunction>& cache) const { // in cache? - typename std::hash_map<TNode, TNode, TNodeHashFunction>::const_iterator i = cache.find(*this); + typename std::unordered_map<TNode, TNode, TNodeHashFunction>::const_iterator i = cache.find(*this); if(i != cache.end()) { return (*i).second; } @@ -1468,7 +1468,7 @@ inline Node NodeTemplate<true>::fromExpr(const Expr& e) { template<bool ref_count> bool NodeTemplate<ref_count>::hasSubterm(NodeTemplate<false> t, bool strict) const { - typedef std::hash_set<TNode, TNodeHashFunction> node_set; + typedef std::unordered_set<TNode, TNodeHashFunction> node_set; if (!strict && *this == t) { return true; diff --git a/src/expr/node_builder.h b/src/expr/node_builder.h index 7cb14ed5a..2d45d0367 100644 --- a/src/expr/node_builder.h +++ b/src/expr/node_builder.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -155,10 +155,11 @@ #ifndef __CVC4__NODE_BUILDER_H #define __CVC4__NODE_BUILDER_H -#include <iostream> -#include <vector> #include <cstdlib> +#include <iostream> +#include <memory> #include <stdint.h> +#include <vector> namespace CVC4 { static const unsigned default_nchild_thresh = 10; @@ -171,7 +172,6 @@ namespace CVC4 { #include "base/cvc4_assert.h" #include "base/output.h" -#include "base/ptr_closer.h" #include "expr/kind.h" #include "expr/metakind.h" #include "expr/node_value.h" @@ -179,12 +179,6 @@ namespace CVC4 { namespace CVC4 { -/* see expr/convenience_node_builders.h */ -class AndNodeBuilder; -class OrNodeBuilder; -class PlusNodeBuilder; -class MultNodeBuilder; - // Sometimes it's useful for debugging to output a NodeBuilder that // isn't yet a Node.. template <unsigned nchild_thresh> @@ -728,11 +722,6 @@ public: NodeBuilder<nchild_thresh>& operator-=(TNode); NodeBuilder<nchild_thresh>& operator*=(TNode); - friend class AndNodeBuilder; - friend class OrNodeBuilder; - friend class PlusNodeBuilder; - friend class MultNodeBuilder; - // This is needed for copy constructors of different sizes to access // private fields template <unsigned N> @@ -890,14 +879,14 @@ template <unsigned nchild_thresh> Node* NodeBuilder<nchild_thresh>::constructNodePtr() { // maybeCheckType() can throw an exception. Make sure to call the destructor // on the exception branch. - PtrCloser<Node> np(new Node(constructNV())); + std::unique_ptr<Node> np(new Node(constructNV())); maybeCheckType(*np.get()); return np.release(); } template <unsigned nchild_thresh> Node* NodeBuilder<nchild_thresh>::constructNodePtr() const { - PtrCloser<Node> np(new Node(constructNV())); + std::unique_ptr<Node> np(new Node(constructNV())); maybeCheckType(*np.get()); return np.release(); } diff --git a/src/expr/node_manager.cpp b/src/expr/node_manager.cpp index 66a56b2ab..e440261cb 100644 --- a/src/expr/node_manager.cpp +++ b/src/expr/node_manager.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -18,7 +18,6 @@ #include "expr/node_manager.h" #include <algorithm> -#include <ext/hash_set> #include <stack> #include <utility> @@ -36,7 +35,6 @@ using namespace std; using namespace CVC4::expr; -using __gnu_cxx::hash_set; namespace CVC4 { @@ -506,51 +504,6 @@ TypeNode NodeManager::mkConstructorType(const DatatypeConstructor& constructor, return mkTypeNode(kind::CONSTRUCTOR_TYPE, sorts); } -TypeNode NodeManager::mkPredicateSubtype(Expr lambda) - throw(TypeCheckingExceptionPrivate) { - - Node lambdan = Node::fromExpr(lambda); - - if(lambda.isNull()) { - throw TypeCheckingExceptionPrivate(lambdan, "cannot make a predicate subtype based on null expression"); - } - - TypeNode tn = lambdan.getType(); - if(! tn.isPredicateLike() || - tn.getArgTypes().size() != 1) { - stringstream ss; - ss << "expected a predicate of one argument to define predicate subtype, but got type `" << tn << "'"; - throw TypeCheckingExceptionPrivate(lambdan, ss.str()); - } - - return TypeNode(mkTypeConst(Predicate(lambda))); -} - -TypeNode NodeManager::mkPredicateSubtype(Expr lambda, Expr witness) - throw(TypeCheckingExceptionPrivate) { - - Node lambdan = Node::fromExpr(lambda); - - if(lambda.isNull()) { - throw TypeCheckingExceptionPrivate(lambdan, "cannot make a predicate subtype based on null expression"); - } - - TypeNode tn = lambdan.getType(); - if(! tn.isPredicateLike() || - tn.getArgTypes().size() != 1) { - stringstream ss; - ss << "expected a predicate of one argument to define predicate subtype, but got type `" << tn << "'"; - throw TypeCheckingExceptionPrivate(lambdan, ss.str()); - } - - return TypeNode(mkTypeConst(Predicate(lambda, witness))); -} - -TypeNode NodeManager::mkSubrangeType(const SubrangeBounds& bounds) - throw(TypeCheckingExceptionPrivate) { - return TypeNode(mkTypeConst(bounds)); -} - TypeNode NodeManager::TupleTypeCache::getTupleType( NodeManager * nm, std::vector< TypeNode >& types, unsigned index ) { if( index==types.size() ){ if( d_data.isNull() ){ diff --git a/src/expr/node_manager.h b/src/expr/node_manager.h index 3aa826b49..f112381d8 100644 --- a/src/expr/node_manager.h +++ b/src/expr/node_manager.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Christopher L. Conway, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -30,7 +30,7 @@ #include <vector> #include <string> -#include <ext/hash_set> +#include <unordered_set> #include "base/tls.h" #include "expr/kind.h" @@ -95,12 +95,12 @@ class NodeManager { bool operator()(expr::NodeValue* nv) { return nv->d_rc > 0; } }; - typedef __gnu_cxx::hash_set<expr::NodeValue*, - expr::NodeValuePoolHashFunction, - expr::NodeValuePoolEq> NodeValuePool; - typedef __gnu_cxx::hash_set<expr::NodeValue*, - expr::NodeValueIDHashFunction, - expr::NodeValueIDEquality> NodeValueIDSet; + typedef std::unordered_set<expr::NodeValue*, + expr::NodeValuePoolHashFunction, + expr::NodeValuePoolEq> NodeValuePool; + typedef std::unordered_set<expr::NodeValue*, + expr::NodeValueIDHashFunction, + expr::NodeValueIDEquality> NodeValueIDSet; static CVC4_THREADLOCAL(NodeManager*) s_current; @@ -875,31 +875,6 @@ public: TypeNode mkSortConstructor(const std::string& name, size_t arity); /** - * Make a predicate subtype type defined by the given LAMBDA - * expression. A TypeCheckingExceptionPrivate can be thrown if - * lambda is not a LAMBDA, or is ill-typed, or if CVC4 fails at - * proving that the resulting predicate subtype is inhabited. - */ - TypeNode mkPredicateSubtype(Expr lambda) - throw(TypeCheckingExceptionPrivate); - - /** - * Make a predicate subtype type defined by the given LAMBDA - * expression and whose non-emptiness is witnessed by the given - * witness. A TypeCheckingExceptionPrivate can be thrown if lambda - * is not a LAMBDA, or is ill-typed, or if the witness is not a - * witness or ill-typed. - */ - TypeNode mkPredicateSubtype(Expr lambda, Expr witness) - throw(TypeCheckingExceptionPrivate); - - /** - * Make an integer subrange type as defined by the argument. - */ - TypeNode mkSubrangeType(const SubrangeBounds& bounds) - throw(TypeCheckingExceptionPrivate); - - /** * Get the type for the given node and optionally do type checking. * * Initial type computation will be near-constant time if diff --git a/src/expr/node_manager_attributes.h b/src/expr/node_manager_attributes.h index 20e1c6c50..06cdd2599 100644 --- a/src/expr/node_manager_attributes.h +++ b/src/expr/node_manager_attributes.h @@ -2,9 +2,9 @@ /*! \file node_manager_attributes.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/node_manager_listeners.cpp b/src/expr/node_manager_listeners.cpp index 3915aa9bd..4724e5d0f 100644 --- a/src/expr/node_manager_listeners.cpp +++ b/src/expr/node_manager_listeners.cpp @@ -2,9 +2,9 @@ /*! \file node_manager_listeners.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/node_manager_listeners.h b/src/expr/node_manager_listeners.h index caff3a545..bdfe5a487 100644 --- a/src/expr/node_manager_listeners.h +++ b/src/expr/node_manager_listeners.h @@ -2,9 +2,9 @@ /*! \file node_manager_listeners.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/node_self_iterator.h b/src/expr/node_self_iterator.h index 9d37f6e6e..6d655e1fe 100644 --- a/src/expr/node_self_iterator.h +++ b/src/expr/node_self_iterator.h @@ -2,9 +2,9 @@ /*! \file node_self_iterator.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -27,7 +27,7 @@ namespace CVC4 { namespace expr { -class NodeSelfIterator : std::iterator<std::input_iterator_tag, Node> { +class NodeSelfIterator : public std::iterator<std::input_iterator_tag, Node> { Node d_node; Node::const_iterator d_child; diff --git a/src/expr/node_value.cpp b/src/expr/node_value.cpp index f8de8c0c8..3dd1fe8ce 100644 --- a/src/expr/node_value.cpp +++ b/src/expr/node_value.cpp @@ -2,9 +2,9 @@ /*! \file node_value.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Clark Barrett + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/node_value.h b/src/expr/node_value.h index 79ce8cb4f..84fd5cb2d 100644 --- a/src/expr/node_value.h +++ b/src/expr/node_value.h @@ -2,9 +2,9 @@ /*! \file node_value.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Morgan Deters, Tim King, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -39,10 +39,6 @@ namespace CVC4 { template <bool ref_count> class NodeTemplate; class TypeNode; template <unsigned N> class NodeBuilder; -class AndNodeBuilder; -class OrNodeBuilder; -class PlusNodeBuilder; -class MultNodeBuilder; class NodeManager; namespace expr { diff --git a/src/expr/pickle_data.cpp b/src/expr/pickle_data.cpp index 2050d2d15..00143d709 100644 --- a/src/expr/pickle_data.cpp +++ b/src/expr/pickle_data.cpp @@ -2,9 +2,9 @@ /*! \file pickle_data.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/pickle_data.h b/src/expr/pickle_data.h index 6c283719a..ff355dedd 100644 --- a/src/expr/pickle_data.h +++ b/src/expr/pickle_data.h @@ -2,9 +2,9 @@ /*! \file pickle_data.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/pickler.cpp b/src/expr/pickler.cpp index ab8037a9a..c4bb633bd 100644 --- a/src/expr/pickler.cpp +++ b/src/expr/pickler.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Kshitij Bansal, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/pickler.h b/src/expr/pickler.h index abd927788..f9a3d07bd 100644 --- a/src/expr/pickler.h +++ b/src/expr/pickler.h @@ -2,9 +2,9 @@ /*! \file pickler.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Kshitij Bansal + ** Morgan Deters, Paul Meng, Kshitij Bansal ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/predicate.cpp b/src/expr/predicate.cpp deleted file mode 100644 index 52b580148..000000000 --- a/src/expr/predicate.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/********************* */ -/*! \file predicate.cpp - ** \verbatim - ** Top contributors (to current version): - ** Tim King, Morgan Deters - ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 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 Representation of predicates for predicate subtyping - ** - ** Simple class to represent predicates for predicate subtyping. - ** Instances of this class are carried as the payload of - ** the CONSTANT-metakinded SUBTYPE_TYPE types. - **/ -#include "expr/predicate.h" - -#include "base/cvc4_assert.h" -#include "expr/expr.h" - - -using namespace std; - -namespace CVC4 { - -Predicate::Predicate(const Predicate& p) - : d_predicate(new Expr(p.getExpression())) - , d_witness(new Expr(p.getWitness())) -{} - -Predicate::Predicate(const Expr& e) throw(IllegalArgumentException) - : d_predicate(new Expr(e)) - , d_witness(new Expr()) -{ - PrettyCheckArgument(! e.isNull(), e, "Predicate cannot be null"); - PrettyCheckArgument(e.getType().isPredicate(), e, - "Expression given is not predicate"); - PrettyCheckArgument(FunctionType(e.getType()).getArgTypes().size() == 1, e, - "Expression given is not predicate of a single argument"); -} - -Predicate::Predicate(const Expr& e, const Expr& w) - throw(IllegalArgumentException) - : d_predicate(new Expr(e)) - , d_witness(new Expr(w)) -{ - PrettyCheckArgument(! e.isNull(), e, "Predicate cannot be null"); - PrettyCheckArgument(e.getType().isPredicate(), e, - "Expression given is not predicate"); - PrettyCheckArgument(FunctionType(e.getType()).getArgTypes().size() == 1, e, - "Expression given is not predicate of a single argument"); -} - -Predicate::~Predicate() { - delete d_predicate; - delete d_witness; -} - -Predicate& Predicate::operator=(const Predicate& p){ - (*d_predicate) = p.getExpression(); - (*d_witness) = p.getWitness(); - return *this; -} - - -// Predicate::operator Expr() const { -// return d_predicate; -// } - -const Expr& Predicate::getExpression() const { - return *d_predicate; -} - -const Expr& Predicate::getWitness() const { - return *d_witness; -} - -bool Predicate::operator==(const Predicate& p) const { - return getExpression() == p.getExpression() && - getWitness() == p.getWitness(); -} - -std::ostream& operator<<(std::ostream& out, const Predicate& p) { - out << p.getExpression(); - const Expr& witness = p.getWitness(); - if(! witness.isNull()) { - out << " : " << witness; - } - return out; -} - -size_t PredicateHashFunction::operator()(const Predicate& p) const { - ExprHashFunction h; - return h(p.getWitness()) * 5039 + h(p.getExpression()); -} - -}/* CVC4 namespace */ diff --git a/src/expr/predicate.h b/src/expr/predicate.h deleted file mode 100644 index a7003fbd1..000000000 --- a/src/expr/predicate.h +++ /dev/null @@ -1,72 +0,0 @@ -/********************* */ -/*! \file predicate.h - ** \verbatim - ** Top contributors (to current version): - ** Morgan Deters, Tim King - ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 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 Representation of predicates for predicate subtyping - ** - ** Simple class to represent predicates for predicate subtyping. - ** Instances of this class are carried as the payload of - ** the CONSTANT-metakinded SUBTYPE_TYPE types. - **/ - -#include "cvc4_public.h" - -#ifndef __CVC4__PREDICATE_H -#define __CVC4__PREDICATE_H - -#include "base/exception.h" - -namespace CVC4 { - -class Predicate; - -std::ostream& operator<<(std::ostream& out, const Predicate& p) CVC4_PUBLIC; - -struct CVC4_PUBLIC PredicateHashFunction { - size_t operator()(const Predicate& p) const; -};/* class PredicateHashFunction */ - -}/* CVC4 namespace */ - - -namespace CVC4 { -class CVC4_PUBLIC Expr; -}/* CVC4 namespace */ - - -namespace CVC4 { -class CVC4_PUBLIC Predicate { -public: - - Predicate(const Expr& e) throw(IllegalArgumentException); - Predicate(const Expr& e, const Expr& w) throw(IllegalArgumentException); - - Predicate(const Predicate& p); - ~Predicate(); - Predicate& operator=(const Predicate& p); - - //operator Expr() const; - - const Expr& getExpression() const; - const Expr& getWitness() const; - - bool operator==(const Predicate& p) const; - - friend std::ostream& CVC4::operator<<(std::ostream& out, const Predicate& p); - friend size_t PredicateHashFunction::operator()(const Predicate& p) const; - -private: - Expr* d_predicate; - Expr* d_witness; -};/* class Predicate */ - -}/* CVC4 namespace */ - -#endif /* __CVC4__PREDICATE_H */ diff --git a/src/expr/predicate.i b/src/expr/predicate.i deleted file mode 100644 index aa80a98b5..000000000 --- a/src/expr/predicate.i +++ /dev/null @@ -1,12 +0,0 @@ -%{ -#include "expr/predicate.h" -%} - -%rename(equals) CVC4::Predicate::operator==(const Predicate&) const; -%rename(toExpr) CVC4::Predicate::operator Expr() const; - -%rename(apply) CVC4::PredicateHashFunction::operator()(const Predicate&) const; - -%ignore CVC4::operator<<(std::ostream&, const Predicate&); - -%include "expr/predicate.h" diff --git a/src/expr/record.cpp b/src/expr/record.cpp index 0d2fd6527..4b2d50ea6 100644 --- a/src/expr/record.cpp +++ b/src/expr/record.cpp @@ -2,9 +2,9 @@ /*! \file record.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/record.h b/src/expr/record.h index 84feb7e1d..7c5854db2 100644 --- a/src/expr/record.h +++ b/src/expr/record.h @@ -2,9 +2,9 @@ /*! \file record.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,11 +19,11 @@ #ifndef __CVC4__RECORD_H #define __CVC4__RECORD_H +#include <functional> #include <iostream> #include <string> #include <vector> #include <utility> -#include "util/hash.h" // Forward Declarations namespace CVC4 { @@ -56,13 +56,13 @@ public: struct CVC4_PUBLIC RecordSelectHashFunction { inline size_t operator()(const RecordSelect& t) const { - return StringHashFunction()(t.getField()); + return std::hash<std::string>()(t.getField()); } };/* struct RecordSelectHashFunction */ struct CVC4_PUBLIC RecordUpdateHashFunction { inline size_t operator()(const RecordUpdate& t) const { - return StringHashFunction()(t.getField()); + return std::hash<std::string>()(t.getField()); } };/* struct RecordUpdateHashFunction */ diff --git a/src/expr/symbol_table.cpp b/src/expr/symbol_table.cpp index 185006e73..ba731ec1e 100644 --- a/src/expr/symbol_table.cpp +++ b/src/expr/symbol_table.cpp @@ -2,9 +2,9 @@ /*! \file symbol_table.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Christopher L. Conway, Tim King + ** Morgan Deters, Christopher L. Conway, Francois Bobot ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -18,6 +18,7 @@ #include "expr/symbol_table.h" +#include <ostream> #include <string> #include <utility> @@ -28,39 +29,77 @@ #include "expr/expr_manager_scope.h" #include "expr/type.h" +namespace CVC4 { -using namespace CVC4::context; -using namespace std; +using ::CVC4::context::CDHashMap; +using ::CVC4::context::CDHashSet; +using ::CVC4::context::Context; +using ::std::copy; +using ::std::endl; +using ::std::ostream_iterator; +using ::std::pair; +using ::std::string; +using ::std::vector; -namespace CVC4 { +class SymbolTable::Implementation { + public: + Implementation() + : d_context(), + d_exprMap(new (true) CDHashMap<string, Expr>(&d_context)), + d_typeMap(new (true) TypeMap(&d_context)), + d_functions(new (true) CDHashSet<Expr, ExprHashFunction>(&d_context)) {} -SymbolTable::SymbolTable() : - d_context(new Context()), - d_exprMap(new(true) CDHashMap<std::string, Expr, StringHashFunction>(d_context)), - d_typeMap(new(true) CDHashMap<std::string, pair<vector<Type>, Type>, StringHashFunction>(d_context)), - d_functions(new(true) CDHashSet<Expr, ExprHashFunction>(d_context)) { -} + void bind(const string& name, Expr obj, bool levelZero) throw(); + void bindDefinedFunction(const string& name, Expr obj, + bool levelZero) throw(); + void bindType(const string& name, Type t, bool levelZero = false) throw(); + void bindType(const string& name, const vector<Type>& params, Type t, + bool levelZero = false) throw(); + bool isBound(const string& name) const throw(); + bool isBoundDefinedFunction(const string& name) const throw(); + bool isBoundDefinedFunction(Expr func) const throw(); + bool isBoundType(const string& name) const throw(); + Expr lookup(const string& name) const throw(); + Type lookupType(const string& name) const throw(); + Type lookupType(const string& name, const vector<Type>& params) const throw(); + size_t lookupArity(const string& name); + void popScope() throw(ScopeException); + void pushScope() throw(); + size_t getLevel() const throw(); + void reset(); -SymbolTable::~SymbolTable() { - d_exprMap->deleteSelf(); - d_typeMap->deleteSelf(); - d_functions->deleteSelf(); - delete d_context; -} + private: + /** The context manager for the scope maps. */ + Context d_context; + + /** A map for expressions. */ + CDHashMap<string, Expr>* d_exprMap; + + /** A map for types. */ + using TypeMap = CDHashMap<string, std::pair<vector<Type>, Type>>; + TypeMap* d_typeMap; -void SymbolTable::bind(const std::string& name, Expr obj, - bool levelZero) throw() { + /** A set of defined functions. */ + CDHashSet<Expr, ExprHashFunction>* d_functions; +}; /* SymbolTable::Implementation */ + +void SymbolTable::Implementation::bind(const string& name, Expr obj, + bool levelZero) throw() { PrettyCheckArgument(!obj.isNull(), obj, "cannot bind to a null Expr"); ExprManagerScope ems(obj); - if(levelZero) d_exprMap->insertAtContextLevelZero(name, obj); - else d_exprMap->insert(name, obj); + if (levelZero) { + d_exprMap->insertAtContextLevelZero(name, obj); + } else { + d_exprMap->insert(name, obj); + } } -void SymbolTable::bindDefinedFunction(const std::string& name, Expr obj, - bool levelZero) throw() { +void SymbolTable::Implementation::bindDefinedFunction(const string& name, + Expr obj, + bool levelZero) throw() { PrettyCheckArgument(!obj.isNull(), obj, "cannot bind to a null Expr"); ExprManagerScope ems(obj); - if(levelZero){ + if (levelZero) { d_exprMap->insertAtContextLevelZero(name, obj); d_functions->insertAtContextLevelZero(obj); } else { @@ -69,111 +108,111 @@ void SymbolTable::bindDefinedFunction(const std::string& name, Expr obj, } } -bool SymbolTable::isBound(const std::string& name) const throw() { +bool SymbolTable::Implementation::isBound(const string& name) const throw() { return d_exprMap->find(name) != d_exprMap->end(); } -bool SymbolTable::isBoundDefinedFunction(const std::string& name) const throw() { - CDHashMap<std::string, Expr, StringHashFunction>::iterator found = - d_exprMap->find(name); +bool SymbolTable::Implementation::isBoundDefinedFunction( + const string& name) const throw() { + CDHashMap<string, Expr>::iterator found = d_exprMap->find(name); return found != d_exprMap->end() && d_functions->contains((*found).second); } -bool SymbolTable::isBoundDefinedFunction(Expr func) const throw() { +bool SymbolTable::Implementation::isBoundDefinedFunction(Expr func) const + throw() { return d_functions->contains(func); } -Expr SymbolTable::lookup(const std::string& name) const throw() { +Expr SymbolTable::Implementation::lookup(const string& name) const throw() { return (*d_exprMap->find(name)).second; } -void SymbolTable::bindType(const std::string& name, Type t, - bool levelZero) throw() { - if(levelZero) { +void SymbolTable::Implementation::bindType(const string& name, Type t, + bool levelZero) throw() { + if (levelZero) { d_typeMap->insertAtContextLevelZero(name, make_pair(vector<Type>(), t)); } else { d_typeMap->insert(name, make_pair(vector<Type>(), t)); } } -void SymbolTable::bindType(const std::string& name, - const std::vector<Type>& params, - Type t, - bool levelZero) throw() { - if(Debug.isOn("sort")) { +void SymbolTable::Implementation::bindType(const string& name, + const vector<Type>& params, Type t, + bool levelZero) throw() { + if (Debug.isOn("sort")) { Debug("sort") << "bindType(" << name << ", ["; - if(params.size() > 0) { - copy( params.begin(), params.end() - 1, - ostream_iterator<Type>(Debug("sort"), ", ") ); + if (params.size() > 0) { + copy(params.begin(), params.end() - 1, + ostream_iterator<Type>(Debug("sort"), ", ")); Debug("sort") << params.back(); } Debug("sort") << "], " << t << ")" << endl; } - if(levelZero) { + if (levelZero) { d_typeMap->insertAtContextLevelZero(name, make_pair(params, t)); } else { d_typeMap->insert(name, make_pair(params, t)); } } -bool SymbolTable::isBoundType(const std::string& name) const throw() { +bool SymbolTable::Implementation::isBoundType(const string& name) const + throw() { return d_typeMap->find(name) != d_typeMap->end(); } -Type SymbolTable::lookupType(const std::string& name) const throw() { +Type SymbolTable::Implementation::lookupType(const string& name) const throw() { pair<vector<Type>, Type> p = (*d_typeMap->find(name)).second; PrettyCheckArgument(p.first.size() == 0, name, - "type constructor arity is wrong: " - "`%s' requires %u parameters but was provided 0", - name.c_str(), p.first.size()); + "type constructor arity is wrong: " + "`%s' requires %u parameters but was provided 0", + name.c_str(), p.first.size()); return p.second; } -Type SymbolTable::lookupType(const std::string& name, - const std::vector<Type>& params) const throw() { +Type SymbolTable::Implementation::lookupType(const string& name, + const vector<Type>& params) const + throw() { pair<vector<Type>, Type> p = (*d_typeMap->find(name)).second; PrettyCheckArgument(p.first.size() == params.size(), params, - "type constructor arity is wrong: " - "`%s' requires %u parameters but was provided %u", - name.c_str(), p.first.size(), params.size()); - if(p.first.size() == 0) { + "type constructor arity is wrong: " + "`%s' requires %u parameters but was provided %u", + name.c_str(), p.first.size(), params.size()); + if (p.first.size() == 0) { PrettyCheckArgument(p.second.isSort(), name.c_str()); return p.second; } - if(p.second.isSortConstructor()) { - if(Debug.isOn("sort")) { + if (p.second.isSortConstructor()) { + if (Debug.isOn("sort")) { Debug("sort") << "instantiating using a sort constructor" << endl; Debug("sort") << "have formals ["; - copy( p.first.begin(), p.first.end() - 1, - ostream_iterator<Type>(Debug("sort"), ", ") ); - Debug("sort") << p.first.back() << "]" << endl - << "parameters ["; - copy( params.begin(), params.end() - 1, - ostream_iterator<Type>(Debug("sort"), ", ") ); + copy(p.first.begin(), p.first.end() - 1, + ostream_iterator<Type>(Debug("sort"), ", ")); + Debug("sort") << p.first.back() << "]" << endl << "parameters ["; + copy(params.begin(), params.end() - 1, + ostream_iterator<Type>(Debug("sort"), ", ")); Debug("sort") << params.back() << "]" << endl << "type ctor " << name << endl << "type is " << p.second << endl; } - Type instantiation = - SortConstructorType(p.second).instantiate(params); + Type instantiation = SortConstructorType(p.second).instantiate(params); Debug("sort") << "instance is " << instantiation << endl; return instantiation; - } else if(p.second.isDatatype()) { - PrettyCheckArgument(DatatypeType(p.second).isParametric(), name, "expected parametric datatype"); + } else if (p.second.isDatatype()) { + PrettyCheckArgument(DatatypeType(p.second).isParametric(), name, + "expected parametric datatype"); return DatatypeType(p.second).instantiate(params); } else { - if(Debug.isOn("sort")) { + if (Debug.isOn("sort")) { Debug("sort") << "instantiating using a sort substitution" << endl; Debug("sort") << "have formals ["; - copy( p.first.begin(), p.first.end() - 1, - ostream_iterator<Type>(Debug("sort"), ", ") ); - Debug("sort") << p.first.back() << "]" << endl - << "parameters ["; - copy( params.begin(), params.end() - 1, - ostream_iterator<Type>(Debug("sort"), ", ") ); + copy(p.first.begin(), p.first.end() - 1, + ostream_iterator<Type>(Debug("sort"), ", ")); + Debug("sort") << p.first.back() << "]" << endl << "parameters ["; + copy(params.begin(), params.end() - 1, + ostream_iterator<Type>(Debug("sort"), ", ")); Debug("sort") << params.back() << "]" << endl << "type ctor " << name << endl << "type is " << p.second << endl; @@ -187,29 +226,88 @@ Type SymbolTable::lookupType(const std::string& name, } } -size_t SymbolTable::lookupArity(const std::string& name) { +size_t SymbolTable::Implementation::lookupArity(const string& name) { pair<vector<Type>, Type> p = (*d_typeMap->find(name)).second; return p.first.size(); } -void SymbolTable::popScope() throw(ScopeException) { - if( d_context->getLevel() == 0 ) { +void SymbolTable::Implementation::popScope() throw(ScopeException) { + if (d_context.getLevel() == 0) { throw ScopeException(); } - d_context->pop(); + d_context.pop(); } -void SymbolTable::pushScope() throw() { - d_context->push(); +void SymbolTable::Implementation::pushScope() throw() { d_context.push(); } + +size_t SymbolTable::Implementation::getLevel() const throw() { + return d_context.getLevel(); } -size_t SymbolTable::getLevel() const throw() { - return d_context->getLevel(); +void SymbolTable::Implementation::reset() { + this->SymbolTable::Implementation::~Implementation(); + new (this) SymbolTable::Implementation(); } -void SymbolTable::reset() { - this->SymbolTable::~SymbolTable(); - new(this) SymbolTable(); +SymbolTable::SymbolTable() + : d_implementation(new SymbolTable::Implementation()) {} + +SymbolTable::~SymbolTable() {} + +void SymbolTable::bind(const string& name, Expr obj, bool levelZero) throw() { + d_implementation->bind(name, obj, levelZero); +} + +void SymbolTable::bindDefinedFunction(const string& name, Expr obj, + bool levelZero) throw() { + d_implementation->bindDefinedFunction(name, obj, levelZero); +} + +void SymbolTable::bindType(const string& name, Type t, bool levelZero) throw() { + d_implementation->bindType(name, t, levelZero); +} + +void SymbolTable::bindType(const string& name, const vector<Type>& params, + Type t, bool levelZero) throw() { + d_implementation->bindType(name, params, t, levelZero); +} + +bool SymbolTable::isBound(const string& name) const throw() { + return d_implementation->isBound(name); +} + +bool SymbolTable::isBoundDefinedFunction(const string& name) const throw() { + return d_implementation->isBoundDefinedFunction(name); +} + +bool SymbolTable::isBoundDefinedFunction(Expr func) const throw() { + return d_implementation->isBoundDefinedFunction(func); +} +bool SymbolTable::isBoundType(const string& name) const throw() { + return d_implementation->isBoundType(name); +} +Expr SymbolTable::lookup(const string& name) const throw() { + return d_implementation->lookup(name); +} +Type SymbolTable::lookupType(const string& name) const throw() { + return d_implementation->lookupType(name); +} + +Type SymbolTable::lookupType(const string& name, + const vector<Type>& params) const throw() { + return d_implementation->lookupType(name, params); +} +size_t SymbolTable::lookupArity(const string& name) { + return d_implementation->lookupArity(name); +} +void SymbolTable::popScope() throw(ScopeException) { + d_implementation->popScope(); +} + +void SymbolTable::pushScope() throw() { d_implementation->pushScope(); } +size_t SymbolTable::getLevel() const throw() { + return d_implementation->getLevel(); } +void SymbolTable::reset() { d_implementation->reset(); } -}/* CVC4 namespace */ +} // namespace CVC4 diff --git a/src/expr/symbol_table.h b/src/expr/symbol_table.h index efd0f1a13..e64488563 100644 --- a/src/expr/symbol_table.h +++ b/src/expr/symbol_table.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Christopher L. Conway, Francois Bobot ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,26 +19,17 @@ #ifndef __CVC4__SYMBOL_TABLE_H #define __CVC4__SYMBOL_TABLE_H +#include <memory> +#include <string> #include <vector> -#include <utility> -#include <ext/hash_map> +#include "base/exception.h" #include "expr/expr.h" -#include "util/hash.h" - -#include "context/cdhashset_forward.h" -#include "context/cdhashmap_forward.h" +#include "expr/type.h" namespace CVC4 { -class Type; - -namespace context { - class Context; -}/* CVC4::context namespace */ - -class CVC4_PUBLIC ScopeException : public Exception { -};/* class ScopeException */ +class CVC4_PUBLIC ScopeException : public Exception {}; /** * A convenience class for handling scoped declarations. Implements the usual @@ -46,23 +37,9 @@ class CVC4_PUBLIC ScopeException : public Exception { * and types. */ class CVC4_PUBLIC SymbolTable { - /** The context manager for the scope maps. */ - context::Context* d_context; - - /** A map for expressions. */ - context::CDHashMap<std::string, Expr, StringHashFunction> *d_exprMap; - - /** A map for types. */ - context::CDHashMap<std::string, std::pair<std::vector<Type>, Type>, StringHashFunction> *d_typeMap; - - /** A set of defined functions. */ - context::CDHashSet<Expr, ExprHashFunction> *d_functions; - -public: + public: /** Create a symbol table. */ SymbolTable(); - - /** Destroy a symbol table. */ ~SymbolTable(); /** @@ -91,7 +68,8 @@ public: * @param obj the expression to bind to <code>name</code> * @param levelZero set if the binding must be done at level 0 */ - void bindDefinedFunction(const std::string& name, Expr obj, bool levelZero = false) throw(); + void bindDefinedFunction(const std::string& name, Expr obj, + bool levelZero = false) throw(); /** * Bind a type to a name in the current scope. If <code>name</code> @@ -104,7 +82,8 @@ public: * @param t the type to bind to <code>name</code> * @param levelZero set if the binding must be done at level 0 */ - void bindType(const std::string& name, Type t, bool levelZero = false) throw(); + void bindType(const std::string& name, Type t, + bool levelZero = false) throw(); /** * Bind a type to a name in the current scope. If <code>name</code> @@ -119,8 +98,7 @@ public: * @param levelZero true to bind it globally (default is to bind it * locally within the current scope) */ - void bindType(const std::string& name, - const std::vector<Type>& params, + void bindType(const std::string& name, const std::vector<Type>& params, Type t, bool levelZero = false) throw(); /** @@ -201,8 +179,15 @@ public: /** Reset everything. */ void reset(); -};/* class SymbolTable */ + private: + // Copying and assignment have not yet been implemented. + SymbolTable(const SymbolTable&); + SymbolTable& operator=(SymbolTable&); + + class Implementation; + std::unique_ptr<Implementation> d_implementation; +}; /* class SymbolTable */ -}/* CVC4 namespace */ +} // namespace CVC4 #endif /* __CVC4__SYMBOL_TABLE_H */ diff --git a/src/expr/type.cpp b/src/expr/type.cpp index 6ce7b0a18..8bcb0f8d5 100644 --- a/src/expr/type.cpp +++ b/src/expr/type.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -329,20 +329,6 @@ bool Type::isSortConstructor() const { return d_typeNode->isSortConstructor(); } -/** Is this a predicate subtype */ -/* - not in release 1.0 -bool Type::isPredicateSubtype() const { - NodeManagerScope nms(d_nodeManager); - return d_typeNode->isPredicateSubtype(); -} -*/ - -/** Is this an integer subrange */ -bool Type::isSubrange() const { - NodeManagerScope nms(d_nodeManager); - return d_typeNode->isSubrange(); -} - size_t FunctionType::getArity() const { return d_typeNode->getNumChildren() - 1; } @@ -505,20 +491,6 @@ SortConstructorType::SortConstructorType(const Type& t) PrettyCheckArgument(isNull() || isSortConstructor(), this); } -/* - not in release 1.0 -PredicateSubtype::PredicateSubtype(const Type& t) - throw(IllegalArgumentException) : - Type(t) { - PrettyCheckArgument(isNull() || isPredicateSubtype(), this); -} -*/ - -SubrangeType::SubrangeType(const Type& t) - throw(IllegalArgumentException) : - Type(t) { - PrettyCheckArgument(isNull() || isSubrange(), this); -} - unsigned BitVectorType::getSize() const { return d_typeNode->getBitVectorSize(); } @@ -666,11 +638,6 @@ Type PredicateSubtype::getParentType() const { } */ -SubrangeBounds SubrangeType::getSubrangeBounds() const { - NodeManagerScope nms(d_nodeManager); - return d_typeNode->getSubrangeBounds(); -} - size_t TypeHashFunction::operator()(const Type& t) const { return TypeNodeHashFunction()(NodeManager::fromType(t)); } diff --git a/src/expr/type.h b/src/expr/type.h index 43cb3ffbf..25f0c5436 100644 --- a/src/expr/type.h +++ b/src/expr/type.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Martin Brain ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -372,7 +372,7 @@ public: * Is this an integer subrange type? * @return true if this is an integer subrange type */ - bool isSubrange() const; + //bool isSubrange() const; /** * Outputs a string representation of this type to the stream. @@ -584,7 +584,6 @@ public: Type getParentType() const; };/* class PredicateSubtype */ -#endif /* 0 */ /** * Class encapsulating an integer subrange type. @@ -600,6 +599,7 @@ public: SubrangeBounds getSubrangeBounds() const; };/* class SubrangeType */ +#endif /* 0 */ /** * Class encapsulating the bit-vector type. diff --git a/src/expr/type_checker.h b/src/expr/type_checker.h index 3df73b268..df8b6a8ca 100644 --- a/src/expr/type_checker.h +++ b/src/expr/type_checker.h @@ -2,9 +2,9 @@ /*! \file type_checker.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/type_checker_template.cpp b/src/expr/type_checker_template.cpp index 757a32529..476510a2f 100644 --- a/src/expr/type_checker_template.cpp +++ b/src/expr/type_checker_template.cpp @@ -2,9 +2,9 @@ /*! \file type_checker_template.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/type_node.cpp b/src/expr/type_node.cpp index 720814aa8..a4ab2f3b7 100644 --- a/src/expr/type_node.cpp +++ b/src/expr/type_node.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Kshitij Bansal ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -31,9 +31,9 @@ TypeNode TypeNode::s_null( &expr::NodeValue::null() ); TypeNode TypeNode::substitute(const TypeNode& type, const TypeNode& replacement, - std::hash_map<TypeNode, TypeNode, HashFunction>& cache) const { + std::unordered_map<TypeNode, TypeNode, HashFunction>& cache) const { // in cache? - std::hash_map<TypeNode, TypeNode, HashFunction>::const_iterator i = cache.find(*this); + std::unordered_map<TypeNode, TypeNode, HashFunction>::const_iterator i = cache.find(*this); if(i != cache.end()) { return (*i).second; } @@ -106,15 +106,6 @@ bool TypeNode::isSubtypeOf(TypeNode t) const { return false; } } - if(isSubrange()) { - if(t.isSubrange()) { - return t.getSubrangeBounds() <= getSubrangeBounds(); - } else { - return t.getKind() == kind::TYPE_CONSTANT && - ( t.getConst<TypeConstant>() == INTEGER_TYPE || - t.getConst<TypeConstant>() == REAL_TYPE ); - } - } if(isTuple() && t.isTuple()) { const Datatype& dt1 = getDatatype(); const Datatype& dt2 = t.getDatatype(); @@ -151,9 +142,6 @@ bool TypeNode::isSubtypeOf(TypeNode t) const { } return true; } - if(isPredicateSubtype()) { - return getSubtypeParentType().isSubtypeOf(t); - } if(isSet() && t.isSet()) { return getSetElementType().isSubtypeOf(t.getSetElementType()); } @@ -205,28 +193,13 @@ bool TypeNode::isComparableTo(TypeNode t) const { if(isArray() && t.isArray()) { return getArrayIndexType().isComparableTo(t.getArrayIndexType()) && getArrayConstituentType().isComparableTo(t.getArrayConstituentType()); } - //if(isPredicateSubtype()) { - // return t.isComparableTo(getSubtypeParentType()); - //} return false; } -Node TypeNode::getSubtypePredicate() const { - Assert(isPredicateSubtype()); - return Node::fromExpr(getConst<Predicate>().getExpression()); -} - -TypeNode TypeNode::getSubtypeParentType() const { - Assert(isPredicateSubtype()); - return getSubtypePredicate().getType().getArgTypes()[0]; -} - TypeNode TypeNode::getBaseType() const { TypeNode realt = NodeManager::currentNM()->realType(); if (isSubtypeOf(realt)) { return realt; - } else if (isPredicateSubtype()) { - return getSubtypeParentType().getBaseType(); } else if (isParametricDatatype()) { vector<Type> v; for(size_t i = 1; i < getNumChildren(); ++i) { @@ -264,14 +237,12 @@ std::vector<TypeNode> TypeNode::getParamTypes() const { /** Is this a tuple type? */ bool TypeNode::isTuple() const { - return ( getKind() == kind::DATATYPE_TYPE && getDatatype().isTuple() ) || - ( isPredicateSubtype() && getSubtypeParentType().isTuple() ); + return ( getKind() == kind::DATATYPE_TYPE && getDatatype().isTuple() ); } /** Is this a record type? */ bool TypeNode::isRecord() const { - return ( getKind() == kind::DATATYPE_TYPE && getDatatype().isRecord() ) || - ( isPredicateSubtype() && getSubtypeParentType().isRecord() ); + return ( getKind() == kind::DATATYPE_TYPE && getDatatype().isRecord() ); } size_t TypeNode::getTupleLength() const { @@ -375,11 +346,7 @@ TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) { return TypeNode(); // null type } default: - //if(t1.isPredicateSubtype() && t1.getSubtypeParentType().isSubtypeOf(t0)) { - // return t0; // t0 is a constant type - //} else { - return TypeNode(); // null type - //} + return TypeNode(); // null type } } else if(t1.getKind() == kind::TYPE_CONSTANT) { return commonTypeNode(t1, t0, isLeast); // decrease the number of special cases @@ -394,11 +361,7 @@ TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) { case kind::CONSTRUCTOR_TYPE: case kind::SELECTOR_TYPE: case kind::TESTER_TYPE: - //if( t1.isPredicateSubtype() && t1.getSubtypeParentType().isSubtypeOf(t0)) { - // return t0; - //} else { - return TypeNode(); - //} + return TypeNode(); case kind::FUNCTION_TYPE: return TypeNode(); // Not sure if this is right case kind::SET_TYPE: { @@ -423,47 +386,6 @@ TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) { case kind::SEXPR_TYPE: Unimplemented("haven't implemented leastCommonType for symbolic expressions yet"); return TypeNode(); - case kind::SUBTYPE_TYPE: - //if(t1.isPredicateSubtype()){ - // // This is the case where both t0 and t1 are predicate subtypes. - // return leastCommonPredicateSubtype(t0, t1); - //}else{ // t0 is a predicate subtype and t1 is not - // return commonTypeNode(t1, t0, isLeast); //decrease the number of special cases - //} - return TypeNode(); - case kind::SUBRANGE_TYPE: - /* - if(t1.isSubrange()) { - const SubrangeBounds& t0SR = t0.getSubrangeBounds(); - const SubrangeBounds& t1SR = t1.getSubrangeBounds(); - if(SubrangeBounds::joinIsBounded(t0SR, t1SR)) { - SubrangeBounds j = SubrangeBounds::join(t0SR, t1SR); - return NodeManager::currentNM()->mkSubrangeType(j); - } else { - return NodeManager::currentNM()->integerType(); - } - } else if(t1.isPredicateSubtype()) { - // t0 is a subrange - // t1 is not a subrange - // t1 is a predicate subtype - if(t1.isInteger()) { - return NodeManager::currentNM()->integerType(); - } else if(t1.isReal()) { - return NodeManager::currentNM()->realType(); - } else { - return TypeNode(); - } - } else { - // t0 is a subrange - // t1 is not a subrange - // t1 is not a type constant && is not a predicate subtype - // t1 cannot be real subtype or integer. - Assert(t1.isReal()); - Assert(t1.isInteger()); - return TypeNode(); - } -*/ - return TypeNode(); case kind::DATATYPE_TYPE: if( t0.isTuple() && t1.isTuple() ){ const Datatype& dt1 = t0.getDatatype(); @@ -490,9 +412,6 @@ TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) { if(!t1.isParametricDatatype()) { return TypeNode(); } - while(t1.getKind() != kind::PARAMETRIC_DATATYPE) { - t1 = t1.getSubtypeParentType(); - } if(t0[0] != t1[0] || t0.getNumChildren() != t1.getNumChildren()) { return TypeNode(); } @@ -508,38 +427,6 @@ TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) { } } -TypeNode TypeNode::leastCommonPredicateSubtype(TypeNode t0, TypeNode t1){ - Assert(t0.isPredicateSubtype()); - Assert(t1.isPredicateSubtype()); - - std::vector<TypeNode> t0stack; - t0stack.push_back(t0); - while(t0stack.back().isPredicateSubtype()){ - t0stack.push_back(t0stack.back().getSubtypeParentType()); - } - std::vector<TypeNode> t1stack; - t1stack.push_back(t1); - while(t1stack.back().isPredicateSubtype()){ - t1stack.push_back(t1stack.back().getSubtypeParentType()); - } - - Assert(!t0stack.empty()); - Assert(!t1stack.empty()); - - if(t0stack.back() == t1stack.back()){ - TypeNode mostGeneral = t1stack.back(); - t0stack.pop_back(); t1stack.pop_back(); - while(!t0stack.empty() && t1stack.empty() && t0stack.back() == t1stack.back()){ - mostGeneral = t0stack.back(); - t0stack.pop_back(); t1stack.pop_back(); - } - return mostGeneral; - }else{ - return leastCommonTypeNode(t0stack.back(), t1stack.back()); - } -} - - Node TypeNode::getEnsureTypeCondition( Node n, TypeNode tn ) { TypeNode ntn = n.getType(); Assert( ntn.isComparableTo( tn ) ); @@ -581,8 +468,7 @@ Node TypeNode::getEnsureTypeCondition( Node n, TypeNode tn ) { /** Is this a sort kind */ bool TypeNode::isSort() const { - return ( getKind() == kind::SORT_TYPE && !hasAttribute(expr::SortArityAttr()) ) || - ( isPredicateSubtype() && getSubtypeParentType().isSort() ); + return ( getKind() == kind::SORT_TYPE && !hasAttribute(expr::SortArityAttr()) ); } /** Is this a sort constructor kind */ diff --git a/src/expr/type_node.h b/src/expr/type_node.h index 114b8a8ed..65b422a53 100644 --- a/src/expr/type_node.h +++ b/src/expr/type_node.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Martin Brain ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -22,11 +22,13 @@ #ifndef __CVC4__TYPE_NODE_H #define __CVC4__TYPE_NODE_H -#include <vector> -#include <string> -#include <iostream> #include <stdint.h> +#include <iostream> +#include <string> +#include <unordered_map> +#include <vector> + #include "base/cvc4_assert.h" #include "expr/kind.h" #include "expr/metakind.h" @@ -93,7 +95,7 @@ private: * member function with a similar signature. */ TypeNode substitute(const TypeNode& type, const TypeNode& replacement, - std::hash_map<TypeNode, TypeNode, HashFunction>& cache) const; + std::unordered_map<TypeNode, TypeNode, HashFunction>& cache) const; /** * Cache-aware, recursive version of substitute() used by the public @@ -102,7 +104,7 @@ private: template <class Iterator1, class Iterator2> TypeNode substitute(Iterator1 typesBegin, Iterator1 typesEnd, Iterator2 replacementsBegin, Iterator2 replacementsEnd, - std::hash_map<TypeNode, TypeNode, HashFunction>& cache) const; + std::unordered_map<TypeNode, TypeNode, HashFunction>& cache) const; public: @@ -620,27 +622,9 @@ public: /** Is this a sort constructor kind */ bool isSortConstructor() const; - /** Is this a subtype predicate */ - bool isPredicateSubtype() const; - - /** Get the predicate defining this subtype */ - Node getSubtypePredicate() const; - - /** - * Get the parent type of this subtype; note that it could be - * another subtype. - */ - TypeNode getSubtypeParentType() const; - /** Get the most general base type of the type */ TypeNode getBaseType() const; - /** Is this a subrange */ - bool isSubrange() const; - - /** Get the bounds defining this subrange */ - const SubrangeBounds& getSubrangeBounds() const; - /** * Returns the leastUpperBound in the extended type lattice of the two types. * If this is \top, i.e. there is no inhabited type that contains both, @@ -657,13 +641,7 @@ public: static Node getEnsureTypeCondition( Node n, TypeNode tn ); private: static TypeNode commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast); - - /** - * Returns the leastUpperBound in the extended type lattice of two - * predicate subtypes. - */ - static TypeNode leastCommonPredicateSubtype(TypeNode t0, TypeNode t1); - + /** * Indents the given stream a given amount of spaces. * @@ -694,8 +672,6 @@ typedef TypeNode::HashFunction TypeNodeHashFunction; }/* CVC4 namespace */ -#include <ext/hash_map> - #include "expr/node_manager.h" namespace CVC4 { @@ -711,7 +687,7 @@ inline TypeNode TypeNode::fromType(const Type& t) { inline TypeNode TypeNode::substitute(const TypeNode& type, const TypeNode& replacement) const { - std::hash_map<TypeNode, TypeNode, HashFunction> cache; + std::unordered_map<TypeNode, TypeNode, HashFunction> cache; return substitute(type, replacement, cache); } @@ -721,7 +697,7 @@ TypeNode::substitute(Iterator1 typesBegin, Iterator1 typesEnd, Iterator2 replacementsBegin, Iterator2 replacementsEnd) const { - std::hash_map<TypeNode, TypeNode, HashFunction> cache; + std::unordered_map<TypeNode, TypeNode, HashFunction> cache; return substitute(typesBegin, typesEnd, replacementsBegin, replacementsEnd, cache); } @@ -731,9 +707,9 @@ TypeNode TypeNode::substitute(Iterator1 typesBegin, Iterator1 typesEnd, Iterator2 replacementsBegin, Iterator2 replacementsEnd, - std::hash_map<TypeNode, TypeNode, HashFunction>& cache) const { + std::unordered_map<TypeNode, TypeNode, HashFunction>& cache) const { // in cache? - std::hash_map<TypeNode, TypeNode, HashFunction>::const_iterator i = cache.find(*this); + std::unordered_map<TypeNode, TypeNode, HashFunction>::const_iterator i = cache.find(*this); if(i != cache.end()) { return (*i).second; } @@ -852,22 +828,18 @@ inline void TypeNode::printAst(std::ostream& out, int indent) const { inline bool TypeNode::isBoolean() const { return - ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == BOOLEAN_TYPE ) || - ( isPredicateSubtype() && getSubtypeParentType().isBoolean() ); + ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == BOOLEAN_TYPE ); } inline bool TypeNode::isInteger() const { return - ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == INTEGER_TYPE ) || - isSubrange() || - ( isPredicateSubtype() && getSubtypeParentType().isInteger() ); + ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == INTEGER_TYPE ); } inline bool TypeNode::isReal() const { return ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == REAL_TYPE ) || - isInteger() || - ( isPredicateSubtype() && getSubtypeParentType().isReal() ); + isInteger(); } inline bool TypeNode::isString() const { @@ -944,43 +916,27 @@ inline TypeNode TypeNode::getRangeType() const { /** Is this a symbolic expression type? */ inline bool TypeNode::isSExpr() const { - return getKind() == kind::SEXPR_TYPE || - ( isPredicateSubtype() && getSubtypeParentType().isSExpr() ); -} - -/** Is this a predicate subtype */ -inline bool TypeNode::isPredicateSubtype() const { - return getKind() == kind::SUBTYPE_TYPE; -} - -/** Is this a subrange type */ -inline bool TypeNode::isSubrange() const { - return getKind() == kind::SUBRANGE_TYPE || - ( isPredicateSubtype() && getSubtypeParentType().isSubrange() ); + return getKind() == kind::SEXPR_TYPE; } /** Is this a floating-point type */ inline bool TypeNode::isFloatingPoint() const { - return getKind() == kind::FLOATINGPOINT_TYPE || - ( isPredicateSubtype() && getSubtypeParentType().isFloatingPoint() ); + return getKind() == kind::FLOATINGPOINT_TYPE; } /** Is this a bit-vector type */ inline bool TypeNode::isBitVector() const { - return getKind() == kind::BITVECTOR_TYPE || - ( isPredicateSubtype() && getSubtypeParentType().isBitVector() ); + return getKind() == kind::BITVECTOR_TYPE; } /** Is this a datatype type */ inline bool TypeNode::isDatatype() const { - return getKind() == kind::DATATYPE_TYPE || getKind() == kind::PARAMETRIC_DATATYPE || - ( isPredicateSubtype() && getSubtypeParentType().isDatatype() ); + return getKind() == kind::DATATYPE_TYPE || getKind() == kind::PARAMETRIC_DATATYPE; } /** Is this a parametric datatype type */ inline bool TypeNode::isParametricDatatype() const { - return getKind() == kind::PARAMETRIC_DATATYPE || - ( isPredicateSubtype() && getSubtypeParentType().isParametricDatatype() ); + return getKind() == kind::PARAMETRIC_DATATYPE; } /** Is this a codatatype type */ @@ -1013,15 +969,13 @@ inline bool TypeNode::isFloatingPoint(unsigned exp, unsigned sig) const { return ( getKind() == kind::FLOATINGPOINT_TYPE && getConst<FloatingPointSize>().exponent() == exp && - getConst<FloatingPointSize>().significand() == sig ) || - ( isPredicateSubtype() && getSubtypeParentType().isFloatingPoint(exp,sig) ); + getConst<FloatingPointSize>().significand() == sig ); } /** Is this a bit-vector type of size <code>size</code> */ inline bool TypeNode::isBitVector(unsigned size) const { return - ( getKind() == kind::BITVECTOR_TYPE && getConst<BitVectorSize>() == size ) || - ( isPredicateSubtype() && getSubtypeParentType().isBitVector(size) ); + ( getKind() == kind::BITVECTOR_TYPE && getConst<BitVectorSize>() == size ); } /** Get the datatype specification from a datatype type */ @@ -1054,16 +1008,6 @@ inline unsigned TypeNode::getBitVectorSize() const { return getConst<BitVectorSize>(); } -inline const SubrangeBounds& TypeNode::getSubrangeBounds() const { - Assert(isSubrange()); - if(getKind() == kind::SUBRANGE_TYPE){ - return getConst<SubrangeBounds>(); - }else{ - Assert(isPredicateSubtype()); - return getSubtypeParentType().getSubrangeBounds(); - } -} - #ifdef CVC4_DEBUG /** * Pretty printer for use within gdb. This is not intended to be used diff --git a/src/expr/type_properties_template.h b/src/expr/type_properties_template.h index 4874a84b8..ce2d9d403 100644 --- a/src/expr/type_properties_template.h +++ b/src/expr/type_properties_template.h @@ -2,9 +2,9 @@ /*! \file type_properties_template.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/uninterpreted_constant.cpp b/src/expr/uninterpreted_constant.cpp index c88c3b591..c823529be 100644 --- a/src/expr/uninterpreted_constant.cpp +++ b/src/expr/uninterpreted_constant.cpp @@ -2,9 +2,9 @@ /*! \file uninterpreted_constant.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/uninterpreted_constant.h b/src/expr/uninterpreted_constant.h index 7d7a3759b..06747e1af 100644 --- a/src/expr/uninterpreted_constant.h +++ b/src/expr/uninterpreted_constant.h @@ -2,9 +2,9 @@ /*! \file uninterpreted_constant.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/expr/variable_type_map.h b/src/expr/variable_type_map.h index 00d2c3eac..94d9c2f67 100644 --- a/src/expr/variable_type_map.h +++ b/src/expr/variable_type_map.h @@ -2,9 +2,9 @@ /*! \file variable_type_map.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,8 +20,9 @@ #ifndef __CVC4__VARIABLE_TYPE_MAP_H #define __CVC4__VARIABLE_TYPE_MAP_H +#include <unordered_map> + #include "expr/expr.h" -#include "util/hash.h" namespace CVC4 { @@ -35,13 +36,13 @@ class CVC4_PUBLIC VariableTypeMap { * A map Expr -> Expr, intended to be used for a mapping of variables * between two ExprManagers. */ - std::hash_map<Expr, Expr, ExprHashFunction> d_variables; + std::unordered_map<Expr, Expr, ExprHashFunction> d_variables; /** * A map Type -> Type, intended to be used for a mapping of types * between two ExprManagers. */ - std::hash_map<Type, Type, TypeHashFunction> d_types; + std::unordered_map<Type, Type, TypeHashFunction> d_types; public: Expr& operator[](Expr e) { return d_variables[e]; } @@ -49,7 +50,7 @@ public: };/* class VariableTypeMap */ -typedef __gnu_cxx::hash_map<uint64_t, uint64_t> VarMap; +typedef std::unordered_map<uint64_t, uint64_t> VarMap; struct CVC4_PUBLIC ExprManagerMapCollection { VariableTypeMap d_typeMap; diff --git a/src/include/cvc4.h b/src/include/cvc4.h index 6e6204c58..d505a1930 100644 --- a/src/include/cvc4.h +++ b/src/include/cvc4.h @@ -2,9 +2,9 @@ /*! \file cvc4.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/include/cvc4_private.h b/src/include/cvc4_private.h index 56be6ff71..2d73c1256 100644 --- a/src/include/cvc4_private.h +++ b/src/include/cvc4_private.h @@ -2,9 +2,9 @@ /*! \file cvc4_private.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/include/cvc4_private_library.h b/src/include/cvc4_private_library.h index c536d0586..3542114b1 100644 --- a/src/include/cvc4_private_library.h +++ b/src/include/cvc4_private_library.h @@ -2,9 +2,9 @@ /*! \file cvc4_private_library.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/include/cvc4_public.h b/src/include/cvc4_public.h index 1308b3d96..7b88a2624 100644 --- a/src/include/cvc4_public.h +++ b/src/include/cvc4_public.h @@ -2,9 +2,9 @@ /*! \file cvc4_public.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/include/cvc4parser_private.h b/src/include/cvc4parser_private.h index 366877c96..c441f77b7 100644 --- a/src/include/cvc4parser_private.h +++ b/src/include/cvc4parser_private.h @@ -2,9 +2,9 @@ /*! \file cvc4parser_private.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/include/cvc4parser_public.h b/src/include/cvc4parser_public.h index ccbd09066..b7548a5ab 100644 --- a/src/include/cvc4parser_public.h +++ b/src/include/cvc4parser_public.h @@ -2,9 +2,9 @@ /*! \file cvc4parser_public.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/lib/clock_gettime.c b/src/lib/clock_gettime.c index 9bd4eafe8..ec549117e 100644 --- a/src/lib/clock_gettime.c +++ b/src/lib/clock_gettime.c @@ -2,9 +2,9 @@ /*! \file clock_gettime.c ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/lib/clock_gettime.h b/src/lib/clock_gettime.h index 74c9f5088..249ea27d5 100644 --- a/src/lib/clock_gettime.h +++ b/src/lib/clock_gettime.h @@ -2,9 +2,9 @@ /*! \file clock_gettime.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/lib/ffs.c b/src/lib/ffs.c index d42f9da94..54ee7cdfe 100644 --- a/src/lib/ffs.c +++ b/src/lib/ffs.c @@ -2,9 +2,9 @@ /*! \file ffs.c ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/lib/ffs.h b/src/lib/ffs.h index 878c8f7cf..adb572501 100644 --- a/src/lib/ffs.h +++ b/src/lib/ffs.h @@ -2,9 +2,9 @@ /*! \file ffs.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/lib/replacements.h b/src/lib/replacements.h index d2f7d9f4f..ecd4391e7 100644 --- a/src/lib/replacements.h +++ b/src/lib/replacements.h @@ -2,9 +2,9 @@ /*! \file replacements.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/lib/strtok_r.c b/src/lib/strtok_r.c index 9173596a3..02526cbcc 100644 --- a/src/lib/strtok_r.c +++ b/src/lib/strtok_r.c @@ -2,9 +2,9 @@ /*! \file strtok_r.c ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/lib/strtok_r.h b/src/lib/strtok_r.h index e3803b0c1..50d880842 100644 --- a/src/lib/strtok_r.h +++ b/src/lib/strtok_r.h @@ -2,9 +2,9 @@ /*! \file strtok_r.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/command_executor.cpp b/src/main/command_executor.cpp index ebb57da74..796557b1d 100644 --- a/src/main/command_executor.cpp +++ b/src/main/command_executor.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Kshitij Bansal, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/command_executor.h b/src/main/command_executor.h index 7a33e1db7..0ace140c1 100644 --- a/src/main/command_executor.h +++ b/src/main/command_executor.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Kshitij Bansal, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/command_executor_portfolio.cpp b/src/main/command_executor_portfolio.cpp index bd8b6a9ed..948e05ad3 100644 --- a/src/main/command_executor_portfolio.cpp +++ b/src/main/command_executor_portfolio.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Kshitij Bansal, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -197,9 +197,13 @@ bool CommandExecutorPortfolio::doCommandSingleton(Command* cmd) // mode = 2 : run _only_ the lastWinner thread, not saving the // command + if( dynamic_cast<CheckSynthCommand*>(cmd) != NULL ){ + // sygus not supported in portfolio : FIXME: can support once datatypes exportTo is supported + return CommandExecutor::doCommandSingleton(cmd); + } + if(dynamic_cast<CheckSatCommand*>(cmd) != NULL || - dynamic_cast<QueryCommand*>(cmd) != NULL || - dynamic_cast<CheckSynthCommand*>(cmd) != NULL) { + dynamic_cast<QueryCommand*>(cmd) != NULL ) { mode = 1; } else if(dynamic_cast<GetValueCommand*>(cmd) != NULL || dynamic_cast<GetAssignmentCommand*>(cmd) != NULL || diff --git a/src/main/command_executor_portfolio.h b/src/main/command_executor_portfolio.h index be980a01b..d045ab77e 100644 --- a/src/main/command_executor_portfolio.h +++ b/src/main/command_executor_portfolio.h @@ -2,9 +2,9 @@ /*! \file command_executor_portfolio.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Morgan Deters, Tim King + ** Kshitij Bansal, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/driver_unified.cpp b/src/main/driver_unified.cpp index 5113bab10..697ce6642 100644 --- a/src/main/driver_unified.cpp +++ b/src/main/driver_unified.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,6 +20,7 @@ #include <cstring> #include <fstream> #include <iostream> +#include <memory> #include <new> // This must come before PORTFOLIO_BUILD. @@ -27,7 +28,6 @@ #include "base/configuration.h" #include "base/output.h" -#include "base/ptr_closer.h" #include "expr/expr_iomanip.h" #include "expr/expr_manager.h" #include "main/command_executor.h" @@ -249,7 +249,7 @@ int runCvc4(int argc, char* argv[], Options& opts) { } # endif - PtrCloser<Parser> replayParser; + std::unique_ptr<Parser> replayParser; if( opts.getReplayInputFilename() != "" ) { std::string replayFilename = opts.getReplayInputFilename(); ParserBuilder replayParserBuilder(exprMgr, replayFilename, opts); @@ -357,7 +357,7 @@ int runCvc4(int argc, char* argv[], Options& opts) { vector< vector<Command*> > allCommands; allCommands.push_back(vector<Command*>()); - PtrCloser<Parser> parser(parserBuilder.build()); + std::unique_ptr<Parser> parser(parserBuilder.build()); if(replayParser) { // have the replay parser use the file's declarations replayParser->useDeclarationsFrom(parser.get()); @@ -512,7 +512,7 @@ int runCvc4(int argc, char* argv[], Options& opts) { #endif /* CVC4_COMPETITION_MODE && !CVC4_SMTCOMP_APPLICATION_TRACK */ } - PtrCloser<Parser> parser(parserBuilder.build()); + std::unique_ptr<Parser> parser(parserBuilder.build()); if(replayParser) { // have the replay parser use the file's declarations replayParser->useDeclarationsFrom(parser.get()); diff --git a/src/main/interactive_shell.cpp b/src/main/interactive_shell.cpp index b809e2019..0fa026f76 100644 --- a/src/main/interactive_shell.cpp +++ b/src/main/interactive_shell.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Christopher L. Conway, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/interactive_shell.h b/src/main/interactive_shell.h index 18e42f1e5..a3834a1e3 100644 --- a/src/main/interactive_shell.h +++ b/src/main/interactive_shell.h @@ -2,9 +2,9 @@ /*! \file interactive_shell.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Christopher L. Conway, Tim King + ** Morgan Deters, Christopher L. Conway, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/main.cpp b/src/main/main.cpp index 9f77045c4..758d10af8 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/main.h b/src/main/main.h index e4723a743..dcb5c2a0a 100644 --- a/src/main/main.h +++ b/src/main/main.h @@ -2,9 +2,9 @@ /*! \file main.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/portfolio.cpp b/src/main/portfolio.cpp index 1e1b41bea..ddff4665e 100644 --- a/src/main/portfolio.cpp +++ b/src/main/portfolio.cpp @@ -2,9 +2,9 @@ /*! \file portfolio.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Kshitij Bansal, Tim King + ** Morgan Deters, Kshitij Bansal, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/portfolio.h b/src/main/portfolio.h index b96efda51..a370c01dc 100644 --- a/src/main/portfolio.h +++ b/src/main/portfolio.h @@ -2,9 +2,9 @@ /*! \file portfolio.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Kshitij Bansal + ** Morgan Deters, Paul Meng, Kshitij Bansal ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/portfolio_util.cpp b/src/main/portfolio_util.cpp index 8e38eb528..372fe780a 100644 --- a/src/main/portfolio_util.cpp +++ b/src/main/portfolio_util.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Kshitij Bansal ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/portfolio_util.h b/src/main/portfolio_util.h index 32cc04540..5ed9a36fd 100644 --- a/src/main/portfolio_util.h +++ b/src/main/portfolio_util.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Kshitij Bansal, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/main/util.cpp b/src/main/util.cpp index 2fd796d92..e08628848 100644 --- a/src/main/util.cpp +++ b/src/main/util.cpp @@ -2,7 +2,7 @@ /*! \file util.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Kshitij Bansal + ** Morgan Deters, Andres Noetzli, Clément Pit-Claudel ** 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. diff --git a/src/options/Makefile.am b/src/options/Makefile.am index 5a9fa54e6..ff889bcb2 100644 --- a/src/options/Makefile.am +++ b/src/options/Makefile.am @@ -229,6 +229,7 @@ liboptions_la_SOURCES = \ base_handlers.h \ bv_bitblast_mode.cpp \ bv_bitblast_mode.h \ + datatypes_modes.h \ decision_mode.cpp \ decision_mode.h \ decision_weight.h \ diff --git a/src/options/argument_extender.h b/src/options/argument_extender.h index 6be41fe8e..eea8eca56 100644 --- a/src/options/argument_extender.h +++ b/src/options/argument_extender.h @@ -2,9 +2,9 @@ /*! \file argument_extender.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/argument_extender_implementation.cpp b/src/options/argument_extender_implementation.cpp index 0c23434c4..9c38b348b 100644 --- a/src/options/argument_extender_implementation.cpp +++ b/src/options/argument_extender_implementation.cpp @@ -2,9 +2,9 @@ /*! \file argument_extender_implementation.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/argument_extender_implementation.h b/src/options/argument_extender_implementation.h index e948132d7..859a88b3e 100644 --- a/src/options/argument_extender_implementation.h +++ b/src/options/argument_extender_implementation.h @@ -2,9 +2,9 @@ /*! \file argument_extender_implementation.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/arith_heuristic_pivot_rule.cpp b/src/options/arith_heuristic_pivot_rule.cpp index 15c340aa8..b07b400f1 100644 --- a/src/options/arith_heuristic_pivot_rule.cpp +++ b/src/options/arith_heuristic_pivot_rule.cpp @@ -2,9 +2,9 @@ /*! \file arith_heuristic_pivot_rule.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/arith_heuristic_pivot_rule.h b/src/options/arith_heuristic_pivot_rule.h index 9048cb92e..ebfbf5ee9 100644 --- a/src/options/arith_heuristic_pivot_rule.h +++ b/src/options/arith_heuristic_pivot_rule.h @@ -2,9 +2,9 @@ /*! \file arith_heuristic_pivot_rule.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/arith_options b/src/options/arith_options index 32310a495..bddde7a16 100644 --- a/src/options/arith_options +++ b/src/options/arith_options @@ -171,6 +171,9 @@ option nlExt --nl-ext bool :default true option nlExtResBound --nl-ext-rbound bool :default false use resolution-style inference for inferring new bounds +option nlExtFactor --nl-ext-factor bool :default true + use factoring inference in non-linear solver + option nlExtTangentPlanes --nl-ext-tplanes bool :default false use non-terminating tangent plane strategy for non-linear diff --git a/src/options/arith_propagation_mode.cpp b/src/options/arith_propagation_mode.cpp index 5baf0b832..67e6f51dc 100644 --- a/src/options/arith_propagation_mode.cpp +++ b/src/options/arith_propagation_mode.cpp @@ -2,9 +2,9 @@ /*! \file arith_propagation_mode.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/arith_propagation_mode.h b/src/options/arith_propagation_mode.h index dc4b80372..fad89cce5 100644 --- a/src/options/arith_propagation_mode.h +++ b/src/options/arith_propagation_mode.h @@ -2,9 +2,9 @@ /*! \file arith_propagation_mode.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/arith_unate_lemma_mode.cpp b/src/options/arith_unate_lemma_mode.cpp index 9b683f4c1..ca076a791 100644 --- a/src/options/arith_unate_lemma_mode.cpp +++ b/src/options/arith_unate_lemma_mode.cpp @@ -2,9 +2,9 @@ /*! \file arith_unate_lemma_mode.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/arith_unate_lemma_mode.h b/src/options/arith_unate_lemma_mode.h index 39664d3aa..bab7cfa72 100644 --- a/src/options/arith_unate_lemma_mode.h +++ b/src/options/arith_unate_lemma_mode.h @@ -2,9 +2,9 @@ /*! \file arith_unate_lemma_mode.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/base_handlers.h b/src/options/base_handlers.h index 0345f9e10..b036c7e93 100644 --- a/src/options/base_handlers.h +++ b/src/options/base_handlers.h @@ -2,9 +2,9 @@ /*! \file base_handlers.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/base_options_template.cpp b/src/options/base_options_template.cpp index bdcef6029..1093b83e6 100644 --- a/src/options/base_options_template.cpp +++ b/src/options/base_options_template.cpp @@ -2,9 +2,9 @@ /*! \file base_options_template.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/base_options_template.h b/src/options/base_options_template.h index 486b793d0..8fe3a390f 100644 --- a/src/options/base_options_template.h +++ b/src/options/base_options_template.h @@ -2,9 +2,9 @@ /*! \file base_options_template.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/bv_bitblast_mode.cpp b/src/options/bv_bitblast_mode.cpp index f331345f7..e9f9b60f9 100644 --- a/src/options/bv_bitblast_mode.cpp +++ b/src/options/bv_bitblast_mode.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/bv_bitblast_mode.h b/src/options/bv_bitblast_mode.h index 3a6474104..5bc5f601f 100644 --- a/src/options/bv_bitblast_mode.h +++ b/src/options/bv_bitblast_mode.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/datatypes_modes.h b/src/options/datatypes_modes.h new file mode 100644 index 000000000..3576ffc72 --- /dev/null +++ b/src/options/datatypes_modes.h @@ -0,0 +1,44 @@ +/********************* */ +/*! \file datatypes_modes.h + ** \verbatim + ** Top contributors (to current version): + ** Andrew Reynolds, Tim King, Morgan Deters + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2016 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 [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "cvc4_public.h" + +#ifndef __CVC4__BASE__DATATYPES_MODES_H +#define __CVC4__BASE__DATATYPES_MODES_H + +#include <iostream> + +namespace CVC4 { +namespace theory { + +enum SygusFairMode { + /** enforce fairness by direct conflict lemmas */ + SYGUS_FAIR_DIRECT, + /** enforce fairness by datatypes size */ + SYGUS_FAIR_DT_SIZE, + /** enforce fairness by datatypes height bound */ + SYGUS_FAIR_DT_HEIGHT_PRED, + /** enforce fairness by datatypes size bound */ + SYGUS_FAIR_DT_SIZE_PRED, + /** do not use fair strategy for CEGQI */ + SYGUS_FAIR_NONE, +}; + +}/* CVC4::theory namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__BASE__DATATYPES_MODES_H */ diff --git a/src/options/datatypes_options b/src/options/datatypes_options index bb92b4e05..d4d3e941c 100644 --- a/src/options/datatypes_options +++ b/src/options/datatypes_options @@ -29,5 +29,23 @@ option dtInferAsLemmas --dt-infer-as-lemmas bool :default false # regression explanations for datatype lemmas option dtBlastSplits --dt-blast-splits bool :default false when applicable, blast splitting lemmas for all variables at once +option dtSharedSelectors --dt-share-sel bool :default true + internally use shared selectors across multiple constructors +option sygusSymBreak --sygus-sym-break bool :default true + simple sygus sym break lemmas +option sygusSymBreakDynamic --sygus-sym-break-dynamic bool :default true + dynamic sygus sym break lemmas +option sygusOpt1 --sygus-opt1 bool :default false + sygus experimental option +option sygusSymBreakLazy --sygus-sym-break-lazy bool :default true + lazily add symmetry breaking lemmas for terms +option sygusSymBreakRlv --sygus-sym-break-rlv bool :default true + add relevancy conditions to symmetry breaking lemmas + +option sygusFair --sygus-fair=MODE CVC4::theory::SygusFairMode :default CVC4::theory::SYGUS_FAIR_DT_SIZE :include "options/datatypes_modes.h" :handler stringToSygusFairMode + if and how to apply fairness for sygus +option sygusFairMax --sygus-fair-max bool :default true + use max instead of sum for multi-function sygus conjectures + endmodule diff --git a/src/options/decision_mode.cpp b/src/options/decision_mode.cpp index 3a93b0274..118ff8d68 100644 --- a/src/options/decision_mode.cpp +++ b/src/options/decision_mode.cpp @@ -2,9 +2,9 @@ /*! \file decision_mode.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/decision_mode.h b/src/options/decision_mode.h index efc6ca213..0d9c96e34 100644 --- a/src/options/decision_mode.h +++ b/src/options/decision_mode.h @@ -2,9 +2,9 @@ /*! \file decision_mode.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Kshitij Bansal, Tim King + ** Morgan Deters, Kshitij Bansal, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/decision_weight.h b/src/options/decision_weight.h index 6d01b18cb..83401428e 100644 --- a/src/options/decision_weight.h +++ b/src/options/decision_weight.h @@ -2,9 +2,9 @@ /*! \file decision_weight.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King, Morgan Deters + ** Kshitij Bansal, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/didyoumean.cpp b/src/options/didyoumean.cpp index 693764b37..40836ddd4 100644 --- a/src/options/didyoumean.cpp +++ b/src/options/didyoumean.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Kshitij Bansal, Tim King, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/didyoumean.h b/src/options/didyoumean.h index 31b58aadb..712912644 100644 --- a/src/options/didyoumean.h +++ b/src/options/didyoumean.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Kshitij Bansal, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/didyoumean_test.cpp b/src/options/didyoumean_test.cpp index 8117b57ac..76578b6c4 100644 --- a/src/options/didyoumean_test.cpp +++ b/src/options/didyoumean_test.cpp @@ -2,9 +2,9 @@ /*! \file didyoumean_test.cpp ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Morgan Deters, Tim King + ** Kshitij Bansal, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -21,28 +21,28 @@ #include "didyoumean.h" #include <iostream> -#include <boost/foreach.hpp> + using namespace std; using namespace CVC4; set<string> getDebugTags(); set<string> getOptionStrings(); -int main() -{ +int main() { string a, b; cin >> a; cout << "Matches with debug tags:" << endl; - vector<string> ret = DidYouMean(getDebugTags()).getMatch(a); - BOOST_FOREACH(string s, ret) cout << s << endl; + for (const string& s : DidYouMean(getDebugTags()).getMatch(a)) { + cout << s << endl; + } cout << "Matches with option strings:" << endl; - ret = DidYouMean(getOptionStrings()).getMatch(a); - BOOST_FOREACH(string s, ret) cout << s << endl; + for (const string& s : DidYouMean(getOptionStrings()).getMatch(a)) { + cout << s << endl; + } } -set<string> getDebugTags() -{ +set<string> getDebugTags() { set<string> a; a.insert("CDInsertHashMap"); a.insert("CDTrailHashMap"); @@ -426,340 +426,339 @@ set<string> getDebugTags() return a; } -set<string> getOptionStrings() -{ +set<string> getOptionStrings() { const char* cmdlineOptions[] = { - "lang", - "output-lang", - "language", - "output-language", - "verbose", - "quiet", - "stats", - "no-stats", - "statistics", - "no-statistics", - "stats-every-query", - "no-stats-every-query", - "statistics-every-query", - "no-statistics-every-query", - "parse-only", - "no-parse-only", - "preprocess-only", - "no-preprocess-only", - "trace", - "debug", - "print-success", - "no-print-success", - "smtlib-strict", - "default-expr-depth", - "default-dag-thresh", - "print-expr-types", - "eager-type-checking", - "lazy-type-checking", - "no-type-checking", - "biased-ites", - "no-biased-ites", - "boolean-term-conversion-mode", - "theoryof-mode", - "use-theory", - "bitblast-eager", - "no-bitblast-eager", - "bitblast-share-lemmas", - "no-bitblast-share-lemmas", - "bitblast-eager-fullcheck", - "no-bitblast-eager-fullcheck", - "bv-inequality-solver", - "no-bv-inequality-solver", - "bv-core-solver", - "no-bv-core-solver", - "bv-to-bool", - "no-bv-to-bool", - "bv-propagate", - "no-bv-propagate", - "bv-eq", - "no-bv-eq", - "dt-rewrite-error-sel", - "no-dt-rewrite-error-sel", - "dt-force-assignment", - "unate-lemmas", - "arith-prop", - "heuristic-pivots", - "standard-effort-variable-order-pivots", - "error-selection-rule", - "simplex-check-period", - "pivot-threshold", - "prop-row-length", - "disable-dio-solver", - "enable-arith-rewrite-equalities", - "disable-arith-rewrite-equalities", - "enable-miplib-trick", - "disable-miplib-trick", - "miplib-trick-subs", - "cut-all-bounded", - "no-cut-all-bounded", - "maxCutsInContext", - "revert-arith-models-on-unsat", - "no-revert-arith-models-on-unsat", - "fc-penalties", - "no-fc-penalties", - "use-fcsimplex", - "no-use-fcsimplex", - "use-soi", - "no-use-soi", - "restrict-pivots", - "no-restrict-pivots", - "collect-pivot-stats", - "no-collect-pivot-stats", - "use-approx", - "no-use-approx", - "approx-branch-depth", - "dio-decomps", - "no-dio-decomps", - "new-prop", - "no-new-prop", - "arith-prop-clauses", - "soi-qe", - "no-soi-qe", - "rewrite-divk", - "no-rewrite-divk", - "se-solve-int", - "no-se-solve-int", - "lemmas-on-replay-failure", - "no-lemmas-on-replay-failure", - "dio-turns", - "rr-turns", - "dio-repeat", - "no-dio-repeat", - "replay-early-close-depth", - "replay-failure-penalty", - "replay-num-err-penalty", - "replay-reject-cut", - "replay-lemma-reject-cut", - "replay-soi-major-threshold", - "replay-soi-major-threshold-pen", - "replay-soi-minor-threshold", - "replay-soi-minor-threshold-pen", - "symmetry-breaker", - "no-symmetry-breaker", - "condense-function-values", - "no-condense-function-values", - "disable-uf-ss-regions", - "uf-ss-eager-split", - "no-uf-ss-eager-split", - "uf-ss-totality", - "no-uf-ss-totality", - "uf-ss-totality-limited", - "uf-ss-totality-sym-break", - "no-uf-ss-totality-sym-break", - "uf-ss-abort-card", - "uf-ss-explained-cliques", - "no-uf-ss-explained-cliques", - "uf-ss-simple-cliques", - "no-uf-ss-simple-cliques", - "uf-ss-deq-prop", - "no-uf-ss-deq-prop", - "disable-uf-ss-min-model", - "uf-ss-clique-splits", - "no-uf-ss-clique-splits", - "uf-ss-sym-break", - "no-uf-ss-sym-break", - "uf-ss-fair", - "no-uf-ss-fair", - "arrays-optimize-linear", - "no-arrays-optimize-linear", - "arrays-lazy-rintro1", - "no-arrays-lazy-rintro1", - "arrays-model-based", - "no-arrays-model-based", - "arrays-eager-index", - "no-arrays-eager-index", - "arrays-eager-lemmas", - "no-arrays-eager-lemmas", - "disable-miniscope-quant", - "disable-miniscope-quant-fv", - "disable-prenex-quant", - "disable-var-elim-quant", - "disable-ite-lift-quant", - "cnf-quant", - "no-cnf-quant", - "clause-split", - "no-clause-split", - "pre-skolem-quant", - "no-pre-skolem-quant", - "ag-miniscope-quant", - "no-ag-miniscope-quant", - "macros-quant", - "no-macros-quant", - "fo-prop-quant", - "no-fo-prop-quant", - "disable-smart-triggers", - "relevant-triggers", - "no-relevant-triggers", - "relational-triggers", - "no-relational-triggers", - "register-quant-body-terms", - "no-register-quant-body-terms", - "inst-when", - "eager-inst-quant", - "no-eager-inst-quant", - "full-saturate-quant", - "no-full-saturate-quant", - "literal-matching", - "enable-cbqi", - "no-enable-cbqi", - "cbqi-recurse", - "no-cbqi-recurse", - "user-pat", - "flip-decision", - "disable-quant-internal-reps", - "finite-model-find", - "no-finite-model-find", - "mbqi", - "mbqi-one-inst-per-round", - "no-mbqi-one-inst-per-round", - "mbqi-one-quant-per-round", - "no-mbqi-one-quant-per-round", - "fmf-inst-engine", - "no-fmf-inst-engine", - "disable-fmf-inst-gen", - "fmf-inst-gen-one-quant-per-round", - "no-fmf-inst-gen-one-quant-per-round", - "fmf-fresh-dc", - "no-fmf-fresh-dc", - "disable-fmf-fmc-simple", - "fmf-bound-int", - "no-fmf-bound-int", - "axiom-inst", - "quant-cf", - "no-quant-cf", - "quant-cf-mode", - "quant-cf-when", - "rewrite-rules", - "no-rewrite-rules", - "rr-one-inst-per-round", - "no-rr-one-inst-per-round", - "strings-exp", - "no-strings-exp", - "strings-lb", - "strings-fmf", - "no-strings-fmf", - "strings-eit", - "no-strings-eit", - "strings-alphabet-card", - "show-sat-solvers", - "random-freq", - "random-seed", - "restart-int-base", - "restart-int-inc", - "refine-conflicts", - "no-refine-conflicts", - "minisat-elimination", - "no-minisat-elimination", - "minisat-dump-dimacs", - "no-minisat-dump-dimacs", - "model-format", - "dump", - "dump-to", - "force-logic", - "simplification", - "no-simplification", - "static-learning", - "no-static-learning", - "produce-models", - "no-produce-models", - "check-models", - "no-check-models", - "dump-models", - "no-dump-models", - "proof", - "no-proof", - "check-proofs", - "no-check-proofs", - "dump-proofs", - "no-dump-proofs", - "produce-unsat-cores", - "no-produce-unsat-cores", - "produce-assignments", - "no-produce-assignments", - "interactive", - "no-interactive", - "ite-simp", - "no-ite-simp", - "on-repeat-ite-simp", - "no-on-repeat-ite-simp", - "simp-with-care", - "no-simp-with-care", - "simp-ite-compress", - "no-simp-ite-compress", - "unconstrained-simp", - "no-unconstrained-simp", - "repeat-simp", - "no-repeat-simp", - "simp-ite-hunt-zombies", - "sort-inference", - "no-sort-inference", - "incremental", - "no-incremental", - "abstract-values", - "no-abstract-values", - "model-u-dt-enum", - "no-model-u-dt-enum", - "tlimit", - "tlimit-per", - "rlimit", - "rlimit-per", - "rewrite-apply-to-const", - "no-rewrite-apply-to-const", - "replay", - "replay-log", - "decision", - "decision-threshold", - "decision-use-weight", - "no-decision-use-weight", - "decision-random-weight", - "decision-weight-internal", - "version", - "license", - "help", - "show-config", - "show-debug-tags", - "show-trace-tags", - "early-exit", - "no-early-exit", - "threads", - "threadN", - "filter-lemma-length", - "fallback-sequential", - "no-fallback-sequential", - "incremental-parallel", - "no-incremental-parallel", - "no-interactive-prompt", - "continued-execution", - "immediate-exit", - "segv-spin", - "no-segv-spin", - "segv-nospin", - "wait-to-join", - "no-wait-to-join", - "strict-parsing", - "no-strict-parsing", - "mmap", - "no-mmap", - "no-checking", - "no-filesystem-access", - "no-include-file", - "enable-idl-rewrite-equalities", - "disable-idl-rewrite-equalities", - "sets-propagate", - "no-sets-propagate", - "sets-eager-lemmas", - "no-sets-eager-lemmas", - NULL, - };/* cmdlineOptions */ + "lang", + "output-lang", + "language", + "output-language", + "verbose", + "quiet", + "stats", + "no-stats", + "statistics", + "no-statistics", + "stats-every-query", + "no-stats-every-query", + "statistics-every-query", + "no-statistics-every-query", + "parse-only", + "no-parse-only", + "preprocess-only", + "no-preprocess-only", + "trace", + "debug", + "print-success", + "no-print-success", + "smtlib-strict", + "default-expr-depth", + "default-dag-thresh", + "print-expr-types", + "eager-type-checking", + "lazy-type-checking", + "no-type-checking", + "biased-ites", + "no-biased-ites", + "boolean-term-conversion-mode", + "theoryof-mode", + "use-theory", + "bitblast-eager", + "no-bitblast-eager", + "bitblast-share-lemmas", + "no-bitblast-share-lemmas", + "bitblast-eager-fullcheck", + "no-bitblast-eager-fullcheck", + "bv-inequality-solver", + "no-bv-inequality-solver", + "bv-core-solver", + "no-bv-core-solver", + "bv-to-bool", + "no-bv-to-bool", + "bv-propagate", + "no-bv-propagate", + "bv-eq", + "no-bv-eq", + "dt-rewrite-error-sel", + "no-dt-rewrite-error-sel", + "dt-force-assignment", + "unate-lemmas", + "arith-prop", + "heuristic-pivots", + "standard-effort-variable-order-pivots", + "error-selection-rule", + "simplex-check-period", + "pivot-threshold", + "prop-row-length", + "disable-dio-solver", + "enable-arith-rewrite-equalities", + "disable-arith-rewrite-equalities", + "enable-miplib-trick", + "disable-miplib-trick", + "miplib-trick-subs", + "cut-all-bounded", + "no-cut-all-bounded", + "maxCutsInContext", + "revert-arith-models-on-unsat", + "no-revert-arith-models-on-unsat", + "fc-penalties", + "no-fc-penalties", + "use-fcsimplex", + "no-use-fcsimplex", + "use-soi", + "no-use-soi", + "restrict-pivots", + "no-restrict-pivots", + "collect-pivot-stats", + "no-collect-pivot-stats", + "use-approx", + "no-use-approx", + "approx-branch-depth", + "dio-decomps", + "no-dio-decomps", + "new-prop", + "no-new-prop", + "arith-prop-clauses", + "soi-qe", + "no-soi-qe", + "rewrite-divk", + "no-rewrite-divk", + "se-solve-int", + "no-se-solve-int", + "lemmas-on-replay-failure", + "no-lemmas-on-replay-failure", + "dio-turns", + "rr-turns", + "dio-repeat", + "no-dio-repeat", + "replay-early-close-depth", + "replay-failure-penalty", + "replay-num-err-penalty", + "replay-reject-cut", + "replay-lemma-reject-cut", + "replay-soi-major-threshold", + "replay-soi-major-threshold-pen", + "replay-soi-minor-threshold", + "replay-soi-minor-threshold-pen", + "symmetry-breaker", + "no-symmetry-breaker", + "condense-function-values", + "no-condense-function-values", + "disable-uf-ss-regions", + "uf-ss-eager-split", + "no-uf-ss-eager-split", + "uf-ss-totality", + "no-uf-ss-totality", + "uf-ss-totality-limited", + "uf-ss-totality-sym-break", + "no-uf-ss-totality-sym-break", + "uf-ss-abort-card", + "uf-ss-explained-cliques", + "no-uf-ss-explained-cliques", + "uf-ss-simple-cliques", + "no-uf-ss-simple-cliques", + "uf-ss-deq-prop", + "no-uf-ss-deq-prop", + "disable-uf-ss-min-model", + "uf-ss-clique-splits", + "no-uf-ss-clique-splits", + "uf-ss-sym-break", + "no-uf-ss-sym-break", + "uf-ss-fair", + "no-uf-ss-fair", + "arrays-optimize-linear", + "no-arrays-optimize-linear", + "arrays-lazy-rintro1", + "no-arrays-lazy-rintro1", + "arrays-model-based", + "no-arrays-model-based", + "arrays-eager-index", + "no-arrays-eager-index", + "arrays-eager-lemmas", + "no-arrays-eager-lemmas", + "disable-miniscope-quant", + "disable-miniscope-quant-fv", + "disable-prenex-quant", + "disable-var-elim-quant", + "disable-ite-lift-quant", + "cnf-quant", + "no-cnf-quant", + "clause-split", + "no-clause-split", + "pre-skolem-quant", + "no-pre-skolem-quant", + "ag-miniscope-quant", + "no-ag-miniscope-quant", + "macros-quant", + "no-macros-quant", + "fo-prop-quant", + "no-fo-prop-quant", + "disable-smart-triggers", + "relevant-triggers", + "no-relevant-triggers", + "relational-triggers", + "no-relational-triggers", + "register-quant-body-terms", + "no-register-quant-body-terms", + "inst-when", + "eager-inst-quant", + "no-eager-inst-quant", + "full-saturate-quant", + "no-full-saturate-quant", + "literal-matching", + "enable-cbqi", + "no-enable-cbqi", + "cbqi-recurse", + "no-cbqi-recurse", + "user-pat", + "flip-decision", + "disable-quant-internal-reps", + "finite-model-find", + "no-finite-model-find", + "mbqi", + "mbqi-one-inst-per-round", + "no-mbqi-one-inst-per-round", + "mbqi-one-quant-per-round", + "no-mbqi-one-quant-per-round", + "fmf-inst-engine", + "no-fmf-inst-engine", + "disable-fmf-inst-gen", + "fmf-inst-gen-one-quant-per-round", + "no-fmf-inst-gen-one-quant-per-round", + "fmf-fresh-dc", + "no-fmf-fresh-dc", + "disable-fmf-fmc-simple", + "fmf-bound-int", + "no-fmf-bound-int", + "axiom-inst", + "quant-cf", + "no-quant-cf", + "quant-cf-mode", + "quant-cf-when", + "rewrite-rules", + "no-rewrite-rules", + "rr-one-inst-per-round", + "no-rr-one-inst-per-round", + "strings-exp", + "no-strings-exp", + "strings-lb", + "strings-fmf", + "no-strings-fmf", + "strings-eit", + "no-strings-eit", + "strings-alphabet-card", + "show-sat-solvers", + "random-freq", + "random-seed", + "restart-int-base", + "restart-int-inc", + "refine-conflicts", + "no-refine-conflicts", + "minisat-elimination", + "no-minisat-elimination", + "minisat-dump-dimacs", + "no-minisat-dump-dimacs", + "model-format", + "dump", + "dump-to", + "force-logic", + "simplification", + "no-simplification", + "static-learning", + "no-static-learning", + "produce-models", + "no-produce-models", + "check-models", + "no-check-models", + "dump-models", + "no-dump-models", + "proof", + "no-proof", + "check-proofs", + "no-check-proofs", + "dump-proofs", + "no-dump-proofs", + "produce-unsat-cores", + "no-produce-unsat-cores", + "produce-assignments", + "no-produce-assignments", + "interactive", + "no-interactive", + "ite-simp", + "no-ite-simp", + "on-repeat-ite-simp", + "no-on-repeat-ite-simp", + "simp-with-care", + "no-simp-with-care", + "simp-ite-compress", + "no-simp-ite-compress", + "unconstrained-simp", + "no-unconstrained-simp", + "repeat-simp", + "no-repeat-simp", + "simp-ite-hunt-zombies", + "sort-inference", + "no-sort-inference", + "incremental", + "no-incremental", + "abstract-values", + "no-abstract-values", + "model-u-dt-enum", + "no-model-u-dt-enum", + "tlimit", + "tlimit-per", + "rlimit", + "rlimit-per", + "rewrite-apply-to-const", + "no-rewrite-apply-to-const", + "replay", + "replay-log", + "decision", + "decision-threshold", + "decision-use-weight", + "no-decision-use-weight", + "decision-random-weight", + "decision-weight-internal", + "version", + "license", + "help", + "show-config", + "show-debug-tags", + "show-trace-tags", + "early-exit", + "no-early-exit", + "threads", + "threadN", + "filter-lemma-length", + "fallback-sequential", + "no-fallback-sequential", + "incremental-parallel", + "no-incremental-parallel", + "no-interactive-prompt", + "continued-execution", + "immediate-exit", + "segv-spin", + "no-segv-spin", + "segv-nospin", + "wait-to-join", + "no-wait-to-join", + "strict-parsing", + "no-strict-parsing", + "mmap", + "no-mmap", + "no-checking", + "no-filesystem-access", + "no-include-file", + "enable-idl-rewrite-equalities", + "disable-idl-rewrite-equalities", + "sets-propagate", + "no-sets-propagate", + "sets-eager-lemmas", + "no-sets-eager-lemmas", + NULL, + }; /* cmdlineOptions */ int i = 0; set<string> ret; - while(cmdlineOptions[i] != NULL) { + while (cmdlineOptions[i] != NULL) { ret.insert(cmdlineOptions[i]); i++; } diff --git a/src/options/language.cpp b/src/options/language.cpp index 7ae9d075a..bbb95f258 100644 --- a/src/options/language.cpp +++ b/src/options/language.cpp @@ -2,9 +2,9 @@ /*! \file language.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Morgan Deters, Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/language.h b/src/options/language.h index 6732aa6bd..f238e765d 100644 --- a/src/options/language.h +++ b/src/options/language.h @@ -2,9 +2,9 @@ /*! \file language.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Francois Bobot, Andrew Reynolds + ** Morgan Deters, Andrew Reynolds, Francois Bobot ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/open_ostream.cpp b/src/options/open_ostream.cpp index 214f148aa..e93764eed 100644 --- a/src/options/open_ostream.cpp +++ b/src/options/open_ostream.cpp @@ -2,9 +2,9 @@ /*! \file open_ostream.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/open_ostream.h b/src/options/open_ostream.h index 6c00e7dd1..7630c3bf0 100644 --- a/src/options/open_ostream.h +++ b/src/options/open_ostream.h @@ -2,9 +2,9 @@ /*! \file open_ostream.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/option_exception.h b/src/options/option_exception.h index 450eda988..4cea29592 100644 --- a/src/options/option_exception.h +++ b/src/options/option_exception.h @@ -2,9 +2,9 @@ /*! \file option_exception.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/options.h b/src/options/options.h index 3551d82ae..6b2bfedad 100644 --- a/src/options/options.h +++ b/src/options/options.h @@ -2,9 +2,9 @@ /*! \file options.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Kshitij Bansal + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/options_get_option_template.cpp b/src/options/options_get_option_template.cpp index d50644a5d..81a0daf5f 100644 --- a/src/options/options_get_option_template.cpp +++ b/src/options/options_get_option_template.cpp @@ -2,9 +2,9 @@ /*! \file options_get_option_template.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/options_handler.cpp b/src/options/options_handler.cpp index d24558a00..5658b17b0 100644 --- a/src/options/options_handler.cpp +++ b/src/options/options_handler.cpp @@ -2,9 +2,9 @@ /*! \file options_handler.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Andrew Reynolds + ** Tim King, Andrew Reynolds, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -36,6 +36,7 @@ #include "options/bv_options.h" #include "options/decision_mode.h" #include "options/decision_options.h" +#include "options/datatypes_modes.h" #include "options/didyoumean.h" #include "options/language.h" #include "options/option_exception.h" @@ -399,11 +400,14 @@ norm \n\ "; const std::string OptionsHandler::s_cegqiFairModeHelp = "\ -Modes for enforcing fairness for counterexample guided quantifier instantion, supported by --cegqi-fair:\n\ +Modes for enforcing fairness for counterexample guided quantifier instantion, supported by --sygus-fair:\n\ \n\ uf-dt-size \n\ + Enforce fairness using an uninterpreted function for datatypes size.\n\ \n\ +direct \n\ ++ Enforce fairness using direct conflict lemmas.\n\ +\n\ default | dt-size \n\ + Default, enforce fairness using size operator.\n\ \n\ @@ -716,17 +720,17 @@ theory::quantifiers::PrenexQuantMode OptionsHandler::stringToPrenexQuantMode(std } } -theory::quantifiers::CegqiFairMode OptionsHandler::stringToCegqiFairMode(std::string option, std::string optarg) throw(OptionException) { - if(optarg == "uf-dt-size" ) { - return theory::quantifiers::CEGQI_FAIR_UF_DT_SIZE; +theory::SygusFairMode OptionsHandler::stringToSygusFairMode(std::string option, std::string optarg) throw(OptionException) { + if(optarg == "direct") { + return theory::SYGUS_FAIR_DIRECT; } else if(optarg == "default" || optarg == "dt-size") { - return theory::quantifiers::CEGQI_FAIR_DT_SIZE; + return theory::SYGUS_FAIR_DT_SIZE; } else if(optarg == "dt-height-bound" ){ - return theory::quantifiers::CEGQI_FAIR_DT_HEIGHT_PRED; - //} else if(optarg == "dt-size-bound" ){ - // return theory::quantifiers::CEGQI_FAIR_DT_SIZE_PRED; + return theory::SYGUS_FAIR_DT_HEIGHT_PRED; + } else if(optarg == "dt-size-bound" ){ + return theory::SYGUS_FAIR_DT_SIZE_PRED; } else if(optarg == "none") { - return theory::quantifiers::CEGQI_FAIR_NONE; + return theory::SYGUS_FAIR_NONE; } else if(optarg == "help") { puts(s_cegqiFairModeHelp.c_str()); exit(1); diff --git a/src/options/options_handler.h b/src/options/options_handler.h index 6721eaa2b..16c77b166 100644 --- a/src/options/options_handler.h +++ b/src/options/options_handler.h @@ -2,9 +2,9 @@ /*! \file options_handler.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Andrew Reynolds + ** Tim King, Andrew Reynolds, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -29,6 +29,7 @@ #include "options/base_handlers.h" #include "options/bv_bitblast_mode.h" #include "options/decision_mode.h" +#include "options/datatypes_modes.h" #include "options/language.h" #include "options/option_exception.h" #include "options/options.h" @@ -95,7 +96,6 @@ public: theory::quantifiers::TriggerSelMode stringToTriggerSelMode(std::string option, std::string optarg) throw(OptionException); theory::quantifiers::TriggerActiveSelMode stringToTriggerActiveSelMode(std::string option, std::string optarg) throw(OptionException); theory::quantifiers::PrenexQuantMode stringToPrenexQuantMode(std::string option, std::string optarg) throw(OptionException); - theory::quantifiers::CegqiFairMode stringToCegqiFairMode(std::string option, std::string optarg) throw(OptionException); theory::quantifiers::TermDbMode stringToTermDbMode(std::string option, std::string optarg) throw(OptionException); theory::quantifiers::IteLiftQuantMode stringToIteLiftQuantMode(std::string option, std::string optarg) throw(OptionException); theory::quantifiers::CegqiSingleInvMode stringToCegqiSingleInvMode(std::string option, std::string optarg) throw(OptionException); @@ -104,6 +104,7 @@ public: theory::quantifiers::QuantDSplitMode stringToQuantDSplitMode(std::string option, std::string optarg) throw(OptionException); theory::quantifiers::QuantRepMode stringToQuantRepMode(std::string option, std::string optarg) throw(OptionException); theory::quantifiers::FmfBoundMinMode stringToFmfBoundMinMode(std::string option, std::string optarg) throw(OptionException); + theory::SygusFairMode stringToSygusFairMode(std::string option, std::string optarg) throw(OptionException); // theory/bv/options_handlers.h void abcEnabledBuild(std::string option, bool value) throw(OptionException); diff --git a/src/options/options_holder_template.h b/src/options/options_holder_template.h index f33656eb1..0d6da1e56 100644 --- a/src/options/options_holder_template.h +++ b/src/options/options_holder_template.h @@ -2,9 +2,9 @@ /*! \file options_holder_template.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/options_public_functions.cpp b/src/options/options_public_functions.cpp index 111b5482a..54fbd3c81 100644 --- a/src/options/options_public_functions.cpp +++ b/src/options/options_public_functions.cpp @@ -2,9 +2,9 @@ /*! \file options_public_functions.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/options_set_option_template.cpp b/src/options/options_set_option_template.cpp index cc068f4e6..cfe642b7b 100644 --- a/src/options/options_set_option_template.cpp +++ b/src/options/options_set_option_template.cpp @@ -2,9 +2,9 @@ /*! \file options_set_option_template.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/options_template.cpp b/src/options/options_template.cpp index 584be1329..6144b57dc 100644 --- a/src/options/options_template.cpp +++ b/src/options/options_template.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Kshitij Bansal ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/printer_modes.cpp b/src/options/printer_modes.cpp index 3ca311a96..ef4dc6b73 100644 --- a/src/options/printer_modes.cpp +++ b/src/options/printer_modes.cpp @@ -2,9 +2,9 @@ /*! \file printer_modes.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Morgan Deters, Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/printer_modes.h b/src/options/printer_modes.h index a05ca2470..db3efe63a 100644 --- a/src/options/printer_modes.h +++ b/src/options/printer_modes.h @@ -2,9 +2,9 @@ /*! \file printer_modes.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tim King + ** Andrew Reynolds, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/quantifiers_modes.cpp b/src/options/quantifiers_modes.cpp index e2cd78de5..0b89260e9 100644 --- a/src/options/quantifiers_modes.cpp +++ b/src/options/quantifiers_modes.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/quantifiers_modes.h b/src/options/quantifiers_modes.h index e4c539e09..0b410e3fe 100644 --- a/src/options/quantifiers_modes.h +++ b/src/options/quantifiers_modes.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -133,19 +133,6 @@ enum CVC4_PUBLIC PrenexQuantMode { PRENEX_QUANT_NORMAL, }; -enum CegqiFairMode { - /** enforce fairness by UF corresponding to datatypes size */ - CEGQI_FAIR_UF_DT_SIZE, - /** enforce fairness by datatypes size */ - CEGQI_FAIR_DT_SIZE, - /** enforce fairness by datatypes height bound */ - CEGQI_FAIR_DT_HEIGHT_PRED, - /** enforce fairness by datatypes size bound */ - CEGQI_FAIR_DT_SIZE_PRED, - /** do not use fair strategy for CEGQI */ - CEGQI_FAIR_NONE, -}; - enum TermDbMode { /** consider all terms in master equality engine */ TERM_DB_ALL, diff --git a/src/options/quantifiers_options b/src/options/quantifiers_options index f15723e08..2cbf15873 100644 --- a/src/options/quantifiers_options +++ b/src/options/quantifiers_options @@ -245,8 +245,6 @@ option conjectureGenMaxDepth --conjecture-gen-max-depth=N int :default 3 option ceGuidedInst --cegqi bool :default false :read-write counterexample-guided quantifier instantiation -option ceGuidedInstFair --cegqi-fair=MODE CVC4::theory::quantifiers::CegqiFairMode :default CVC4::theory::quantifiers::CEGQI_FAIR_DT_SIZE :include "options/quantifiers_modes.h" :handler stringToCegqiFairMode - if and how to apply fairness for cegqi option cegqiSingleInvMode --cegqi-si=MODE CVC4::theory::quantifiers::CegqiSingleInvMode :default CVC4::theory::quantifiers::CEGQI_SI_MODE_NONE :include "options/quantifiers_modes.h" :handler stringToCegqiSingleInvMode :read-write mode for processing single invocation synthesis conjectures option cegqiSingleInvPartial --cegqi-si-partial bool :default false @@ -261,29 +259,31 @@ option cegqiSingleInvReconstructConst --cegqi-si-reconstruct-const bool :default include constants when reconstruct solutions for single invocation conjectures in original grammar option cegqiSingleInvAbort --cegqi-si-abort bool :default false abort if synthesis conjecture is not single invocation +option sygusPbe --sygus-pbe bool :default true + sygus advanced pruning based on examples -option sygusNormalForm --sygus-nf bool :default true - only search for sygus builtin terms that are in normal form -option sygusNormalFormArg --sygus-nf-arg bool :default true - account for relationship between arguments of operations in sygus normal form -option sygusNormalFormGlobal --sygus-nf-sym bool :default true - narrow sygus search space based on global state of current candidate program -option sygusNormalFormGlobalGen --sygus-nf-sym-gen bool :default true - generalize lemmas for global search space narrowing -option sygusNormalFormGlobalArg --sygus-nf-sym-arg bool :default true - generalize based on arguments in global search space narrowing -option sygusNormalFormGlobalContent --sygus-nf-sym-content bool :default true - generalize based on content in global search space narrowing +option sygusMinGrammar --sygus-min-grammar bool :default true + statically minimize sygus grammars +option sygusMinGrammarAgg --sygus-min-grammar-agg bool :default false + aggressively minimize sygus grammars +option sygusAddConstGrammar --sygus-add-const-grammar bool :default true + statically add constants appearing in conjecture to grammars option sygusInvTemplMode --sygus-inv-templ=MODE CVC4::theory::quantifiers::SygusInvTemplMode :default CVC4::theory::quantifiers::SYGUS_INV_TEMPL_MODE_NONE :include "options/quantifiers_modes.h" :handler stringToSygusInvTemplMode template mode for sygus invariant synthesis -option sygusUnifCondSol --sygus-unif-csol bool :default false - enable approach which unifies conditional solutions +option sygusInvAutoUnfold --sygus-auto-unfold bool :default true + enable approach which automatically unfolds transition systems for directly solving invariant synthesis problems +option sygusUnifCondSol --sygus-unif-csol bool :default true + enable new approach which unifies conditional solutions option sygusDirectEval --sygus-direct-eval bool :default true direct unfolding of evaluation functions -option sygusCRefEval --sygus-cref-eval bool :default false +option sygusUnfoldBool --sygus-unfold-bool bool :default true + do unfolding of Boolean evaluation functions that appear in refinement lemmas +option sygusCRefEval --sygus-cref-eval bool :default true direct evaluation of refinement lemmas for conflict analysis +option sygusCRefEvalMinExp --sygus-cref-eval-min-exp bool :default true + use min explain for direct evaluation of refinement lemmas for conflict analysis # approach applied to general quantified formulas option cbqi --cbqi bool :read-write :default false diff --git a/src/options/set_language.cpp b/src/options/set_language.cpp index 32d3d73ae..18546b2e3 100644 --- a/src/options/set_language.cpp +++ b/src/options/set_language.cpp @@ -2,9 +2,9 @@ /*! \file set_language.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/set_language.h b/src/options/set_language.h index c27bb5184..e3db0c461 100644 --- a/src/options/set_language.h +++ b/src/options/set_language.h @@ -2,9 +2,9 @@ /*! \file set_language.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/simplification_mode.cpp b/src/options/simplification_mode.cpp index 7189dacd1..1a3470b8b 100644 --- a/src/options/simplification_mode.cpp +++ b/src/options/simplification_mode.cpp @@ -2,9 +2,9 @@ /*! \file simplification_mode.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/simplification_mode.h b/src/options/simplification_mode.h index d1170f9ad..4bf9166a4 100644 --- a/src/options/simplification_mode.h +++ b/src/options/simplification_mode.h @@ -2,9 +2,9 @@ /*! \file simplification_mode.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/theoryof_mode.cpp b/src/options/theoryof_mode.cpp index cf7178042..9eb2be178 100644 --- a/src/options/theoryof_mode.cpp +++ b/src/options/theoryof_mode.cpp @@ -2,9 +2,9 @@ /*! \file theoryof_mode.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/theoryof_mode.h b/src/options/theoryof_mode.h index 98f05a131..f999a6081 100644 --- a/src/options/theoryof_mode.h +++ b/src/options/theoryof_mode.h @@ -2,9 +2,9 @@ /*! \file theoryof_mode.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/options/ufss_mode.h b/src/options/ufss_mode.h index 4a4b8b4c1..4cbf18cc0 100644 --- a/src/options/ufss_mode.h +++ b/src/options/ufss_mode.h @@ -2,9 +2,9 @@ /*! \file ufss_mode.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/antlr_input.cpp b/src/parser/antlr_input.cpp index cbdaaa2bf..915174982 100644 --- a/src/parser/antlr_input.cpp +++ b/src/parser/antlr_input.cpp @@ -2,9 +2,9 @@ /*! \file antlr_input.cpp ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Kshitij Bansal, Tim King + ** Christopher L. Conway, Kshitij Bansal, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/antlr_input.h b/src/parser/antlr_input.h index 293be0087..afede6bbf 100644 --- a/src/parser/antlr_input.h +++ b/src/parser/antlr_input.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Christopher L. Conway, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/antlr_input_imports.cpp b/src/parser/antlr_input_imports.cpp index e74d83882..3f0a119a7 100644 --- a/src/parser/antlr_input_imports.cpp +++ b/src/parser/antlr_input_imports.cpp @@ -1,15 +1,13 @@ /********************* */ /*! \file antlr_input_imports.cpp ** \verbatim - ** Original author: cconway - ** Major contributors: none - ** Minor contributors (to current version): none - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) - ** Courant Institute of Mathematical Sciences - ** New York University - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** Top contributors (to current version): + ** Christopher L. Conway, Francois Bobot, Morgan Deters + ** 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 [[ Add one-line brief description here ]] ** diff --git a/src/parser/antlr_line_buffered_input.cpp b/src/parser/antlr_line_buffered_input.cpp index e65125ad9..8a4bcdebb 100644 --- a/src/parser/antlr_line_buffered_input.cpp +++ b/src/parser/antlr_line_buffered_input.cpp @@ -2,9 +2,9 @@ /*! \file antlr_line_buffered_input.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andres Noetzli + ** Morgan Deters, Andres Noetzli, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/antlr_line_buffered_input.h b/src/parser/antlr_line_buffered_input.h index 4535ffe6b..bdff4b6b6 100644 --- a/src/parser/antlr_line_buffered_input.h +++ b/src/parser/antlr_line_buffered_input.h @@ -2,9 +2,9 @@ /*! \file antlr_line_buffered_input.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andres Noetzli + ** Morgan Deters, Andres Noetzli, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/antlr_tracing.h b/src/parser/antlr_tracing.h index 93a781796..a1d2811c4 100644 --- a/src/parser/antlr_tracing.h +++ b/src/parser/antlr_tracing.h @@ -2,9 +2,9 @@ /*! \file antlr_tracing.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/antlr_undefines.h b/src/parser/antlr_undefines.h index edf64c8a6..fa80e5135 100644 --- a/src/parser/antlr_undefines.h +++ b/src/parser/antlr_undefines.h @@ -2,9 +2,9 @@ /*! \file antlr_undefines.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/bounded_token_buffer.cpp b/src/parser/bounded_token_buffer.cpp index 31a2219b9..7fb29b9e1 100644 --- a/src/parser/bounded_token_buffer.cpp +++ b/src/parser/bounded_token_buffer.cpp @@ -2,9 +2,9 @@ /*! \file bounded_token_buffer.cpp ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/bounded_token_buffer.h b/src/parser/bounded_token_buffer.h index 947b33f69..4fc62d468 100644 --- a/src/parser/bounded_token_buffer.h +++ b/src/parser/bounded_token_buffer.h @@ -2,9 +2,9 @@ /*! \file bounded_token_buffer.h ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/bounded_token_factory.cpp b/src/parser/bounded_token_factory.cpp index 1c5a00958..81be2e5ff 100644 --- a/src/parser/bounded_token_factory.cpp +++ b/src/parser/bounded_token_factory.cpp @@ -2,9 +2,9 @@ /*! \file bounded_token_factory.cpp ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/bounded_token_factory.h b/src/parser/bounded_token_factory.h index 8535d49cf..c2d3417d4 100644 --- a/src/parser/bounded_token_factory.h +++ b/src/parser/bounded_token_factory.h @@ -2,9 +2,9 @@ /*! \file bounded_token_factory.h ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/cvc/Cvc.g b/src/parser/cvc/Cvc.g index b5bad6a2d..a2e9e6f47 100644 --- a/src/parser/cvc/Cvc.g +++ b/src/parser/cvc/Cvc.g @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Christopher L. Conway, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -489,10 +489,11 @@ Expr addNots(ExprManager* em, size_t n, Expr e) { @header { /** - ** This file is part of CVC4. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information. + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2016 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. **/ }/* @header */ @@ -530,10 +531,10 @@ Expr addNots(ExprManager* em, size_t n, Expr e) { // files. See the documentation in "parser/antlr_undefines.h" for more details. #include "parser/antlr_undefines.h" -#include <stdint.h> #include <cassert> +#include <memory> +#include <stdint.h> -#include "base/ptr_closer.h" #include "options/set_language.h" #include "parser/antlr_tracing.h" #include "parser/parser.h" @@ -594,7 +595,6 @@ namespace CVC4 { #include <vector> #include "base/output.h" -#include "base/ptr_closer.h" #include "expr/expr.h" #include "expr/kind.h" #include "expr/type.h" @@ -658,7 +658,7 @@ parseExpr returns [CVC4::Expr expr = CVC4::Expr()] */ parseCommand returns [CVC4::Command* cmd_return = NULL] @declarations { - CVC4::PtrCloser<CVC4::Command> cmd; + std::unique_ptr<CVC4::Command> cmd; } @after { cmd_return = cmd.release(); @@ -688,7 +688,7 @@ parseCommand returns [CVC4::Command* cmd_return = NULL] * Matches a command of the input. If a declaration, it will return an empty * command. */ -command [CVC4::PtrCloser<CVC4::Command>* cmd] +command [std::unique_ptr<CVC4::Command>* cmd] : ( mainCommand[cmd] SEMICOLON | SEMICOLON | LET_TOK { PARSER_STATE->pushScope(); } @@ -715,7 +715,7 @@ options { backtrack = true; } : letDecl | typeLetDecl[check] ; -mainCommand[CVC4::PtrCloser<CVC4::Command>* cmd] +mainCommand[std::unique_ptr<CVC4::Command>* cmd] @init { Expr f; SExpr sexpr; @@ -933,7 +933,7 @@ symbolicExpr[CVC4::SExpr& sexpr] /** * Match a top-level declaration. */ -toplevelDeclaration[CVC4::PtrCloser<CVC4::Command>* cmd] +toplevelDeclaration[std::unique_ptr<CVC4::Command>* cmd] @init { std::vector<std::string> ids; Type t; @@ -950,7 +950,7 @@ toplevelDeclaration[CVC4::PtrCloser<CVC4::Command>* cmd] */ boundVarDecl[std::vector<std::string>& ids, CVC4::Type& t] @init { - CVC4::PtrCloser<Command> local_cmd; + std::unique_ptr<Command> local_cmd; } : identifierList[ids,CHECK_NONE,SYM_VARIABLE] COLON declareVariables[&local_cmd,t,ids,false] @@ -1001,14 +1001,14 @@ boundVarDeclReturn[std::vector<CVC4::Expr>& terms, * because type declarations are always top-level, except for * type-lets, which don't use this rule. */ -declareTypes[CVC4::PtrCloser<CVC4::Command>* cmd, +declareTypes[std::unique_ptr<CVC4::Command>* cmd, const std::vector<std::string>& idList] @init { Type t; } /* A sort declaration (e.g., "T : TYPE") */ : TYPE_TOK - { CVC4::PtrCloser<DeclarationSequence> seq(new DeclarationSequence()); + { std::unique_ptr<DeclarationSequence> seq(new DeclarationSequence()); for(std::vector<std::string>::const_iterator i = idList.begin(); i != idList.end(); ++i) { // Don't allow a type variable to clash with a previously @@ -1043,7 +1043,7 @@ declareTypes[CVC4::PtrCloser<CVC4::Command>* cmd, * permitted and "cmd" is output. If topLevel is false, bound vars * are created */ -declareVariables[CVC4::PtrCloser<CVC4::Command>* cmd, CVC4::Type& t, +declareVariables[std::unique_ptr<CVC4::Command>* cmd, CVC4::Type& t, const std::vector<std::string>& idList, bool topLevel] @init { Expr f; @@ -1051,7 +1051,7 @@ declareVariables[CVC4::PtrCloser<CVC4::Command>* cmd, CVC4::Type& t, } /* A variable declaration (or definition) */ : type[t,CHECK_DECLARED] ( EQUAL_TOK formula[f] )? - { CVC4::PtrCloser<DeclarationSequence> seq; + { std::unique_ptr<DeclarationSequence> seq; if(topLevel) { seq.reset(new DeclarationSequence()); } @@ -1292,7 +1292,8 @@ restrictedTypePossiblyFunctionLHS[CVC4::Type& t, << "] inappropriate: range must be nonempty!"; PARSER_STATE->parseError(ss.str()); } - t = EXPR_MANAGER->mkSubrangeType(SubrangeBounds(k1, k2)); + PARSER_STATE->unimplementedFeature("subrange typing not supported in this release"); + //t = EXPR_MANAGER->mkSubrangeType(SubrangeBounds(k1, k2)); } /* tuple types / old-style function types */ @@ -1615,7 +1616,7 @@ tupleStore[CVC4::Expr& f] const Datatype & dt = ((DatatypeType)t).getDatatype(); args.push_back( dt[0][k].getSelector() ); args.push_back( f ); - f2 = MK_EXPR(CVC4::kind::APPLY_SELECTOR_TOTAL,args); + f2 = MK_EXPR(CVC4::kind::APPLY_SELECTOR,args); } ( ( arrayStore[f2] | DOT ( tupleStore[f2] @@ -1650,7 +1651,7 @@ recordStore[CVC4::Expr& f] const Datatype & dt = ((DatatypeType)t).getDatatype(); args.push_back( dt[0][id].getSelector() ); args.push_back( f ); - f2 = MK_EXPR(CVC4::kind::APPLY_SELECTOR_TOTAL,args); + f2 = MK_EXPR(CVC4::kind::APPLY_SELECTOR,args); } ( ( arrayStore[f2] | DOT ( tupleStore[f2] @@ -1801,7 +1802,7 @@ postfixTerm[CVC4::Expr& f] std::vector<Expr> sargs; sargs.push_back( dt[0][id].getSelector() ); sargs.push_back( f ); - f = MK_EXPR(CVC4::kind::APPLY_SELECTOR_TOTAL,sargs); + f = MK_EXPR(CVC4::kind::APPLY_SELECTOR,sargs); } | k=numeral { Type t = f.getType(); @@ -1818,7 +1819,7 @@ postfixTerm[CVC4::Expr& f] std::vector<Expr> sargs; sargs.push_back( dt[0][k].getSelector() ); sargs.push_back( f ); - f = MK_EXPR(CVC4::kind::APPLY_SELECTOR_TOTAL,sargs); + f = MK_EXPR(CVC4::kind::APPLY_SELECTOR,sargs); } ) )* @@ -2258,7 +2259,7 @@ datatypeDef[std::vector<CVC4::Datatype>& datatypes] constructorDef[CVC4::Datatype& type] @init { std::string id; - CVC4::PtrCloser<CVC4::DatatypeConstructor> ctor; + std::unique_ptr<CVC4::DatatypeConstructor> ctor; } : identifier[id,CHECK_UNDECLARED,SYM_SORT] { // make the tester @@ -2278,7 +2279,7 @@ constructorDef[CVC4::Datatype& type] } ; -selector[CVC4::PtrCloser<CVC4::DatatypeConstructor>* ctor] +selector[std::unique_ptr<CVC4::DatatypeConstructor>* ctor] @init { std::string id; Type t, t2; diff --git a/src/parser/cvc/Makefile.am b/src/parser/cvc/Makefile.am index 8f084ba34..ff3308d89 100644 --- a/src/parser/cvc/Makefile.am +++ b/src/parser/cvc/Makefile.am @@ -4,8 +4,9 @@ AM_CPPFLAGS = \ AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) $(WNO_PARENTHESES) $(WNO_TAUTOLOGICAL_COMPARE) -Wno-unused-function -Wno-unused-variable $(WNO_UNINITIALIZED) $(WNO_CONVERSION_NULL) # Compile generated C files using C++ compiler -CC=$(CXX) AM_CFLAGS = $(AM_CXXFLAGS) +CFLAGS=$(CXXFLAGS) +CC=$(CXX) ANTLR_OPTS = diff --git a/src/parser/cvc/cvc_input.cpp b/src/parser/cvc/cvc_input.cpp index 9e00567fe..f2809391f 100644 --- a/src/parser/cvc/cvc_input.cpp +++ b/src/parser/cvc/cvc_input.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Christopher L. Conway, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/cvc/cvc_input.h b/src/parser/cvc/cvc_input.h index aff3698fc..bc16d646e 100644 --- a/src/parser/cvc/cvc_input.h +++ b/src/parser/cvc/cvc_input.h @@ -2,9 +2,9 @@ /*! \file cvc_input.h ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/input.cpp b/src/parser/input.cpp index 5fadbcc54..c8c3c5e6d 100644 --- a/src/parser/input.cpp +++ b/src/parser/input.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Christopher L. Conway, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/input.h b/src/parser/input.h index 6aec8a2b1..b41d8a898 100644 --- a/src/parser/input.h +++ b/src/parser/input.h @@ -2,9 +2,9 @@ /*! \file input.h ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/line_buffer.cpp b/src/parser/line_buffer.cpp index cdb06193e..399b4d210 100644 --- a/src/parser/line_buffer.cpp +++ b/src/parser/line_buffer.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/line_buffer.h b/src/parser/line_buffer.h index d7ccb5a10..f65e27fed 100644 --- a/src/parser/line_buffer.h +++ b/src/parser/line_buffer.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/memory_mapped_input_buffer.cpp b/src/parser/memory_mapped_input_buffer.cpp index 1554428f7..87142e0fd 100644 --- a/src/parser/memory_mapped_input_buffer.cpp +++ b/src/parser/memory_mapped_input_buffer.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Christopher L. Conway, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/memory_mapped_input_buffer.h b/src/parser/memory_mapped_input_buffer.h index 2a34d1197..9373c0ad5 100644 --- a/src/parser/memory_mapped_input_buffer.h +++ b/src/parser/memory_mapped_input_buffer.h @@ -2,9 +2,9 @@ /*! \file memory_mapped_input_buffer.h ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 2377b8a44..63492caa8 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -2,9 +2,9 @@ /*! \file parser.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Christopher L. Conway, Tim King + ** Morgan Deters, Tim King, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/parser.h b/src/parser/parser.h index b310456bd..5e867afa3 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Christopher L. Conway, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/parser_builder.cpp b/src/parser/parser_builder.cpp index a666fd381..ec8d4949d 100644 --- a/src/parser/parser_builder.cpp +++ b/src/parser/parser_builder.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Christopher L. Conway, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/parser_builder.h b/src/parser/parser_builder.h index 68dd684c1..4b4eb4e4e 100644 --- a/src/parser/parser_builder.h +++ b/src/parser/parser_builder.h @@ -2,9 +2,9 @@ /*! \file parser_builder.h ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/parser_exception.h b/src/parser/parser_exception.h index d83aab299..48eb43e33 100644 --- a/src/parser/parser_exception.h +++ b/src/parser/parser_exception.h @@ -2,9 +2,9 @@ /*! \file parser_exception.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Christopher L. Conway, Tim King + ** Morgan Deters, Christopher L. Conway, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/smt1/Makefile.am b/src/parser/smt1/Makefile.am index ae49d0659..f5320002d 100644 --- a/src/parser/smt1/Makefile.am +++ b/src/parser/smt1/Makefile.am @@ -5,6 +5,7 @@ AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) $(WNO_PARENTH # Compile generated C files using C++ compiler AM_CFLAGS = $(AM_CXXFLAGS) +CFLAGS=$(CXXFLAGS) CC=$(CXX) ANTLR_OPTS = diff --git a/src/parser/smt1/Smt1.g b/src/parser/smt1/Smt1.g index 28c54fc80..b30922d58 100644 --- a/src/parser/smt1/Smt1.g +++ b/src/parser/smt1/Smt1.g @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Christopher L. Conway, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -31,10 +31,11 @@ options { @header { /** - ** This file is part of CVC4. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information. + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2016 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. **/ }/* @header */ @@ -70,9 +71,9 @@ options { // files. See the documentation in "parser/antlr_undefines.h" for more details. #include "parser/antlr_undefines.h" +#include <memory> #include <stdint.h> -#include "base/ptr_closer.h" #include "smt/command.h" #include "parser/parser.h" #include "parser/antlr_tracing.h" @@ -114,7 +115,6 @@ namespace CVC4 { #include <vector> #include "base/output.h" -#include "base/ptr_closer.h" #include "expr/expr.h" #include "expr/kind.h" #include "expr/type.h" @@ -156,7 +156,7 @@ parseExpr returns [CVC4::parser::smt1::myExpr expr] */ parseCommand returns [CVC4::Command* cmd_return = NULL] @declarations { - CVC4::PtrCloser<CVC4::Command> cmd; + std::unique_ptr<CVC4::Command> cmd; } @after { cmd_return = cmd.release(); @@ -176,7 +176,7 @@ parseCommand returns [CVC4::Command* cmd_return = NULL] * Matches the whole SMT-LIB benchmark. * @return the sequence command containing the whole problem */ -benchmark [CVC4::PtrCloser<CVC4::Command>* cmd] +benchmark [std::unique_ptr<CVC4::Command>* cmd] : LPAREN_TOK BENCHMARK_TOK IDENTIFIER benchAttributes[cmd] RPAREN_TOK | EOF ; @@ -186,10 +186,10 @@ benchmark [CVC4::PtrCloser<CVC4::Command>* cmd] * command sequence. * @return the command sequence */ -benchAttributes [CVC4::PtrCloser<CVC4::Command>* cmd] +benchAttributes [std::unique_ptr<CVC4::Command>* cmd] @init { - CVC4::PtrCloser<CVC4::CommandSequence> cmd_seq(new CommandSequence()); - CVC4::PtrCloser<CVC4::Command> attribute; + std::unique_ptr<CVC4::CommandSequence> cmd_seq(new CommandSequence()); + std::unique_ptr<CVC4::Command> attribute; } @after { cmd->reset(cmd_seq.release()); @@ -204,13 +204,13 @@ benchAttributes [CVC4::PtrCloser<CVC4::Command>* cmd] * a corresponding command * @return a command corresponding to the attribute */ -benchAttribute [CVC4::PtrCloser<CVC4::Command>* smt_command] +benchAttribute [std::unique_ptr<CVC4::Command>* smt_command] @declarations { std::string name; BenchmarkStatus b_status; Expr expr; - CVC4::PtrCloser<CVC4::CommandSequence> command_seq; - CVC4::PtrCloser<CVC4::Command> declaration_command; + std::unique_ptr<CVC4::CommandSequence> command_seq; + std::unique_ptr<CVC4::Command> declaration_command; } : LOGIC_TOK identifier[name,CHECK_NONE,SYM_VARIABLE] { PARSER_STATE->preemptCommand(new SetBenchmarkLogicCommand(name)); @@ -494,7 +494,7 @@ attribute[std::string& s] { s = AntlrInput::tokenText($ATTR_IDENTIFIER); } ; -functionDeclaration[CVC4::PtrCloser<CVC4::Command>* smt_command] +functionDeclaration[std::unique_ptr<CVC4::Command>* smt_command] @declarations { std::string name; std::vector<Type> sorts; @@ -516,7 +516,7 @@ functionDeclaration[CVC4::PtrCloser<CVC4::Command>* smt_command] /** * Matches the declaration of a predicate and declares it */ -predicateDeclaration[CVC4::PtrCloser<CVC4::Command>* smt_command] +predicateDeclaration[std::unique_ptr<CVC4::Command>* smt_command] @declarations { std::string name; std::vector<Type> p_sorts; @@ -533,7 +533,7 @@ predicateDeclaration[CVC4::PtrCloser<CVC4::Command>* smt_command] } ; -sortDeclaration[CVC4::PtrCloser<CVC4::Command>* smt_command] +sortDeclaration[std::unique_ptr<CVC4::Command>* smt_command] @declarations { std::string name; } @@ -589,7 +589,7 @@ status[ CVC4::BenchmarkStatus& status ] * Matches an annotation, which is an attribute name, with an optional user * value. */ -annotation[CVC4::PtrCloser<CVC4::Command>* smt_command] +annotation[std::unique_ptr<CVC4::Command>* smt_command] @init { std::string key, value; std::vector<Expr> pats; diff --git a/src/parser/smt1/smt1.cpp b/src/parser/smt1/smt1.cpp index c8d1b774c..c4e670f6d 100644 --- a/src/parser/smt1/smt1.cpp +++ b/src/parser/smt1/smt1.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Christopher L. Conway, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -12,21 +12,17 @@ ** Definitions of SMT-LIB (v1) constants. **/ -#include <ext/hash_map> -namespace std { - using namespace __gnu_cxx; -} +#include "parser/smt1/smt1.h" #include "expr/type.h" #include "smt/command.h" #include "parser/parser.h" -#include "parser/smt1/smt1.h" namespace CVC4 { namespace parser { -std::hash_map<const std::string, Smt1::Logic, CVC4::StringHashFunction> Smt1::newLogicMap() { - std::hash_map<const std::string, Smt1::Logic, CVC4::StringHashFunction> logicMap; +std::unordered_map<std::string, Smt1::Logic> Smt1::newLogicMap() { + std::unordered_map<std::string, Smt1::Logic> logicMap; logicMap["AUFLIA"] = AUFLIA; logicMap["AUFLIRA"] = AUFLIRA; logicMap["AUFNIRA"] = AUFNIRA; @@ -68,7 +64,7 @@ std::hash_map<const std::string, Smt1::Logic, CVC4::StringHashFunction> Smt1::ne } Smt1::Logic Smt1::toLogic(const std::string& name) { - static std::hash_map<const std::string, Smt1::Logic, CVC4::StringHashFunction> logicMap = newLogicMap(); + static std::unordered_map<std::string, Smt1::Logic> logicMap = newLogicMap(); return logicMap[name]; } diff --git a/src/parser/smt1/smt1.h b/src/parser/smt1/smt1.h index 45de222ac..e9dbea1a9 100644 --- a/src/parser/smt1/smt1.h +++ b/src/parser/smt1/smt1.h @@ -2,9 +2,9 @@ /*! \file smt1.h ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,10 +17,9 @@ #ifndef __CVC4__PARSER__SMT1_H #define __CVC4__PARSER__SMT1_H -#include <ext/hash_map> -namespace std { using namespace __gnu_cxx; } +#include <string> +#include <unordered_map> -#include "util/hash.h" #include "parser/parser.h" namespace CVC4 { @@ -117,7 +116,7 @@ public: private: void addArithmeticOperators(); - static std::hash_map<const std::string, Logic, CVC4::StringHashFunction> newLogicMap(); + static std::unordered_map<std::string, Logic> newLogicMap(); };/* class Smt1 */ }/* CVC4::parser namespace */ diff --git a/src/parser/smt1/smt1_input.cpp b/src/parser/smt1/smt1_input.cpp index 69801e8b4..d7cc3686f 100644 --- a/src/parser/smt1/smt1_input.cpp +++ b/src/parser/smt1/smt1_input.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Christopher L. Conway, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/smt1/smt1_input.h b/src/parser/smt1/smt1_input.h index 0e719f519..c5a3d312e 100644 --- a/src/parser/smt1/smt1_input.h +++ b/src/parser/smt1/smt1_input.h @@ -2,9 +2,9 @@ /*! \file smt1_input.h ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/smt2/Makefile.am b/src/parser/smt2/Makefile.am index fece5e5e8..995e442e6 100644 --- a/src/parser/smt2/Makefile.am +++ b/src/parser/smt2/Makefile.am @@ -5,6 +5,7 @@ AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) $(WNO_PARENTH # Compile generated C files using C++ compiler AM_CFLAGS = $(AM_CXXFLAGS) +CFLAGS=$(CXXFLAGS) CC=$(CXX) ANTLR_OPTS = diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g index e693f1d57..c7156635d 100644 --- a/src/parser/smt2/Smt2.g +++ b/src/parser/smt2/Smt2.g @@ -2,9 +2,9 @@ /*! \file Smt2.g ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Christopher L. Conway + ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -31,10 +31,11 @@ options { @header { /** - ** This file is part of CVC4. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information. + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2016 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. **/ }/* @header */ @@ -84,7 +85,8 @@ using namespace CVC4::parser; // files. See the documentation in "parser/antlr_undefines.h" for more details. #include "parser/antlr_undefines.h" -#include "base/ptr_closer.h" +#include <memory> + #include "parser/parser.h" #include "parser/antlr_tracing.h" #include "smt/command.h" @@ -115,6 +117,7 @@ namespace CVC4 { #include <set> #include <sstream> #include <string> +#include <unordered_set> #include <vector> #include "base/output.h" @@ -148,7 +151,7 @@ using namespace CVC4::parser; #define MK_CONST EXPR_MANAGER->mkConst #define UNSUPPORTED PARSER_STATE->unimplementedFeature -static bool isClosed(const Expr& e, std::set<Expr>& free, std::hash_set<Expr, ExprHashFunction>& closedCache) { +static bool isClosed(const Expr& e, std::set<Expr>& free, std::unordered_set<Expr, ExprHashFunction>& closedCache) { if(closedCache.find(e) != closedCache.end()) { return true; } @@ -179,7 +182,7 @@ static bool isClosed(const Expr& e, std::set<Expr>& free, std::hash_set<Expr, Ex } static inline bool isClosed(const Expr& e, std::set<Expr>& free) { - std::hash_set<Expr, ExprHashFunction> cache; + std::unordered_set<Expr, ExprHashFunction> cache; return isClosed(e, free, cache); } @@ -204,7 +207,7 @@ parseExpr returns [CVC4::parser::smt2::myExpr expr] */ parseCommand returns [CVC4::Command* cmd_return = NULL] @declarations { - CVC4::PtrCloser<CVC4::Command> cmd; + std::unique_ptr<CVC4::Command> cmd; std::string name; } @after { @@ -240,7 +243,7 @@ parseCommand returns [CVC4::Command* cmd_return = NULL] */ parseSygus returns [CVC4::Command* cmd_return = NULL] @declarations { - CVC4::PtrCloser<CVC4::Command> cmd; + std::unique_ptr<CVC4::Command> cmd; std::string name; } @after { @@ -254,7 +257,7 @@ parseSygus returns [CVC4::Command* cmd_return = NULL] * Parse the internal portion of the command, ignoring the surrounding * parentheses. */ -command [CVC4::PtrCloser<CVC4::Command>* cmd] +command [std::unique_ptr<CVC4::Command>* cmd] @declarations { std::string name; std::vector<std::string> names; @@ -272,7 +275,7 @@ command [CVC4::PtrCloser<CVC4::Command>* cmd] } PARSER_STATE->setLogic(name); if( PARSER_STATE->sygus() ){ - cmd->reset(new SetBenchmarkLogicCommand("ALL")); + cmd->reset(new SetBenchmarkLogicCommand(PARSER_STATE->getLogic().getLogicString())); }else{ cmd->reset(new SetBenchmarkLogicCommand(name)); } @@ -454,7 +457,7 @@ command [CVC4::PtrCloser<CVC4::Command>* cmd] PARSER_STATE->pushUnsatCoreNameScope(); cmd->reset(new PushCommand()); } else { - CVC4::PtrCloser<CommandSequence> seq(new CommandSequence()); + std::unique_ptr<CommandSequence> seq(new CommandSequence()); do { PARSER_STATE->pushScope(); PARSER_STATE->pushUnsatCoreNameScope(); @@ -494,7 +497,7 @@ command [CVC4::PtrCloser<CVC4::Command>* cmd] PARSER_STATE->popScope(); cmd->reset(new PopCommand()); } else { - CVC4::PtrCloser<CommandSequence> seq(new CommandSequence()); + std::unique_ptr<CommandSequence> seq(new CommandSequence()); do { PARSER_STATE->popUnsatCoreNameScope(); PARSER_STATE->popScope(); @@ -553,7 +556,7 @@ command [CVC4::PtrCloser<CVC4::Command>* cmd] } ; -sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] +sygusCommand [std::unique_ptr<CVC4::Command>* cmd] @declarations { std::string name, fun; std::vector<std::string> names; @@ -564,7 +567,7 @@ sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] std::vector<Expr> sygus_vars; std::vector<std::pair<std::string, Type> > sortedVarNames; SExpr sexpr; - CVC4::PtrCloser<CVC4::CommandSequence> seq; + std::unique_ptr<CVC4::CommandSequence> seq; std::vector< std::vector< CVC4::SygusGTerm > > sgts; std::vector< CVC4::Datatype > datatypes; std::vector< std::vector<Expr> > ops; @@ -577,6 +580,7 @@ sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] std::map< CVC4::Type, CVC4::Type > sygus_to_builtin; std::map< CVC4::Type, CVC4::Expr > sygus_to_builtin_expr; int startIndex = -1; + Expr synth_fun; } : /* declare-var */ DECLARE_VAR_TOK { PARSER_STATE->checkThatLogicIsSet(); } @@ -600,7 +604,25 @@ sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] { PARSER_STATE->checkThatLogicIsSet(); } symbol[fun,CHECK_UNDECLARED,SYM_VARIABLE] LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK - { seq.reset(new CommandSequence()); + ( sortSymbol[range,CHECK_DECLARED] )? { + if( range.isNull() ){ + PARSER_STATE->parseError("Must supply return type for synth-fun."); + } + seq.reset(new CommandSequence()); + std::vector<Type> var_sorts; + for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i = + sortedVarNames.begin(), iend = sortedVarNames.end(); i != iend; + ++i) { + var_sorts.push_back( (*i).second ); + } + Debug("parser-sygus") << "Define synth fun : " << fun << std::endl; + Type synth_fun_type; + if( var_sorts.size()>0 ){ + synth_fun_type = EXPR_MANAGER->mkFunctionType(var_sorts, range); + }else{ + synth_fun_type = range; + } + synth_fun = PARSER_STATE->mkVar(fun, synth_fun_type); PARSER_STATE->pushScope(true); for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i = sortedVarNames.begin(), iend = sortedVarNames.end(); i != iend; @@ -615,11 +637,12 @@ sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] } terms.clear(); terms.push_back(bvl); - } - ( sortSymbol[range,CHECK_DECLARED] )? { - if( range.isNull() ){ - PARSER_STATE->parseError("Must supply return type for synth-fun."); - } + // associate this variable list with the synth fun + std::vector< Expr > attr_val_bvl; + attr_val_bvl.push_back( bvl ); + Command* cattr_bvl = new SetUserAttributeCommand("sygus-synth-fun-var-list", synth_fun, attr_val_bvl); + cattr_bvl->setMuted(true); + PARSER_STATE->preemptCommand(cattr_bvl); } ( LPAREN_TOK ( LPAREN_TOK @@ -663,18 +686,11 @@ sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] )+ RPAREN_TOK { read_syntax = true; } )? - { + { // the sygus sym type specifies the required grammar for synth_fun, expressed as a type + Type sygus_sym_type; if( !read_syntax ){ - //create the default grammar - Debug("parser-sygus") << "Make default grammar..." << std::endl; - PARSER_STATE->mkSygusDefaultGrammar( - range, terms[0], fun, datatypes, sorts, ops, sygus_vars, - startIndex); - //set start index - Debug("parser-sygus") << "Set start index " << startIndex << "..." - << std::endl; - PARSER_STATE->setSygusStartIndex(fun, startIndex, datatypes, sorts, - ops); + sygus_sym_type = range; + PARSER_STATE->popScope(); }else{ Debug("parser-sygus") << "--- Process " << sgts.size() << " sygus gterms..." << std::endl; @@ -707,57 +723,32 @@ sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] datatypes[i], ops[i], cnames[i], cargs[i], unresolved_gterm_sym[i], sygus_to_builtin ); } - PARSER_STATE->setSygusStartIndex(fun, startIndex, datatypes, sorts, - ops); - } - //only care about datatypes/sorts/ops past here - PARSER_STATE->popScope(); - Debug("parser-sygus") << "--- Make " << datatypes.size() - << " mutual datatypes..." << std::endl; - for( unsigned i=0; i<datatypes.size(); i++ ){ - Debug("parser-sygus") << " " << i << " : " << datatypes[i].getName() - << std::endl; - } - std::vector<DatatypeType> datatypeTypes = - PARSER_STATE->mkMutualDatatypeTypes(datatypes); - seq->addCommand(new DatatypeDeclarationCommand(datatypeTypes)); - std::map<DatatypeType, Expr> evals; - if( sorts[0]!=range ){ - PARSER_STATE->parseError(std::string("Bad return type in grammar for " - "SyGuS function ") + fun); - } - // make all the evals first, since they are mutually referential - for(size_t i = 0; i < datatypeTypes.size(); ++i) { - DatatypeType dtt = datatypeTypes[i]; - const Datatype& dt = dtt.getDatatype(); - Expr eval = dt.getSygusEvaluationFunc(); - Debug("parser-sygus") << "Make eval " << eval << " for " << dt.getName() - << std::endl; - evals.insert(std::make_pair(dtt, eval)); - if(i == 0) { - PARSER_STATE->addSygusFun(fun, eval); + PARSER_STATE->setSygusStartIndex(fun, startIndex, datatypes, sorts, ops); + //only care about datatypes/sorts/ops past here + PARSER_STATE->popScope(); + Debug("parser-sygus") << "--- Make " << datatypes.size() + << " mutual datatypes..." << std::endl; + for( unsigned i=0; i<datatypes.size(); i++ ){ + Debug("parser-sygus") << " " << i << " : " << datatypes[i].getName() << std::endl; } - } - // now go through and settle everything - for(size_t i = 0; i < datatypeTypes.size(); ++i) { - DatatypeType dtt = datatypeTypes[i]; - const Datatype& dt = dtt.getDatatype(); - Expr eval = evals[dtt]; - Debug("parser-sygus") << "Sygus : process grammar : " << dt - << std::endl; - for(size_t j = 0; j < dt.getNumConstructors(); ++j) { - Expr assertion = PARSER_STATE->getSygusAssertion( - datatypeTypes, ops, evals, terms, eval, dt, i, j ); - seq->addCommand(new AssertCommand(assertion)); + std::vector<DatatypeType> datatypeTypes = + PARSER_STATE->mkMutualDatatypeTypes(datatypes); + seq->addCommand(new DatatypeDeclarationCommand(datatypeTypes)); + if( sorts[0]!=range ){ + PARSER_STATE->parseError(std::string("Bad return type in grammar for " + "SyGuS function ") + fun); } + sygus_sym_type = datatypeTypes[0]; } + + // store a dummy variable which stands for second-order quantification, linked to synth fun by an attribute + PARSER_STATE->addSygusFunSymbol( sygus_sym_type, synth_fun ); cmd->reset(seq.release()); } | /* constraint */ CONSTRAINT_TOK { PARSER_STATE->checkThatLogicIsSet(); Debug("parser-sygus") << "Sygus : define sygus funs..." << std::endl; - PARSER_STATE->defineSygusFuns(); Debug("parser-sygus") << "Sygus : read constraint..." << std::endl; } term[expr, expr2] @@ -768,7 +759,6 @@ sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] | INV_CONSTRAINT_TOK { PARSER_STATE->checkThatLogicIsSet(); Debug("parser-sygus") << "Sygus : define sygus funs..." << std::endl; - PARSER_STATE->defineSygusFuns(); Debug("parser-sygus") << "Sygus : read inv-constraint..." << std::endl; } ( symbol[name,CHECK_NONE,SYM_VARIABLE] { @@ -795,9 +785,8 @@ sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] } //make relevant terms for( unsigned i=0; i<4; i++ ){ - Debug("parser-sygus") << "Make inv-constraint term #" << i << "..." - << std::endl; Expr op = terms[i]; + Debug("parser-sygus") << "Make inv-constraint term #" << i << " : " << op << "..." << std::endl; std::vector< Expr > children; children.push_back( op ); if( i==2 ){ @@ -805,13 +794,13 @@ sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] }else{ children.insert( children.end(), primed[0].begin(), primed[0].end() ); } - terms[i] = EXPR_MANAGER->mkExpr(kind::APPLY,children); + terms[i] = EXPR_MANAGER->mkExpr( i==0 ? kind::APPLY_UF : kind::APPLY,children); if( i==0 ){ std::vector< Expr > children2; children2.push_back( op ); children2.insert(children2.end(), primed[1].begin(), primed[1].end()); - terms.push_back( EXPR_MANAGER->mkExpr(kind::APPLY,children2) ); + terms.push_back( EXPR_MANAGER->mkExpr(kind::APPLY_UF,children2) ); } } //make constraints @@ -831,7 +820,7 @@ sygusCommand [CVC4::PtrCloser<CVC4::Command>* cmd] } | /* check-synth */ CHECK_SYNTH_TOK - { PARSER_STATE->checkThatLogicIsSet(); PARSER_STATE->defineSygusFuns(); } + { PARSER_STATE->checkThatLogicIsSet(); } { Expr sygusVar = EXPR_MANAGER->mkVar("sygus", EXPR_MANAGER->booleanType()); Expr inst_attr =EXPR_MANAGER->mkExpr(kind::INST_ATTRIBUTE, sygusVar); Expr sygusAttr = EXPR_MANAGER->mkExpr(kind::INST_PATTERN_LIST, inst_attr); @@ -899,12 +888,18 @@ sygusGTerm[CVC4::SygusGTerm& sgt, std::string& fun] k = CVC4::kind::BITVECTOR_UDIV_TOTAL; }else if( k==CVC4::kind::BITVECTOR_UREM ){ k = CVC4::kind::BITVECTOR_UREM_TOTAL; + }else if( k==CVC4::kind::DIVISION ){ + k = CVC4::kind::DIVISION_TOTAL; + }else if( k==CVC4::kind::INTS_DIVISION ){ + k = CVC4::kind::INTS_DIVISION_TOTAL; + }else if( k==CVC4::kind::INTS_MODULUS ){ + k = CVC4::kind::INTS_MODULUS_TOTAL; } sgt.d_name = kind::kindToString(k); sgt.d_gterm_type = SygusGTerm::gterm_op; sgt.d_expr = EXPR_MANAGER->operatorOf(k); } - | LET_TOK LPAREN_TOK { + | SYGUS_LET_TOK LPAREN_TOK { sgt.d_name = std::string("let"); sgt.d_gterm_type = SygusGTerm::gterm_let; PARSER_STATE->pushScope(true); @@ -951,6 +946,12 @@ sygusGTerm[CVC4::SygusGTerm& sgt, std::string& fun] k = CVC4::kind::BITVECTOR_UDIV_TOTAL; }else if( k==CVC4::kind::BITVECTOR_UREM ){ k = CVC4::kind::BITVECTOR_UREM_TOTAL; + }else if( k==CVC4::kind::DIVISION ){ + k = CVC4::kind::DIVISION_TOTAL; + }else if( k==CVC4::kind::INTS_DIVISION ){ + k = CVC4::kind::INTS_DIVISION_TOTAL; + }else if( k==CVC4::kind::INTS_MODULUS ){ + k = CVC4::kind::INTS_MODULUS_TOTAL; } sgt.d_name = kind::kindToString(k); sgt.d_gterm_type = SygusGTerm::gterm_op; @@ -1076,7 +1077,7 @@ sygusGTerm[CVC4::SygusGTerm& sgt, std::string& fun] ; // Separate this into its own rule (can be invoked by set-info or meta-info) -metaInfoInternal[CVC4::PtrCloser<CVC4::Command>* cmd] +metaInfoInternal[std::unique_ptr<CVC4::Command>* cmd] @declarations { std::string name; SExpr sexpr; @@ -1106,7 +1107,7 @@ metaInfoInternal[CVC4::PtrCloser<CVC4::Command>* cmd] } ; -setOptionInternal[CVC4::PtrCloser<CVC4::Command>* cmd] +setOptionInternal[std::unique_ptr<CVC4::Command>* cmd] @init { std::string name; SExpr sexpr; @@ -1123,7 +1124,7 @@ setOptionInternal[CVC4::PtrCloser<CVC4::Command>* cmd] } ; -smt25Command[CVC4::PtrCloser<CVC4::Command>* cmd] +smt25Command[std::unique_ptr<CVC4::Command>* cmd] @declarations { std::string name; std::string fname; @@ -1137,7 +1138,7 @@ smt25Command[CVC4::PtrCloser<CVC4::Command>* cmd] std::vector<Expr> funcs; std::vector<Expr> func_defs; Expr aexpr; - CVC4::PtrCloser<CVC4::CommandSequence> seq; + std::unique_ptr<CVC4::CommandSequence> seq; } /* meta-info */ : META_INFO_TOK metaInfoInternal[cmd] @@ -1331,7 +1332,7 @@ smt25Command[CVC4::PtrCloser<CVC4::Command>* cmd] // GET_UNSAT_ASSUMPTIONS ; -extendedCommand[CVC4::PtrCloser<CVC4::Command>* cmd] +extendedCommand[std::unique_ptr<CVC4::Command>* cmd] @declarations { std::vector<CVC4::Datatype> dts; Expr e, e2; @@ -1341,7 +1342,7 @@ extendedCommand[CVC4::PtrCloser<CVC4::Command>* cmd] std::vector<Expr> terms; std::vector<Type> sorts; std::vector<std::pair<std::string, Type> > sortedVarNames; - CVC4::PtrCloser<CVC4::CommandSequence> seq; + std::unique_ptr<CVC4::CommandSequence> seq; } /* Extended SMT-LIB set of commands syntax, not permitted in * --smtlib2 compliance mode. */ @@ -1496,7 +1497,7 @@ extendedCommand[CVC4::PtrCloser<CVC4::Command>* cmd] ; -datatypes_2_5_DefCommand[bool isCo, CVC4::PtrCloser<CVC4::Command>* cmd] +datatypes_2_5_DefCommand[bool isCo, std::unique_ptr<CVC4::Command>* cmd] @declarations { std::vector<CVC4::Datatype> dts; std::string name; @@ -1516,7 +1517,7 @@ datatypes_2_5_DefCommand[bool isCo, CVC4::PtrCloser<CVC4::Command>* cmd] } ; -datatypeDefCommand[bool isCo, CVC4::PtrCloser<CVC4::Command>* cmd] +datatypeDefCommand[bool isCo, std::unique_ptr<CVC4::Command>* cmd] @declarations { std::vector<CVC4::Datatype> dts; std::string name; @@ -1531,7 +1532,7 @@ datatypeDefCommand[bool isCo, CVC4::PtrCloser<CVC4::Command>* cmd] { cmd->reset(new DatatypeDeclarationCommand(PARSER_STATE->mkMutualDatatypeTypes(dts))); } ; -datatypesDefCommand[bool isCo, CVC4::PtrCloser<CVC4::Command>* cmd] +datatypesDefCommand[bool isCo, std::unique_ptr<CVC4::Command>* cmd] @declarations { std::vector<CVC4::Datatype> dts; std::string name; @@ -1594,7 +1595,7 @@ datatypesDefCommand[bool isCo, CVC4::PtrCloser<CVC4::Command>* cmd] } ; -rewriterulesCommand[CVC4::PtrCloser<CVC4::Command>* cmd] +rewriterulesCommand[std::unique_ptr<CVC4::Command>* cmd] @declarations { std::vector<std::pair<std::string, Type> > sortedVarNames; std::vector<Expr> args, guards, heads, triggers; @@ -1798,12 +1799,11 @@ term[CVC4::Expr& expr, CVC4::Expr& expr2] Expr attexpr; std::vector<Expr> patexprs; std::vector<Expr> patconds; - std::hash_set<std::string, StringHashFunction> names; + std::unordered_set<std::string> names; std::vector< std::pair<std::string, Expr> > binders; Type type; std::string s; bool isBuiltinOperator = false; - bool readLetSort = false; int match_vindex = -1; std::vector<Type> match_ptypes; } @@ -2005,27 +2005,41 @@ term[CVC4::Expr& expr, CVC4::Expr& expr2] expr = MK_CONST( ::CVC4::ArrayStoreAll(type, f) ); } ) - | /* a let binding */ - LPAREN_TOK LET_TOK LPAREN_TOK - { PARSER_STATE->pushScope(true); } - ( LPAREN_TOK symbol[name,CHECK_NONE,SYM_VARIABLE] - (term[expr, f2] | sortSymbol[type,CHECK_DECLARED] - { readLetSort = true; } term[expr, f2] - ) - RPAREN_TOK - // this is a parallel let, so we have to save up all the contributions - // of the let and define them only later on - { if( !PARSER_STATE->sygus() && readLetSort ){ - PARSER_STATE->parseError("Bad syntax for let term."); - }else if(names.count(name) == 1) { - std::stringstream ss; - ss << "warning: symbol `" << name << "' bound multiple times by let;" - << " the last binding will be used, shadowing earlier ones"; - PARSER_STATE->warning(ss.str()); - } else { - names.insert(name); - } - binders.push_back(std::make_pair(name, expr)); } )+ + | /* a let or sygus let binding */ + LPAREN_TOK ( + LET_TOK LPAREN_TOK + { PARSER_STATE->pushScope(true); } + ( LPAREN_TOK symbol[name,CHECK_NONE,SYM_VARIABLE] + term[expr, f2] + RPAREN_TOK + // this is a parallel let, so we have to save up all the contributions + // of the let and define them only later on + { if(names.count(name) == 1) { + std::stringstream ss; + ss << "warning: symbol `" << name << "' bound multiple times by let;" + << " the last binding will be used, shadowing earlier ones"; + PARSER_STATE->warning(ss.str()); + } else { + names.insert(name); + } + binders.push_back(std::make_pair(name, expr)); } )+ | + SYGUS_LET_TOK LPAREN_TOK + { PARSER_STATE->pushScope(true); } + ( LPAREN_TOK symbol[name,CHECK_NONE,SYM_VARIABLE] + sortSymbol[type,CHECK_DECLARED] + term[expr, f2] + RPAREN_TOK + // this is a parallel let, so we have to save up all the contributions + // of the let and define them only later on + { if(names.count(name) == 1) { + std::stringstream ss; + ss << "warning: symbol `" << name << "' bound multiple times by let;" + << " the last binding will be used, shadowing earlier ones"; + PARSER_STATE->warning(ss.str()); + } else { + names.insert(name); + } + binders.push_back(std::make_pair(name, expr)); } )+ ) { // now implement these bindings for(std::vector< std::pair<std::string, Expr> >::iterator i = binders.begin(); i != binders.end(); ++i) { @@ -2083,6 +2097,7 @@ term[CVC4::Expr& expr, CVC4::Expr& expr2] if( args.size()!=dtc.getNumArgs() ){ PARSER_STATE->parseError("Bad number of arguments for application of constructor in pattern."); } + //FIXME: make MATCH a kind and make this a rewrite // build a lambda std::vector<Expr> largs; largs.push_back( MK_EXPR( CVC4::kind::BOUND_VAR_LIST, args ) ); @@ -2091,7 +2106,8 @@ term[CVC4::Expr& expr, CVC4::Expr& expr2] aargs.push_back( MK_EXPR( CVC4::kind::LAMBDA, largs ) ); for( unsigned i=0; i<dtc.getNumArgs(); i++ ){ //can apply total version since we will be guarded by ITE condition - aargs.push_back( MK_EXPR( CVC4::kind::APPLY_SELECTOR_TOTAL, dtc[i].getSelector(), expr ) ); + // however, we need to apply partial version since we don't have the internal selector available + aargs.push_back( MK_EXPR( CVC4::kind::APPLY_SELECTOR, dtc[i].getSelector(), expr ) ); } patexprs.push_back( MK_EXPR( CVC4::kind::APPLY, aargs ) ); patconds.push_back( MK_EXPR( CVC4::kind::APPLY_TESTER, dtc.getTester(), expr ) ); @@ -3002,7 +3018,8 @@ EXIT_TOK : 'exit'; RESET_TOK : { PARSER_STATE->v2_5(false) }? 'reset'; RESET_ASSERTIONS_TOK : 'reset-assertions'; ITE_TOK : 'ite'; -LET_TOK : 'let'; +LET_TOK : { !PARSER_STATE->sygus() }? 'let'; +SYGUS_LET_TOK : { PARSER_STATE->sygus() }? 'let'; ATTRIBUTE_TOK : '!'; LPAREN_TOK : '('; RPAREN_TOK : ')'; diff --git a/src/parser/smt2/smt2.cpp b/src/parser/smt2/smt2.cpp index ebe730e29..674dbe49d 100644 --- a/src/parser/smt2/smt2.cpp +++ b/src/parser/smt2/smt2.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Kshitij Bansal, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -33,8 +33,7 @@ namespace parser { Smt2::Smt2(ExprManager* exprManager, Input* input, bool strictMode, bool parseOnly) : Parser(exprManager,input,strictMode,parseOnly), - d_logicSet(false), - d_nextSygusFun(0) { + d_logicSet(false) { d_unsatCoreNames.push(std::map<Expr, std::string>()); if( !strictModeEnabled() ) { addTheory(Smt2::THEORY_CORE); @@ -54,6 +53,12 @@ void Smt2::addArithmeticOperators() { Parser::addOperator(kind::LEQ); Parser::addOperator(kind::GT); Parser::addOperator(kind::GEQ); + + addOperator(kind::POW, "^"); + addOperator(kind::EXPONENTIAL, "exp"); + addOperator(kind::SINE, "sin"); + addOperator(kind::COSINE, "cos"); + addOperator(kind::TANGENT, "tan"); } void Smt2::addBitvectorOperators() { @@ -354,22 +359,23 @@ void Smt2::resetAssertions() { void Smt2::setLogic(std::string name) { if(sygus()) { + // sygus by default requires UF, datatypes, and LIA if(name == "Arrays") { - name = "AUF"; + name = "AUFDTLIA"; } else if(name == "Reals") { - name = "UFLRA"; + name = "UFDTLIRA"; } else if(name == "LIA") { - name = "UFLIA"; + name = "UFDTLIA"; } else if(name == "LRA") { - name = "UFLRA"; + name = "UFDTLIRA"; } else if(name == "LIRA") { - name = "UFLIRA"; + name = "UFDTLIRA"; } else if(name == "BV") { - name = "UFBV"; + name = "UFDTBVLIA"; } else if(name == "SLIA") { - name = "UFSLIA"; + name = "UFDTSLIA"; } else if(name == "SAT") { - name = "UF"; + name = "UFDTLIA"; } else if(name == "ALL" || name == "ALL_SUPPORTED") { //no change } else { @@ -452,16 +458,12 @@ void Smt2::checkThatLogicIsSet() { if(strictModeEnabled()) { parseError("set-logic must appear before this point."); } else { - if(sygus()) { - setLogic("LIA"); - } else { - warning("No set-logic command was given before this point."); - warning("CVC4 will make all theories available."); - warning("Consider setting a stricter logic for (likely) better performance."); - warning("To suppress this warning in the future use (set-logic ALL)."); + warning("No set-logic command was given before this point."); + warning("CVC4 will make all theories available."); + warning("Consider setting a stricter logic for (likely) better performance."); + warning("To suppress this warning in the future use (set-logic ALL)."); - setLogic("ALL"); - } + setLogic("ALL"); Command* c = new SetBenchmarkLogicCommand("ALL"); c->setMuted(true); @@ -544,246 +546,6 @@ Expr Smt2::mkSygusVar(const std::string& name, const Type& type, bool isPrimed) return e; } -void collectSygusGrammarTypesFor( Type range, std::vector< Type >& types, std::map< Type, std::vector< DatatypeConstructorArg > >& sels ){ - if( !range.isBoolean() ){ - if( std::find( types.begin(), types.end(), range )==types.end() ){ - Debug("parser-sygus") << "...will make grammar for " << range << std::endl; - types.push_back( range ); - if( range.isDatatype() ){ - const Datatype& dt = ((DatatypeType)range).getDatatype(); - for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ - for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){ - Type crange = ((SelectorType)dt[i][j].getType()).getRangeType(); - sels[crange].push_back( dt[i][j] ); - collectSygusGrammarTypesFor( crange, types, sels ); - } - } - } - } - } -} - -void Smt2::mkSygusDefaultGrammar( const Type& range, Expr& bvl, const std::string& fun, std::vector<CVC4::Datatype>& datatypes, - std::vector<Type>& sorts, std::vector< std::vector<Expr> >& ops, std::vector<Expr> sygus_vars, int& startIndex ) { - - //if( !range.isBoolean() && !range.isInteger() && !range.isBitVector() && !range.isDatatype() ){ - // parseError("No default grammar for type."); - //} - startIndex = -1; - Debug("parser-sygus") << "Construct default grammar for " << fun << " " << range << std::endl; - std::map< CVC4::Type, CVC4::Type > sygus_to_builtin; - - std::vector< Type > types; - std::map< Type, std::vector< DatatypeConstructorArg > > sels; - //types for each of the variables - for( unsigned i=0; i<sygus_vars.size(); i++ ){ - collectSygusGrammarTypesFor( sygus_vars[i].getType(), types, sels ); - } - //types connected to range - collectSygusGrammarTypesFor( range, types, sels ); - - //name of boolean sort - std::stringstream ssb; - ssb << fun << "_Bool"; - std::string dbname = ssb.str(); - Type unres_bt = mkUnresolvedType(ssb.str()); - - std::vector< Type > unres_types; - std::map< Type, Type > type_to_unres; - for( unsigned i=0; i<types.size(); i++ ){ - std::stringstream ss; - ss << fun << "_" << types[i]; - std::string dname = ss.str(); - datatypes.push_back(Datatype(dname)); - ops.push_back(std::vector<Expr>()); - //make unresolved type - Type unres_t = mkUnresolvedType(dname); - unres_types.push_back(unres_t); - type_to_unres[types[i]] = unres_t; - sygus_to_builtin[unres_t] = types[i]; - } - for( unsigned i=0; i<types.size(); i++ ){ - Debug("parser-sygus") << "Make grammar for " << types[i] << " " << unres_types[i] << std::endl; - std::vector<std::string> cnames; - std::vector<std::vector<CVC4::Type> > cargs; - std::vector<std::string> unresolved_gterm_sym; - Type unres_t = unres_types[i]; - //add variables - for( unsigned j=0; j<sygus_vars.size(); j++ ){ - if( sygus_vars[j].getType()==types[i] ){ - std::stringstream ss; - ss << sygus_vars[j]; - Debug("parser-sygus") << "...add for variable " << ss.str() << std::endl; - ops[i].push_back( sygus_vars[j] ); - cnames.push_back( ss.str() ); - cargs.push_back( std::vector< CVC4::Type >() ); - } - } - //add constants - std::vector< Expr > consts; - mkSygusConstantsForType( types[i], consts ); - for( unsigned j=0; j<consts.size(); j++ ){ - std::stringstream ss; - ss << consts[j]; - Debug("parser-sygus") << "...add for constant " << ss.str() << std::endl; - ops[i].push_back( consts[j] ); - cnames.push_back( ss.str() ); - cargs.push_back( std::vector< CVC4::Type >() ); - } - //ITE - CVC4::Kind k = kind::ITE; - Debug("parser-sygus") << "...add for " << k << std::endl; - ops[i].push_back(getExprManager()->operatorOf(k)); - cnames.push_back( kind::kindToString(k) ); - cargs.push_back( std::vector< CVC4::Type >() ); - cargs.back().push_back(unres_bt); - cargs.back().push_back(unres_t); - cargs.back().push_back(unres_t); - - if( types[i].isInteger() ){ - for( unsigned j=0; j<2; j++ ){ - CVC4::Kind k = j==0 ? kind::PLUS : kind::MINUS; - Debug("parser-sygus") << "...add for " << k << std::endl; - ops[i].push_back(getExprManager()->operatorOf(k)); - cnames.push_back(kind::kindToString(k)); - cargs.push_back( std::vector< CVC4::Type >() ); - cargs.back().push_back(unres_t); - cargs.back().push_back(unres_t); - } - }else if( types[i].isDatatype() ){ - Debug("parser-sygus") << "...add for constructors" << std::endl; - const Datatype& dt = ((DatatypeType)types[i]).getDatatype(); - for( unsigned k=0; k<dt.getNumConstructors(); k++ ){ - Debug("parser-sygus") << "...for " << dt[k].getName() << std::endl; - ops[i].push_back( dt[k].getConstructor() ); - cnames.push_back( dt[k].getName() ); - cargs.push_back( std::vector< CVC4::Type >() ); - for( unsigned j=0; j<dt[k].getNumArgs(); j++ ){ - Type crange = ((SelectorType)dt[k][j].getType()).getRangeType(); - //Assert( type_to_unres.find(crange)!=type_to_unres.end() ); - cargs.back().push_back( type_to_unres[crange] ); - } - } - }else{ - std::stringstream sserr; - sserr << "No implementation for default Sygus grammar of type " << types[i] << std::endl; - warning(sserr.str()); - } - //add for all selectors to this type - if( !sels[types[i]].empty() ){ - Debug("parser-sygus") << "...add for selectors" << std::endl; - for( unsigned j=0; j<sels[types[i]].size(); j++ ){ - Debug("parser-sygus") << "...for " << sels[types[i]][j].getName() << std::endl; - Type arg_type = ((SelectorType)sels[types[i]][j].getType()).getDomain(); - ops[i].push_back( sels[types[i]][j].getSelector() ); - cnames.push_back( sels[types[i]][j].getName() ); - cargs.push_back( std::vector< CVC4::Type >() ); - //Assert( type_to_unres.find(arg_type)!=type_to_unres.end() ); - cargs.back().push_back( type_to_unres[arg_type] ); - } - } - Debug("parser-sygus") << "...make datatype " << datatypes.back() << std::endl; - datatypes[i].setSygus( types[i], bvl, true, true ); - mkSygusDatatype( datatypes[i], ops[i], cnames, cargs, unresolved_gterm_sym, sygus_to_builtin ); - sorts.push_back( types[i] ); - //set start index if applicable - if( types[i]==range ){ - startIndex = i; - } - } - - //make Boolean type - Type btype = getExprManager()->booleanType(); - datatypes.push_back(Datatype(dbname)); - ops.push_back(std::vector<Expr>()); - std::vector<std::string> cnames; - std::vector<std::vector<CVC4::Type> > cargs; - std::vector<std::string> unresolved_gterm_sym; - Debug("parser-sygus") << "Make grammar for " << btype << " " << datatypes.back() << std::endl; - //add variables - for( unsigned i=0; i<sygus_vars.size(); i++ ){ - if( sygus_vars[i].getType().isBoolean() ){ - std::stringstream ss; - ss << sygus_vars[i]; - Debug("parser-sygus") << "...add for variable " << ss.str() << std::endl; - ops.back().push_back( sygus_vars[i] ); - cnames.push_back( ss.str() ); - cargs.push_back( std::vector< CVC4::Type >() ); - } - } - //add constants if no variables and no connected types - if( ops.back().empty() && types.empty() ){ - std::vector< Expr > consts; - mkSygusConstantsForType( btype, consts ); - for( unsigned j=0; j<consts.size(); j++ ){ - std::stringstream ss; - ss << consts[j]; - Debug("parser-sygus") << "...add for constant " << ss.str() << std::endl; - ops.back().push_back( consts[j] ); - cnames.push_back( ss.str() ); - cargs.push_back( std::vector< CVC4::Type >() ); - } - } - //add operators - for( unsigned i=0; i<3; i++ ){ - CVC4::Kind k = i==0 ? kind::NOT : ( i==1 ? kind::AND : kind::OR ); - Debug("parser-sygus") << "...add for " << k << std::endl; - ops.back().push_back(getExprManager()->operatorOf(k)); - cnames.push_back(kind::kindToString(k)); - cargs.push_back( std::vector< CVC4::Type >() ); - if( k==kind::NOT ){ - cargs.back().push_back(unres_bt); - }else if( k==kind::AND || k==kind::OR ){ - cargs.back().push_back(unres_bt); - cargs.back().push_back(unres_bt); - } - } - //add predicates for types - for( unsigned i=0; i<types.size(); i++ ){ - Debug("parser-sygus") << "...add predicates for " << types[i] << std::endl; - //add equality per type - CVC4::Kind k = kind::EQUAL; - Debug("parser-sygus") << "...add for " << k << std::endl; - ops.back().push_back(getExprManager()->operatorOf(k)); - std::stringstream ss; - ss << kind::kindToString(k) << "_" << types[i]; - cnames.push_back(ss.str()); - cargs.push_back( std::vector< CVC4::Type >() ); - cargs.back().push_back(unres_types[i]); - cargs.back().push_back(unres_types[i]); - //type specific predicates - if( types[i].isInteger() ){ - CVC4::Kind k = kind::LEQ; - Debug("parser-sygus") << "...add for " << k << std::endl; - ops.back().push_back(getExprManager()->operatorOf(k)); - cnames.push_back(kind::kindToString(k)); - cargs.push_back( std::vector< CVC4::Type >() ); - cargs.back().push_back(unres_types[i]); - cargs.back().push_back(unres_types[i]); - }else if( types[i].isDatatype() ){ - //add for testers - Debug("parser-sygus") << "...add for testers" << std::endl; - const Datatype& dt = ((DatatypeType)types[i]).getDatatype(); - for( unsigned k=0; k<dt.getNumConstructors(); k++ ){ - Debug("parser-sygus") << "...for " << dt[k].getTesterName() << std::endl; - ops.back().push_back(dt[k].getTester()); - cnames.push_back(dt[k].getTesterName()); - cargs.push_back( std::vector< CVC4::Type >() ); - cargs.back().push_back(unres_types[i]); - } - } - } - if( range==btype ){ - startIndex = sorts.size(); - } - Debug("parser-sygus") << "...make datatype " << datatypes.back() << std::endl; - datatypes.back().setSygus( btype, bvl, true, true ); - mkSygusDatatype( datatypes.back(), ops.back(), cnames, cargs, unresolved_gterm_sym, sygus_to_builtin ); - sorts.push_back( btype ); - - Debug("parser-sygus") << "...finished make default grammar for " << fun << " " << range << std::endl; -} - void Smt2::mkSygusConstantsForType( const Type& type, std::vector<CVC4::Expr>& ops ) { if( type.isInteger() ){ ops.push_back(getExprManager()->mkConst(Rational(0))); @@ -1155,77 +917,22 @@ void Smt2::setSygusStartIndex( std::string& fun, int startIndex, } } -void Smt2::defineSygusFuns() { - // only define each one once - while(d_nextSygusFun < d_sygusFuns.size()) { - std::pair<std::string, Expr> p = d_sygusFuns[d_nextSygusFun]; - std::string fun = p.first; - Debug("parser-sygus") << "Sygus : define fun " << fun << std::endl; - Expr eval = p.second; - FunctionType evalType = eval.getType(); - std::vector<Type> argTypes = evalType.getArgTypes(); - Type rangeType = evalType.getRangeType(); - Debug("parser-sygus") << "...eval type : " << evalType << ", #args=" << argTypes.size() << std::endl; - - // first make the function type - std::vector<Expr> sygusVars; - std::vector<Type> funType; - for(size_t j = 1; j < argTypes.size(); ++j) { - funType.push_back(argTypes[j]); - std::stringstream ss; - ss << fun << "_v_" << j; - sygusVars.push_back(getExprManager()->mkBoundVar(ss.str(), argTypes[j])); - } - Type funt; - if( !funType.empty() ){ - funt = getExprManager()->mkFunctionType(funType, rangeType); - Debug("parser-sygus") << "...eval function type : " << funt << std::endl; - - // copy the bound vars - /* - std::vector<Expr> sygusVars; - //std::vector<Type> types; - for(size_t i = 0; i < d_sygusVars.size(); ++i) { - std::stringstream ss; - ss << d_sygusVars[i]; - Type type = d_sygusVars[i].getType(); - sygusVars.push_back(getExprManager()->mkBoundVar(ss.str(), type)); - //types.push_back(type); - } - Debug("parser-sygus") << "...made vars, #vars=" << sygusVars.size() << std::endl; - */ - - //Type t = getExprManager()->mkFunctionType(types, rangeType); - //Debug("parser-sygus") << "...function type : " << t << std::endl; - }else{ - funt = rangeType; - } - Expr lambda = mkFunction(fun, funt, ExprManager::VAR_FLAG_DEFINED); - Debug("parser-sygus") << "...made function : " << lambda << std::endl; - std::vector<Expr> applyv; - Expr funbv = getExprManager()->mkBoundVar(std::string("f") + fun, argTypes[0]); - d_sygusFunSymbols.push_back(funbv); - applyv.push_back(eval); - applyv.push_back(funbv); - for(size_t i = 0; i < sygusVars.size(); ++i) { - applyv.push_back(sygusVars[i]); - } - Expr apply = getExprManager()->mkExpr(kind::APPLY_UF, applyv); - Debug("parser-sygus") << "...made apply " << apply << std::endl; - Debug("parser-sygus") << "--> Define " << fun << " as " << lambda << " " << apply << std::endl; - Command* cmd = new DefineFunctionCommand(fun, lambda, sygusVars, apply); - preemptCommand(cmd); - - ++d_nextSygusFun; - } -} - void Smt2::mkSygusDatatype( CVC4::Datatype& dt, std::vector<CVC4::Expr>& ops, std::vector<std::string>& cnames, std::vector< std::vector< CVC4::Type > >& cargs, std::vector<std::string>& unresolved_gterm_sym, std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin ) { Debug("parser-sygus") << "Making sygus datatype " << dt.getName() << std::endl; Debug("parser-sygus") << " add constructors..." << std::endl; + std::vector<std::string> df_name; + std::vector<CVC4::Expr> df_op; + std::vector< std::vector<Expr> > df_let_args; + std::vector< Expr > df_let_body; + //dt.mkSygusConstructors( ops, cnames, cargs, sygus_to_builtin, + // d_sygus_let_func_to_vars, d_sygus_let_func_to_body, d_sygus_let_func_to_num_input_vars, + // df_name, df_op, df_let_args, df_let_body ); + + Debug("parser-sygus") << "SMT2 sygus parser : Making constructors for sygus datatype " << dt.getName() << std::endl; + Debug("parser-sygus") << " add constructors..." << std::endl; for( int i=0; i<(int)cnames.size(); i++ ){ bool is_dup = false; bool is_dup_op = false; @@ -1286,9 +993,15 @@ void Smt2::mkSygusDatatype( CVC4::Datatype& dt, std::vector<CVC4::Expr>& ops, //replace operator and name ops[i] = mkFunction(ss.str(), ft, ExprManager::VAR_FLAG_DEFINED); cnames[i] = ss.str(); - d_sygus_defined_funs.push_back( ops[i] ); - preemptCommand( new DefineFunctionCommand(ss.str(), ops[i], let_args, let_body) ); - addSygusDatatypeConstructor( dt, ops[i], cnames[i], cargs[i], let_body, let_args, 0 ); + // indicate we need a define function + df_name.push_back( ss.str() ); + df_op.push_back( ops[i] ); + df_let_args.push_back( let_args ); + df_let_body.push_back( let_body ); + + //d_sygus_defined_funs.push_back( ops[i] ); + //preemptCommand( new DefineFunctionCommand(ss.str(), ops[i], let_args, let_body) ); + dt.addSygusConstructor( ops[i], cnames[i], cargs[i], let_body, let_args, 0 ); }else{ std::map< CVC4::Expr, CVC4::Expr >::iterator it = d_sygus_let_func_to_body.find( ops[i] ); if( it!=d_sygus_let_func_to_body.end() ){ @@ -1296,9 +1009,10 @@ void Smt2::mkSygusDatatype( CVC4::Datatype& dt, std::vector<CVC4::Expr>& ops, let_args.insert( let_args.end(), d_sygus_let_func_to_vars[ops[i]].begin(), d_sygus_let_func_to_vars[ops[i]].end() ); let_num_input_args = d_sygus_let_func_to_num_input_vars[ops[i]]; } - addSygusDatatypeConstructor( dt, ops[i], cnames[i], cargs[i], let_body, let_args, let_num_input_args ); + dt.addSygusConstructor( ops[i], cnames[i], cargs[i], let_body, let_args, let_num_input_args ); } } + Debug("parser-sygus") << " add constructors for unresolved symbols..." << std::endl; if( !unresolved_gterm_sym.empty() ){ std::vector< Type > types; @@ -1323,12 +1037,18 @@ void Smt2::mkSygusDatatype( CVC4::Datatype& dt, std::vector<CVC4::Expr>& ops, std::stringstream ssid; ssid << unresolved_gterm_sym[i] << "_id"; Expr id_op = mkFunction(ss.str(), ft, ExprManager::VAR_FLAG_DEFINED); - d_sygus_defined_funs.push_back( id_op ); - preemptCommand( new DefineFunctionCommand(ssid.str(), id_op, let_args, let_body) ); + // indicate we need a define function + df_name.push_back( ssid.str() ); + df_op.push_back( id_op ); + df_let_args.push_back( let_args ); + df_let_body.push_back( let_body ); + + //d_sygus_defined_funs.push_back( id_op ); + //preemptCommand( new DefineFunctionCommand(ssid.str(), id_op, let_args, let_body) ); //make the sygus argument list std::vector< Type > id_carg; id_carg.push_back( t ); - addSygusDatatypeConstructor( dt, id_op, unresolved_gterm_sym[i], id_carg, let_body, let_args, 0 ); + dt.addSygusConstructor( id_op, unresolved_gterm_sym[i], id_carg, let_body, let_args, 0 ); //add to operators ops.push_back( id_op ); } @@ -1337,187 +1057,12 @@ void Smt2::mkSygusDatatype( CVC4::Datatype& dt, std::vector<CVC4::Expr>& ops, } } } - -} - -void Smt2::addSygusDatatypeConstructor( CVC4::Datatype& dt, CVC4::Expr op, std::string& cname, std::vector< CVC4::Type >& cargs, - CVC4::Expr& let_body, std::vector< CVC4::Expr >& let_args, unsigned let_num_input_args ) { - Debug("parser-sygus") << "--> Add constructor " << cname << " to " << dt.getName() << std::endl; - if( !let_body.isNull() ){ - Debug("parser-sygus") << " let body = " << let_body << ", args = " << let_args.size() << "," << let_num_input_args << std::endl; - //TODO : remove arguments not occurring in body - //if this is a self identity function, ignore - if( let_args.size()==0 && let_args[0]==let_body ){ - Debug("parser-sygus") << " identity function " << cargs[0] << " to " << dt.getName() << std::endl; - //TODO - } - } - std::string name = dt.getName() + "_" + cname; - std::string testerId("is-"); - testerId.append(name); - checkDeclaration(name, CHECK_UNDECLARED, SYM_VARIABLE); - checkDeclaration(testerId, CHECK_UNDECLARED, SYM_VARIABLE); - CVC4::DatatypeConstructor c(name, testerId ); - c.setSygus( op, let_body, let_args, let_num_input_args ); - for( unsigned j=0; j<cargs.size(); j++ ){ - Debug("parser-sygus-debug") << " arg " << j << " : " << cargs[j] << std::endl; - std::stringstream sname; - sname << name << "_" << j; - c.addArg(sname.str(), cargs[j]); - } - dt.addConstructor(c); -} - - -// i is index in datatypes/ops -// j is index is datatype -Expr Smt2::getSygusAssertion( std::vector<DatatypeType>& datatypeTypes, std::vector< std::vector<Expr> >& ops, - std::map<DatatypeType, Expr>& evals, std::vector<Expr>& terms, - Expr eval, const Datatype& dt, size_t i, size_t j ) { - const DatatypeConstructor& ctor = dt[j]; - Debug("parser-sygus") << "Sygus : process constructor " << j << " : " << dt[j] << std::endl; - std::vector<Expr> bvs, extraArgs; - for(size_t k = 0; k < ctor.getNumArgs(); ++k) { - std::string vname = "v_" + ctor[k].getName(); - Expr bv = getExprManager()->mkBoundVar(vname, SelectorType(ctor[k].getType()).getRangeType()); - bvs.push_back(bv); - extraArgs.push_back(bv); - } - if( !terms[0].isNull() ){ - bvs.insert(bvs.end(), terms[0].begin(), terms[0].end()); - } - Expr bvl; - if( !bvs.empty() ){ - bvl = getExprManager()->mkExpr(kind::BOUND_VAR_LIST, bvs); - } - Debug("parser-sygus") << "...made bv list " << bvl << std::endl; - std::vector<Expr> patv; - patv.push_back(eval); - std::vector<Expr> applyv; - applyv.push_back(ctor.getConstructor()); - applyv.insert(applyv.end(), extraArgs.begin(), extraArgs.end()); - for(size_t k = 0; k < applyv.size(); ++k) { - } - Expr cpatv = getExprManager()->mkExpr(kind::APPLY_CONSTRUCTOR, applyv); - Debug("parser-sygus") << "...made eval ctor apply " << cpatv << std::endl; - patv.push_back(cpatv); - if( !terms[0].isNull() ){ - patv.insert(patv.end(), terms[0].begin(), terms[0].end()); - } - Expr evalApply = getExprManager()->mkExpr(kind::APPLY_UF, patv); - Debug("parser-sygus") << "...made eval apply " << evalApply << std::endl; - std::vector<Expr> builtApply; - for(size_t k = 0; k < extraArgs.size(); ++k) { - std::vector<Expr> patvb; - patvb.push_back(evals[DatatypeType(extraArgs[k].getType())]); - patvb.push_back(extraArgs[k]); - if( !terms[0].isNull() ){ - patvb.insert(patvb.end(), terms[0].begin(), terms[0].end()); - } - Debug("parser-sygus-debug") << "...add to built apply " << evals[DatatypeType(extraArgs[k].getType())] << " " << extraArgs[k] << " " << extraArgs[k].getType() << std::endl; - builtApply.push_back(getExprManager()->mkExpr(kind::APPLY_UF, patvb)); - Debug("parser-sygus-debug") << "...added " << builtApply.back() << std::endl; - } - for(size_t k = 0; k < builtApply.size(); ++k) { - } - Expr builtTerm; - Debug("parser-sygus") << "...operator is : " << ops[i][j] << ", type = " << ops[i][j].getType() << ", kind = " << ops[i][j].getKind() << ", is defined = " << isDefinedFunction( ops[i][j] ) << std::endl; - if( ops[i][j].getKind() != kind::BUILTIN ){ - Kind ok = kind::UNDEFINED_KIND; - if( isDefinedFunction( ops[i][j] ) || std::find( d_sygus_defined_funs.begin(), d_sygus_defined_funs.end(), ops[i][j] )!=d_sygus_defined_funs.end() ){ - ok = kind::APPLY; - }else{ - Type t = ops[i][j].getType(); - if( t.isConstructor() ){ - ok = kind::APPLY_CONSTRUCTOR; - }else if( t.isSelector() ){ - ok = kind::APPLY_SELECTOR; - }else if( t.isTester() ){ - ok = kind::APPLY_TESTER; - }else{ - ok = getExprManager()->operatorToKind( ops[i][j] ); - } - } - Debug("parser-sygus") << "...processed operator kind : " << ok << std::endl; - if( ok!=kind::UNDEFINED_KIND ){ - builtTerm = getExprManager()->mkExpr(ok, ops[i][j], builtApply); - }else{ - builtTerm = ops[i][j]; - } - }else{ - if( !builtApply.empty() ){ - builtTerm = getExprManager()->mkExpr(ops[i][j], builtApply); - }else{ - builtTerm = ops[i][j]; - } - } - Debug("parser-sygus") << "...made built term " << builtTerm << std::endl; - Expr assertion = getExprManager()->mkExpr(kind::EQUAL, evalApply, builtTerm); - if( !bvl.isNull() ){ - Expr pattern = getExprManager()->mkExpr(kind::INST_PATTERN, evalApply); - pattern = getExprManager()->mkExpr(kind::INST_PATTERN_LIST, pattern); - assertion = getExprManager()->mkExpr(kind::FORALL, bvl, assertion, pattern); - } - Debug("parser-sygus") << "...made assertion " << assertion << std::endl; - - //linearize multiplication if possible - if( builtTerm.getKind()==kind::MULT ){ - for(size_t k = 0; k < ctor.getNumArgs(); ++k) { - Type at = SelectorType(ctor[k].getType()).getRangeType(); - if( at.isDatatype() ){ - DatatypeType atd = (DatatypeType)SelectorType(ctor[k].getType()).getRangeType(); - Debug("parser-sygus") << "Argument " << k << " " << atd << std::endl; - std::vector<DatatypeType>::iterator itd = std::find( datatypeTypes.begin(), datatypeTypes.end(), atd ); - if( itd!=datatypeTypes.end() ){ - Debug("parser-sygus2") << "Exists in datatypeTypes." << std::endl; - unsigned index = itd-datatypeTypes.begin(); - Debug("parser-sygus2") << "index = " << index << std::endl; - bool isConst = true; - for( unsigned cc = 0; cc < ops[index].size(); cc++ ){ - Debug("parser-sygus2") << "ops[" << cc << "]=" << ops[index][cc] << std::endl; - if( ops[index][cc].getKind() != kind::CONST_RATIONAL ){ - isConst = false; - break; - } - } - if( isConst ){ - Debug("parser-sygus") << "Linearize multiplication " << ctor << " based on argument " << k << std::endl; - const Datatype & atdd = atd.getDatatype(); - std::vector<Expr> assertions; - std::vector<Expr> nbvs; - for( unsigned a=0; a<bvl.getNumChildren(); a++ ){ - if( a!=k ){ - nbvs.push_back( bvl[a] ); - } - } - Expr nbvl = getExprManager()->mkExpr( kind::BOUND_VAR_LIST, nbvs ); - for( unsigned cc = 0; cc < ops[index].size(); cc++ ){ - //Make new assertion based on partially instantiating existing - applyv[k+1] = getExprManager()->mkExpr(kind::APPLY_CONSTRUCTOR, atdd[cc].getConstructor()); - Debug("parser-sygus") << "applyv " << applyv[k+1] << std::endl; - cpatv = getExprManager()->mkExpr(kind::APPLY_CONSTRUCTOR, applyv); - Debug("parser-sygus") << "cpatv " << cpatv << std::endl; - patv[1] = cpatv; - evalApply = getExprManager()->mkExpr(kind::APPLY_UF, patv); - Debug("parser-sygus") << "evalApply " << evalApply << std::endl; - builtApply[k] = ops[index][cc]; - Debug("parser-sygus") << "builtApply " << builtApply[k] << std::endl; - builtTerm = getExprManager()->mkExpr(ops[i][j], builtApply); - Debug("parser-sygus") << "builtTerm " << builtTerm << std::endl; - Expr eassertion = getExprManager()->mkExpr(kind::EQUAL, evalApply, builtTerm); - Expr epattern = getExprManager()->mkExpr(kind::INST_PATTERN, evalApply); - epattern = getExprManager()->mkExpr(kind::INST_PATTERN_LIST, epattern); - eassertion = getExprManager()->mkExpr(kind::FORALL, nbvl, eassertion, epattern); - assertions.push_back( eassertion ); - } - assertion = assertions.size()==1 ? assertions[0] : getExprManager()->mkExpr( kind::AND, assertions ); - Debug("parser-sygus") << "...(linearized) assertion is: " << assertion << std::endl; - } - } - } - } + + + for( unsigned i=0; i<df_name.size(); i++ ){ + d_sygus_defined_funs.push_back( df_op[i] ); + preemptCommand( new DefineFunctionCommand(df_name[i], df_op[i], df_let_args[i], df_let_body[i]) ); } - return assertion; } const void Smt2::getSygusPrimedVars( std::vector<Expr>& vars, bool isPrimed ) { @@ -1534,5 +1079,16 @@ const void Smt2::getSygusPrimedVars( std::vector<Expr>& vars, bool isPrimed ) { } } +const void Smt2::addSygusFunSymbol( Type t, Expr synth_fun ){ + Expr sym = mkBoundVar("sfproxy", t); + d_sygusFunSymbols.push_back(sym); + + std::vector< Expr > attr_value; + attr_value.push_back( synth_fun ); + Command* cattr = new SetUserAttributeCommand("sygus-synth-fun", sym, attr_value); + cattr->setMuted(true); + preemptCommand(cattr); +} + }/* CVC4::parser namespace */ }/* CVC4 namespace */ diff --git a/src/parser/smt2/smt2.h b/src/parser/smt2/smt2.h index 764cb6866..e470c8111 100644 --- a/src/parser/smt2/smt2.h +++ b/src/parser/smt2/smt2.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -22,6 +22,7 @@ #include <sstream> #include <stack> #include <string> +#include <unordered_map> #include <utility> #include "parser/parser.h" @@ -58,14 +59,13 @@ public: private: bool d_logicSet; LogicInfo d_logic; - std::hash_map<std::string, Kind, StringHashFunction> operatorKindMap; + std::unordered_map<std::string, Kind> operatorKindMap; std::pair<Expr, std::string> d_lastNamedTerm; // this is a user-context stack std::stack< std::map<Expr, std::string> > d_unsatCoreNames; + // for sygus std::vector<Expr> d_sygusVars, d_sygusConstraints, d_sygusFunSymbols; - std::vector< std::pair<std::string, Expr> > d_sygusFuns; std::map< Expr, bool > d_sygusVarPrimed; - size_t d_nextSygusFun; protected: Smt2(ExprManager* exprManager, Input* input, bool strictMode = false, bool parseOnly = false); @@ -179,9 +179,6 @@ public: Expr mkSygusVar(const std::string& name, const Type& type, bool isPrimed = false); - void mkSygusDefaultGrammar( const Type& range, Expr& bvl, const std::string& fun, std::vector<CVC4::Datatype>& datatypes, - std::vector<Type>& sorts, std::vector< std::vector<Expr> >& ops, std::vector<Expr> sygus_vars, int& startIndex ); - void mkSygusConstantsForType( const Type& type, std::vector<CVC4::Expr>& ops ); void processSygusGTerm( CVC4::SygusGTerm& sgt, int index, @@ -218,24 +215,11 @@ public: std::vector< CVC4::Type>& sorts, std::vector< std::vector<CVC4::Expr> >& ops ); - void addSygusFun(const std::string& fun, Expr eval) { - d_sygusFuns.push_back(std::make_pair(fun, eval)); - } - - void defineSygusFuns(); - void mkSygusDatatype( CVC4::Datatype& dt, std::vector<CVC4::Expr>& ops, std::vector<std::string>& cnames, std::vector< std::vector< CVC4::Type > >& cargs, std::vector<std::string>& unresolved_gterm_sym, std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin ); - // i is index in datatypes/ops - // j is index is datatype - Expr getSygusAssertion( std::vector<DatatypeType>& datatypeTypes, std::vector< std::vector<Expr> >& ops, - std::map<DatatypeType, Expr>& evals, std::vector<Expr>& terms, - Expr eval, const Datatype& dt, size_t i, size_t j ); - - void addSygusConstraint(Expr constraint) { d_sygusConstraints.push_back(constraint); @@ -254,6 +238,7 @@ public: } const void getSygusPrimedVars( std::vector<Expr>& vars, bool isPrimed ); + const void addSygusFunSymbol( Type t, Expr synth_fun ); const std::vector<Expr>& getSygusFunSymbols() { return d_sygusFunSymbols; } @@ -327,9 +312,6 @@ private: void collectSygusLetArgs( CVC4::Expr e, std::vector< CVC4::Type >& sygusArgs, std::vector< CVC4::Expr >& builtinArgs ); - void addSygusDatatypeConstructor( CVC4::Datatype& dt, CVC4::Expr op, std::string& cname, std::vector< CVC4::Type >& cargs, - CVC4::Expr& let_body, std::vector< CVC4::Expr >& let_args, unsigned let_num_input_args ); - Type processSygusNestedGTerm( int sub_dt_index, std::string& sub_dname, std::vector< CVC4::Datatype >& datatypes, std::vector< CVC4::Type>& sorts, std::vector< std::vector<CVC4::Expr> >& ops, diff --git a/src/parser/smt2/smt2_input.cpp b/src/parser/smt2/smt2_input.cpp index 03f819a5d..0958e9d6c 100644 --- a/src/parser/smt2/smt2_input.cpp +++ b/src/parser/smt2/smt2_input.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Christopher L. Conway, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/smt2/smt2_input.h b/src/parser/smt2/smt2_input.h index 0ed88393f..4d6168643 100644 --- a/src/parser/smt2/smt2_input.h +++ b/src/parser/smt2/smt2_input.h @@ -2,9 +2,9 @@ /*! \file smt2_input.h ** \verbatim ** Top contributors (to current version): - ** Christopher L. Conway, Morgan Deters, Tim King + ** Christopher L. Conway, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/smt2/sygus_input.cpp b/src/parser/smt2/sygus_input.cpp index 5b20e0a9a..a967e95ed 100644 --- a/src/parser/smt2/sygus_input.cpp +++ b/src/parser/smt2/sygus_input.cpp @@ -2,9 +2,9 @@ /*! \file sygus_input.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/smt2/sygus_input.h b/src/parser/smt2/sygus_input.h index 50bc973e9..888d629e8 100644 --- a/src/parser/smt2/sygus_input.h +++ b/src/parser/smt2/sygus_input.h @@ -2,9 +2,9 @@ /*! \file sygus_input.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/tptp/Makefile.am b/src/parser/tptp/Makefile.am index eab01103f..43bbc595d 100644 --- a/src/parser/tptp/Makefile.am +++ b/src/parser/tptp/Makefile.am @@ -5,6 +5,7 @@ AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) $(WNO_PARENTH # Compile generated C files using C++ compiler AM_CFLAGS = $(AM_CXXFLAGS) +CFLAGS=$(CXXFLAGS) CC=$(CXX) ANTLR_OPTS = diff --git a/src/parser/tptp/Tptp.g b/src/parser/tptp/Tptp.g index 4e73fa6cf..fbd3d8cfb 100644 --- a/src/parser/tptp/Tptp.g +++ b/src/parser/tptp/Tptp.g @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Francois Bobot, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -32,10 +32,11 @@ options { @header { /** - ** This file is part of CVC4. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information. + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2016 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. **/ }/* @header */ @@ -92,6 +93,8 @@ using namespace CVC4::parser; // files. See the documentation in "parser/antlr_undefines.h" for more details. #include "parser/antlr_undefines.h" +#include <memory> + #include "smt/command.h" #include "parser/parser.h" #include "parser/tptp/tptp.h" @@ -353,7 +356,7 @@ definedFun[CVC4::Expr& expr] MK_EXPR(CVC4::kind::TO_INTEGER, expr), MK_EXPR(CVC4::kind::UMINUS, MK_EXPR(CVC4::kind::TO_INTEGER, MK_EXPR(CVC4::kind::UMINUS, expr)))); if(remainder) { - expr = MK_EXPR(CVC4::kind::MINUS, n, MK_EXPR(CVC4::kind::MULT, expr, d)); + expr = MK_EXPR(CVC4::kind::TO_INTEGER, MK_EXPR(CVC4::kind::MINUS, n, MK_EXPR(CVC4::kind::MULT, expr, d))); } expr = MK_EXPR(CVC4::kind::LAMBDA, formals, expr); } @@ -368,7 +371,7 @@ definedFun[CVC4::Expr& expr] MK_EXPR(CVC4::kind::TO_INTEGER, expr), MK_EXPR(CVC4::kind::UMINUS, MK_EXPR(CVC4::kind::TO_INTEGER, MK_EXPR(CVC4::kind::UMINUS, expr)))); if(remainder) { - expr = MK_EXPR(CVC4::kind::MINUS, n, MK_EXPR(CVC4::kind::MULT, expr, d)); + expr = MK_EXPR(CVC4::kind::TO_INTEGER, MK_EXPR(CVC4::kind::MINUS, n, MK_EXPR(CVC4::kind::MULT, expr, d))); } expr = MK_EXPR(CVC4::kind::LAMBDA, formals, expr); } @@ -381,7 +384,7 @@ definedFun[CVC4::Expr& expr] expr = MK_EXPR(CVC4::kind::DIVISION_TOTAL, n, d); expr = MK_EXPR(CVC4::kind::TO_INTEGER, expr); if(remainder) { - expr = MK_EXPR(CVC4::kind::MINUS, n, MK_EXPR(CVC4::kind::MULT, expr, d)); + expr = MK_EXPR(CVC4::kind::TO_INTEGER, MK_EXPR(CVC4::kind::MINUS, n, MK_EXPR(CVC4::kind::MULT, expr, d))); } expr = MK_EXPR(CVC4::kind::LAMBDA, formals, expr); } diff --git a/src/parser/tptp/tptp.cpp b/src/parser/tptp/tptp.cpp index dcb23d3f2..64eeddd2f 100644 --- a/src/parser/tptp/tptp.cpp +++ b/src/parser/tptp/tptp.cpp @@ -2,9 +2,9 @@ /*! \file tptp.cpp ** \verbatim ** Top contributors (to current version): - ** Francois Bobot, Morgan Deters, Tim King + ** Francois Bobot, Morgan Deters, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/tptp/tptp.h b/src/parser/tptp/tptp.h index 2a2a5095f..3afd29415 100644 --- a/src/parser/tptp/tptp.h +++ b/src/parser/tptp/tptp.h @@ -2,9 +2,9 @@ /*! \file tptp.h ** \verbatim ** Top contributors (to current version): - ** Francois Bobot, Morgan Deters, Tim King + ** Francois Bobot, Morgan Deters, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -22,7 +22,8 @@ #define __CVC4__PARSER__TPTP_H #include <cassert> -#include <ext/hash_set> +#include <unordered_map> +#include <unordered_set> #include "parser/parser.h" #include "smt/command.h" @@ -45,8 +46,8 @@ class Tptp : public Parser { Expr d_utr_op; Expr d_uts_op; // The set of expression that already have a bridge - std::hash_set<Expr, ExprHashFunction> d_r_converted; - std::hash_map<std::string, Expr, StringHashFunction> d_distinct_objects; + std::unordered_set<Expr, ExprHashFunction> d_r_converted; + std::unordered_map<std::string, Expr> d_distinct_objects; std::vector< pANTLR3_INPUT_STREAM > d_in_created; diff --git a/src/parser/tptp/tptp_input.cpp b/src/parser/tptp/tptp_input.cpp index 42337b42b..5464e1002 100644 --- a/src/parser/tptp/tptp_input.cpp +++ b/src/parser/tptp/tptp_input.cpp @@ -2,9 +2,9 @@ /*! \file tptp_input.cpp ** \verbatim ** Top contributors (to current version): - ** Francois Bobot, Tim King, Morgan Deters + ** Francois Bobot, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/parser/tptp/tptp_input.h b/src/parser/tptp/tptp_input.h index 28bf1828a..a1f70641e 100644 --- a/src/parser/tptp/tptp_input.h +++ b/src/parser/tptp/tptp_input.h @@ -2,9 +2,9 @@ /*! \file tptp_input.h ** \verbatim ** Top contributors (to current version): - ** Francois Bobot, Tim King, Morgan Deters + ** Francois Bobot, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/preproc/preprocessing_passes_core.cpp b/src/preproc/preprocessing_passes_core.cpp index 69d3434ed..25bca94b5 100644 --- a/src/preproc/preprocessing_passes_core.cpp +++ b/src/preproc/preprocessing_passes_core.cpp @@ -1,6 +1,6 @@ #include "preproc/preprocessing_passes_core.h" -#include <ext/hash_map> +#include <unordered_map> #include <string> #include <stack> #include "expr/node_manager_attributes.h" @@ -27,8 +27,8 @@ namespace preproc { ExpandingDefinitionsPass::ExpandingDefinitionsPass(ResourceManager* resourceManager, SmtEngine* smt, TimerStat definitionExpansionTime) : PreprocessingPass(resourceManager), d_smt(smt), d_definitionExpansionTime(definitionExpansionTime){ } -Node ExpandingDefinitionsPass::expandDefinitions(TNode n, hash_map<Node, Node, NodeHashFunction>& cache, bool expandOnly) - throw(TypeCheckingException, LogicException, UnsafeInterruptException) { +Node ExpandingDefinitionsPass::expandDefinitions(TNode n, unordered_map<Node, Node, NodeHashFunction>& cache, bool expandOnly) + throw(TypeCheckingException, LogicException, UnsafeInterruptException) { stack< triple<Node, Node, bool> > worklist; stack<Node> result; worklist.push(make_triple(Node(n), Node(n), false)); @@ -66,8 +66,8 @@ Node ExpandingDefinitionsPass::expandDefinitions(TNode n, hash_map<Node, Node, N } // maybe it's in the cache - hash_map<Node, Node, NodeHashFunction>::iterator cacheHit = cache.find(n); - if(cacheHit != cache.end()) { + unordered_map<Node, Node, NodeHashFunction>::iterator cacheHit = cache.find(n); + if(cacheHit != cache.end()) { TNode ret = (*cacheHit).second; result.push(ret.isNull() ? n : ret); continue; @@ -194,7 +194,7 @@ PreprocessingPassResult ExpandingDefinitionsPass::apply(AssertionPipeline* asser Chat() << "expanding definitions..." << std::endl; Trace("simplify") << "SmtEnginePrivate::simplify(): expanding definitions" << endl; TimerStat::CodeTimer codeTimer(d_definitionExpansionTime); - hash_map<Node, Node, NodeHashFunction> cache; + unordered_map<Node, Node, NodeHashFunction> cache; for(unsigned i = 0; i < assertionsToPreprocess->size(); ++ i) { assertionsToPreprocess->replace(i, expandDefinitions((*assertionsToPreprocess)[i], cache)); } @@ -206,8 +206,8 @@ NlExtPurifyPass::NlExtPurifyPass(ResourceManager* resourceManager) : } PreprocessingPassResult NlExtPurifyPass::apply(AssertionPipeline* assertionsToPreprocess) { - std::hash_map<Node, Node, NodeHashFunction> cache; - std::hash_map<Node, Node, NodeHashFunction> bcache; + std::unordered_map<Node, Node, NodeHashFunction> cache; + std::unordered_map<Node, Node, NodeHashFunction> bcache; std::vector<Node> var_eq; for (unsigned i = 0; i < assertionsToPreprocess->size(); ++i) { assertionsToPreprocess->replace(i, purifyNlTerms((*assertionsToPreprocess)[i], cache, bcache, var_eq)); @@ -282,7 +282,7 @@ SolveRealAsIntPass::SolveRealAsIntPass(ResourceManager* resourceManager) : PreprocessingPassResult SolveRealAsIntPass::apply(AssertionPipeline* assertionsToPreprocess) { Chat() << "converting reals to ints..." << std::endl; - std::hash_map<Node, Node, NodeHashFunction> cache; + std::unordered_map<Node, Node, NodeHashFunction> cache; std::vector<Node> var_eq; for(unsigned i = 0; i < assertionsToPreprocess->size(); ++ i) { assertionsToPreprocess->replace(i, realToInt((*assertionsToPreprocess)[i], cache, var_eq) ); @@ -392,7 +392,7 @@ SolveIntAsBVPass::SolveIntAsBVPass(ResourceManager* resourceManager) : PreprocessingPassResult SolveIntAsBVPass::apply(AssertionPipeline* assertionsToPreprocess) { Chat() << "converting ints to bit-vectors..." << std::endl; - std::hash_map<Node, Node, NodeHashFunction> cache; + std::unordered_map<Node, Node, NodeHashFunction> cache; for(unsigned i = 0; i < assertionsToPreprocess->size(); ++ i) { assertionsToPreprocess->replace(i, intToBV((*assertionsToPreprocess)[i], cache) ); } @@ -670,78 +670,6 @@ PreprocessingPassResult BVAbstractionPass::apply(AssertionPipeline* assertionsTo return PreprocessingPassResult(true); } -ConstrainSubtypesPass::ConstrainSubtypesPass(ResourceManager* resourceManager, SmtEngine* smt) : PreprocessingPass(resourceManager), d_smt(smt) { -} - -void ConstrainSubtypesPass::constrainSubtypes(TNode top, AssertionPipeline& assertions) - throw() { - Trace("constrainSubtypes") << "constrainSubtypes(): looking at " << top << endl; - - set<TNode> done; - stack<TNode> worklist; - worklist.push(top); - done.insert(top); - - do { - TNode n = worklist.top(); - worklist.pop(); - - TypeNode t = n.getType(); - if(t.isPredicateSubtype()) { - WarningOnce() << "Warning: CVC4 doesn't yet do checking that predicate subtypes are nonempty domains" << endl; - Node pred = t.getSubtypePredicate(); - Kind k; - // pred can be a LAMBDA, a function constant, or a datatype tester - Trace("constrainSubtypes") << "constrainSubtypes(): pred.getType() == " << pred.getType() << endl; - if(d_smt->d_definedFunctions->find(pred) != d_smt->d_definedFunctions->end()) { - k = kind::APPLY; - } else if(pred.getType().isTester()) { - k = kind::APPLY_TESTER; - } else { - k = kind::APPLY_UF; - } - Node app = NodeManager::currentNM()->mkNode(k, pred, n); - Trace("constrainSubtypes") << "constrainSubtypes(): assert(" << k << ") " << app << endl; - assertions.push_back(app); - } else if(t.isSubrange()) { - SubrangeBounds bounds = t.getSubrangeBounds(); - Trace("constrainSubtypes") << "constrainSubtypes(): got bounds " << bounds << endl; - if(bounds.lower.hasBound()) { - Node c = NodeManager::currentNM()->mkConst(Rational(bounds.lower.getBound())); - Node lb = NodeManager::currentNM()->mkNode(kind::LEQ, c, n); - Trace("constrainSubtypes") << "constrainSubtypes(): assert " << lb << endl; - assertions.push_back(lb); - } - if(bounds.upper.hasBound()) { - Node c = NodeManager::currentNM()->mkConst(Rational(bounds.upper.getBound())); - Node ub = NodeManager::currentNM()->mkNode(kind::LEQ, n, c); - Trace("constrainSubtypes") << "constrainSubtypes(): assert " << ub << endl; - assertions.push_back(ub); - } - } - - for(TNode::iterator i = n.begin(); i != n.end(); ++i) { - if(done.find(*i) == done.end()) { - worklist.push(*i); - done.insert(*i); - } - } - } while(! worklist.empty()); -} - -PreprocessingPassResult ConstrainSubtypesPass::apply(AssertionPipeline* assertionsToPreprocess){ - // Any variables of subtype types need to be constrained properly. - // Careful, here: constrainSubtypes() adds to the back of - // d_assertions, but we don't need to reprocess those. - // We also can't use an iterator, because the vector may be moved in - // memory during this loop. - Chat() << "constraining subtypes..." << endl; - for(unsigned i = 0, i_end = assertionsToPreprocess->size(); i != i_end; ++i) { - constrainSubtypes((*assertionsToPreprocess)[i], *assertionsToPreprocess); - } - return PreprocessingPassResult(true); -} - UnconstrainedSimpPass::UnconstrainedSimpPass(ResourceManager* resourceManager, TimerStat unconstrainedSimpTime, TheoryEngine* theoryEngine) : PreprocessingPass(resourceManager), @@ -1129,9 +1057,15 @@ RepeatSimpPass::RepeatSimpPass(ResourceManager* resourceManager, d_realAssertionsEnd(realAssertionsEnd){ } +<<<<<<< HEAD +bool RepeatSimpPass::checkForBadSkolems(TNode n, TNode skolem, unordered_map<Node, bool, NodeHashFunction>& cache) +{ + unordered_map<Node, bool, NodeHashFunction>::iterator it; +======= bool RepeatSimpPass::checkForBadSkolems(TNode n, TNode skolem, hash_map<Node, bool, NodeHashFunction>& cache) { hash_map<Node, bool, NodeHashFunction>::iterator it; +>>>>>>> 93c2bbb764e34cd5285607dcb2bc4872bbe92456 it = cache.find(n); if (it != cache.end()) { return (*it).second; @@ -1162,9 +1096,15 @@ bool RepeatSimpPass::checkForBadSkolems(TNode n, TNode skolem, hash_map<Node, bo return false; } +<<<<<<< HEAD +void RepeatSimpPass::collectSkolems(TNode n, set<TNode>& skolemSet, unordered_map<Node, bool, NodeHashFunction>& cache) +{ + unordered_map<Node, bool, NodeHashFunction>::iterator it; +======= void RepeatSimpPass::collectSkolems(TNode n, set<TNode>& skolemSet, hash_map<Node, bool, NodeHashFunction>& cache) { hash_map<Node, bool, NodeHashFunction>::iterator it; +>>>>>>> 93c2bbb764e34cd5285607dcb2bc4872bbe92456 it = cache.find(n); if (it != cache.end()) { return; @@ -1199,8 +1139,7 @@ PreprocessingPassResult RepeatSimpPass::apply(AssertionPipeline* assertionsToPre // For each skolem variable sk, let iteExpr = iteMap(sk) be the ite expr mapped to by sk. // cache for expression traversal - std::hash_map<Node, bool, NodeHashFunction> cache; - + std::unordered_map<Node, bool, NodeHashFunction> cache; // First, find all skolems that appear in the substitution map - their associated iteExpr will need // to be moved to the main assertion set std::set<TNode> skolemSet; diff --git a/src/preproc/preprocessing_passes_core.h b/src/preproc/preprocessing_passes_core.h index 9f8e91c3d..cff581894 100644 --- a/src/preproc/preprocessing_passes_core.h +++ b/src/preproc/preprocessing_passes_core.h @@ -14,8 +14,8 @@ namespace CVC4 { namespace preproc { -typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap; -typedef std::hash_map<Node, Node, NodeHashFunction> NodeToNodeHashMap; +typedef std::unordered_map<Node, Node, NodeHashFunction> NodeMap; +typedef std::unordered_map<Node, Node, NodeHashFunction> NodeToNodeHashMap; typedef context::CDList<Node> NodeList; class ExpandingDefinitionsPass : public PreprocessingPass { @@ -86,16 +86,6 @@ class BVAbstractionPass : public PreprocessingPass { void bvAbstraction(AssertionPipeline* assertionsToPreprocess); }; -class ConstrainSubtypesPass : public PreprocessingPass { - public: - virtual PreprocessingPassResult apply(AssertionPipeline* assertionsToPreprocess); - ConstrainSubtypesPass(ResourceManager* resourceManager, SmtEngine* smt); - private: - SmtEngine* d_smt; - void constrainSubtypes(TNode n, AssertionPipeline& assertions) - throw(); -}; - class UnconstrainedSimpPass : public PreprocessingPass { public: virtual PreprocessingPassResult apply(AssertionPipeline* assertionsToPreprocess); diff --git a/src/printer/ast/ast_printer.cpp b/src/printer/ast/ast_printer.cpp index e15d8766f..35b39914a 100644 --- a/src/printer/ast/ast_printer.cpp +++ b/src/printer/ast/ast_printer.cpp @@ -2,9 +2,9 @@ /*! \file ast_printer.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Liana Hadarean + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/printer/ast/ast_printer.h b/src/printer/ast/ast_printer.h index ef123d1d4..29c3981bf 100644 --- a/src/printer/ast/ast_printer.h +++ b/src/printer/ast/ast_printer.h @@ -2,9 +2,9 @@ /*! \file ast_printer.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/printer/cvc/cvc_printer.cpp b/src/printer/cvc/cvc_printer.cpp index 4605d1956..936a7261e 100644 --- a/src/printer/cvc/cvc_printer.cpp +++ b/src/printer/cvc/cvc_printer.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -145,12 +145,6 @@ void CvcPrinter::toStream(std::ostream& out, TNode n, int depth, bool types, boo } break; } - case kind::SUBRANGE_TYPE: - out << '[' << n.getConst<SubrangeBounds>() << ']'; - break; - case kind::SUBTYPE_TYPE: - out << "SUBTYPE(" << n.getConst<Predicate>() << ")"; - break; case kind::TYPE_CONSTANT: switch(TypeConstant tc = n.getConst<TypeConstant>()) { case REAL_TYPE: @@ -392,18 +386,24 @@ void CvcPrinter::toStream(std::ostream& out, TNode n, int depth, bool types, boo break; case kind::APPLY_SELECTOR: case kind::APPLY_SELECTOR_TOTAL: { - TypeNode t = n.getType(); + TypeNode t = n[0].getType(); + Node opn = n.getOperator(); if( t.isTuple() ){ toStream(out, n[0], depth, types, true); - out << '.' << Datatype::indexOf( n.getOperator().toExpr() ); + const Datatype& dt = ((DatatypeType)t.toType()).getDatatype(); + int sindex = dt[0].getSelectorIndexInternal( opn.toExpr() ); + Assert( sindex>=0 ); + out << '.' << sindex; }else if( t.isRecord() ){ toStream(out, n[0], depth, types, true); const Record& rec = t.getRecord(); - unsigned index = Datatype::indexOf( n.getOperator().toExpr() ); - std::pair<std::string, Type> fld = rec[index]; + const Datatype& dt = ((DatatypeType)t.toType()).getDatatype(); + int sindex = dt[0].getSelectorIndexInternal( opn.toExpr() ); + Assert( sindex>=0 ); + std::pair<std::string, Type> fld = rec[sindex]; out << '.' << fld.first; }else{ - toStream(op, n.getOperator(), depth, types, false); + toStream(op, opn, depth, types, false); } } break; diff --git a/src/printer/cvc/cvc_printer.h b/src/printer/cvc/cvc_printer.h index fd250132b..54ff3ea1d 100644 --- a/src/printer/cvc/cvc_printer.h +++ b/src/printer/cvc/cvc_printer.h @@ -2,9 +2,9 @@ /*! \file cvc_printer.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Dejan Jovanovic + ** Morgan Deters, Paul Meng, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/printer/dagification_visitor.cpp b/src/printer/dagification_visitor.cpp index c52f0ed08..f2bb46107 100644 --- a/src/printer/dagification_visitor.cpp +++ b/src/printer/dagification_visitor.cpp @@ -2,9 +2,9 @@ /*! \file dagification_visitor.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Paul Meng, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/printer/dagification_visitor.h b/src/printer/dagification_visitor.h index c79ec514f..6cbe5f863 100644 --- a/src/printer/dagification_visitor.h +++ b/src/printer/dagification_visitor.h @@ -2,9 +2,9 @@ /*! \file dagification_visitor.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,12 +19,13 @@ #ifndef __CVC4__PRINTER__DAGIFICATION_VISITOR_H #define __CVC4__PRINTER__DAGIFICATION_VISITOR_H +#include <string> +#include <unordered_map> +#include <vector> + #include "expr/node.h" #include "util/hash.h" -#include <vector> -#include <string> - namespace CVC4 { namespace context { @@ -65,7 +66,7 @@ class DagificationVisitor { /** * A map of subexprs to their occurrence count. */ - std::hash_map<TNode, unsigned, TNodeHashFunction> d_nodeCount; + std::unordered_map<TNode, unsigned, TNodeHashFunction> d_nodeCount; /** * The top-most node we are visiting. @@ -109,7 +110,7 @@ class DagificationVisitor { * in independently dagifying the child. (If it is beyond the threshold * and occurs in more than one parent, we'll independently dagify.) */ - std::hash_map<TNode, TNode, TNodeHashFunction> d_uniqueParent; + std::unordered_map<TNode, TNode, TNodeHashFunction> d_uniqueParent; /** * A list of all nodes that meet the occurrence threshold and therefore diff --git a/src/printer/printer.cpp b/src/printer/printer.cpp index a8a84c06f..5e349d123 100644 --- a/src/printer/printer.cpp +++ b/src/printer/printer.cpp @@ -2,9 +2,9 @@ /*! \file printer.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Clark Barrett + ** Morgan Deters, Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/printer/printer.h b/src/printer/printer.h index a6156ad16..ec1f92604 100644 --- a/src/printer/printer.h +++ b/src/printer/printer.h @@ -2,9 +2,9 @@ /*! \file printer.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/printer/smt1/smt1_printer.cpp b/src/printer/smt1/smt1_printer.cpp index 7fde0749b..b67274ce2 100644 --- a/src/printer/smt1/smt1_printer.cpp +++ b/src/printer/smt1/smt1_printer.cpp @@ -2,9 +2,9 @@ /*! \file smt1_printer.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/printer/smt1/smt1_printer.h b/src/printer/smt1/smt1_printer.h index d8101d916..920bd6494 100644 --- a/src/printer/smt1/smt1_printer.h +++ b/src/printer/smt1/smt1_printer.h @@ -2,9 +2,9 @@ /*! \file smt1_printer.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/printer/smt2/smt2_printer.cpp b/src/printer/smt2/smt2_printer.cpp index 4dd6e73aa..aa9c17e5a 100644 --- a/src/printer/smt2/smt2_printer.cpp +++ b/src/printer/smt2/smt2_printer.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Martin Brain ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -281,19 +281,6 @@ void Smt2Printer::toStream(std::ostream& out, TNode n, break; } - case kind::SUBRANGE_TYPE: { - const SubrangeBounds& bounds = n.getConst<SubrangeBounds>(); - // No way to represent subranges in SMT-LIBv2; this is inspired - // by yices format (but isn't identical to it). - out << "(subrange " << bounds.lower << ' ' << bounds.upper << ')'; - break; - } - case kind::SUBTYPE_TYPE: - // No way to represent predicate subtypes in SMT-LIBv2; this is - // inspired by yices format (but isn't identical to it). - out << "(subtype " << n.getConst<Predicate>() << ')'; - break; - case kind::DATATYPE_TYPE: { const Datatype & dt = (NodeManager::currentNM()->getDatatypeForIndex( n.getConst< DatatypeIndexConstant >().getIndex() )); @@ -383,6 +370,10 @@ void Smt2Printer::toStream(std::ostream& out, TNode n, case kind::PLUS: case kind::MULT: case kind::NONLINEAR_MULT: + case kind::EXPONENTIAL: + case kind::SINE: + case kind::COSINE: + case kind::TANGENT: case kind::MINUS: case kind::UMINUS: case kind::LT: @@ -817,6 +808,10 @@ static string smtKindString(Kind k) throw() { case kind::PLUS: return "+"; case kind::MULT: case kind::NONLINEAR_MULT: return "*"; + case kind::EXPONENTIAL: return "exp"; + case kind::SINE: return "sin"; + case kind::COSINE: return "cos"; + case kind::TANGENT: return "tan"; case kind::MINUS: return "-"; case kind::UMINUS: return "-"; case kind::LT: return "<"; @@ -825,10 +820,10 @@ static string smtKindString(Kind k) throw() { case kind::GEQ: return ">="; case kind::DIVISION: case kind::DIVISION_TOTAL: return "/"; + case kind::INTS_DIVISION_TOTAL: case kind::INTS_DIVISION: return "div"; - case kind::INTS_DIVISION_TOTAL: return "INTS_DIVISION_TOTAL"; + case kind::INTS_MODULUS_TOTAL: case kind::INTS_MODULUS: return "mod"; - case kind::INTS_MODULUS_TOTAL: return "INTS_MODULUS_TOTAL"; case kind::ABS: return "abs"; case kind::IS_INTEGER: return "is_int"; case kind::TO_INTEGER: return "to_int"; diff --git a/src/printer/smt2/smt2_printer.h b/src/printer/smt2/smt2_printer.h index eeba0b12a..f6438ae87 100644 --- a/src/printer/smt2/smt2_printer.h +++ b/src/printer/smt2/smt2_printer.h @@ -2,9 +2,9 @@ /*! \file smt2_printer.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Paul Meng, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/printer/tptp/tptp_printer.cpp b/src/printer/tptp/tptp_printer.cpp index 1be98ffad..5fc9b7ed8 100644 --- a/src/printer/tptp/tptp_printer.cpp +++ b/src/printer/tptp/tptp_printer.cpp @@ -2,9 +2,9 @@ /*! \file tptp_printer.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/printer/tptp/tptp_printer.h b/src/printer/tptp/tptp_printer.h index aac69d046..7c8ddbd20 100644 --- a/src/printer/tptp/tptp_printer.h +++ b/src/printer/tptp/tptp_printer.h @@ -2,9 +2,9 @@ /*! \file tptp_printer.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/arith_proof.cpp b/src/proof/arith_proof.cpp index 0f0c14eb2..03de1ca4f 100644 --- a/src/proof/arith_proof.cpp +++ b/src/proof/arith_proof.cpp @@ -2,9 +2,9 @@ /*! \file arith_proof.cpp ** \verbatim ** Top contributors (to current version): - ** Guy Katz + ** Guy Katz, Andrew Reynolds, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/arith_proof.h b/src/proof/arith_proof.h index 08985487d..3de53f866 100644 --- a/src/proof/arith_proof.h +++ b/src/proof/arith_proof.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Guy Katz, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,6 +19,8 @@ #ifndef __CVC4__ARITH__PROOF_H #define __CVC4__ARITH__PROOF_H +#include <unordered_set> + #include "expr/expr.h" #include "proof/proof_manager.h" #include "proof/theory_proof.h" @@ -45,7 +47,7 @@ class TheoryArith; } } -typedef __gnu_cxx::hash_set<Type, TypeHashFunction > TypeSet; +typedef std::unordered_set<Type, TypeHashFunction > TypeSet; class ArithProof : public TheoryProof { diff --git a/src/proof/array_proof.cpp b/src/proof/array_proof.cpp index 6d1bd567d..e5b7e64e5 100644 --- a/src/proof/array_proof.cpp +++ b/src/proof/array_proof.cpp @@ -2,9 +2,9 @@ /*! \file array_proof.cpp ** \verbatim ** Top contributors (to current version): - ** Guy Katz + ** Guy Katz, Andrew Reynolds, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/array_proof.h b/src/proof/array_proof.h index eaf2f47fb..9a2eef9e7 100644 --- a/src/proof/array_proof.h +++ b/src/proof/array_proof.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Guy Katz, Liana Hadarean, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,6 +19,8 @@ #ifndef __CVC4__ARRAY__PROOF_H #define __CVC4__ARRAY__PROOF_H +#include <unordered_set> + #include "expr/expr.h" #include "proof/proof_manager.h" #include "proof/theory_proof.h" @@ -94,7 +96,7 @@ class TheoryArrays; } /* namespace CVC4::theory::arrays */ } /* namespace CVC4::theory */ -typedef __gnu_cxx::hash_set<Type, TypeHashFunction > TypeSet; +typedef std::unordered_set<Type, TypeHashFunction > TypeSet; class ArrayProof : public TheoryProof { // TODO: whatever goes in this theory diff --git a/src/proof/bitvector_proof.cpp b/src/proof/bitvector_proof.cpp index ebe82cd91..5c660b284 100644 --- a/src/proof/bitvector_proof.cpp +++ b/src/proof/bitvector_proof.cpp @@ -2,9 +2,9 @@ /*! \file bitvector_proof.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Guy Katz, Tim King + ** Guy Katz, Liana Hadarean, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/bitvector_proof.h b/src/proof/bitvector_proof.h index fcd1d2584..69f9e774b 100644 --- a/src/proof/bitvector_proof.h +++ b/src/proof/bitvector_proof.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Guy Katz, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,12 +19,11 @@ #ifndef __CVC4__BITVECTOR__PROOF_H #define __CVC4__BITVECTOR__PROOF_H -//#include <cstdint> -#include <ext/hash_map> -#include <ext/hash_set> #include <iostream> #include <set> #include <sstream> +#include <unordered_map> +#include <unordered_set> #include <vector> #include "expr/expr.h" @@ -56,11 +55,11 @@ typedef TSatProof< CVC4::BVMinisat::Solver> BVSatProof; template <class Solver> class LFSCSatProof; typedef LFSCSatProof< CVC4::BVMinisat::Solver> LFSCBVSatProof; -typedef __gnu_cxx::hash_set<Expr, ExprHashFunction> ExprSet; -typedef __gnu_cxx::hash_map<Expr, ClauseId, ExprHashFunction> ExprToClauseId; -typedef __gnu_cxx::hash_map<Expr, unsigned, ExprHashFunction> ExprToId; -typedef __gnu_cxx::hash_map<Expr, Expr, ExprHashFunction> ExprToExpr; -typedef __gnu_cxx::hash_map<Expr, std::string, ExprHashFunction> ExprToString; +typedef std::unordered_set<Expr, ExprHashFunction> ExprSet; +typedef std::unordered_map<Expr, ClauseId, ExprHashFunction> ExprToClauseId; +typedef std::unordered_map<Expr, unsigned, ExprHashFunction> ExprToId; +typedef std::unordered_map<Expr, Expr, ExprHashFunction> ExprToExpr; +typedef std::unordered_map<Expr, std::string, ExprHashFunction> ExprToString; class BitVectorProof : public TheoryProof { protected: diff --git a/src/proof/clause_id.h b/src/proof/clause_id.h index c66f8c9f5..309a235fe 100644 --- a/src/proof/clause_id.h +++ b/src/proof/clause_id.h @@ -2,9 +2,9 @@ /*! \file clause_id.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/cnf_proof.cpp b/src/proof/cnf_proof.cpp index d1a228ecb..ff73a4635 100644 --- a/src/proof/cnf_proof.cpp +++ b/src/proof/cnf_proof.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Guy Katz, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/cnf_proof.h b/src/proof/cnf_proof.h index 788526b80..a0d7096c0 100644 --- a/src/proof/cnf_proof.h +++ b/src/proof/cnf_proof.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Guy Katz, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -21,9 +21,9 @@ #ifndef __CVC4__CNF_PROOF_H #define __CVC4__CNF_PROOF_H -#include <ext/hash_map> -#include <ext/hash_set> #include <iosfwd> +#include <unordered_map> +#include <unordered_set> #include "context/cdhashmap.h" #include "proof/clause_id.h" @@ -38,9 +38,9 @@ namespace prop { class CnfProof; -typedef __gnu_cxx::hash_map<prop::SatVariable, Expr> SatVarToExpr; -typedef __gnu_cxx::hash_map<Node, Node, NodeHashFunction> NodeToNode; -typedef __gnu_cxx::hash_set<ClauseId> ClauseIdSet; +typedef std::unordered_map<prop::SatVariable, Expr> SatVarToExpr; +typedef std::unordered_map<Node, Node, NodeHashFunction> NodeToNode; +typedef std::unordered_set<ClauseId> ClauseIdSet; typedef context::CDHashMap<ClauseId, Node> ClauseIdToNode; typedef context::CDHashMap<Node, ProofRule, NodeHashFunction> NodeToProofRule; diff --git a/src/proof/lemma_proof.cpp b/src/proof/lemma_proof.cpp index fb7df4576..ee5604f9a 100644 --- a/src/proof/lemma_proof.cpp +++ b/src/proof/lemma_proof.cpp @@ -1,11 +1,16 @@ /********************* */ -/*! \file lemma_proof.h -** \verbatim -** -** \brief A class for recoding the steps required in order to prove a theory lemma. -** -** A class for recoding the steps required in order to prove a theory lemma. -** +/*! \file lemma_proof.cpp + ** \verbatim + ** Top contributors (to current version): + ** Guy Katz + ** 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 + ** + ** A class for recoding the steps required in order to prove a theory lemma. + **/ #include "proof/lemma_proof.h" diff --git a/src/proof/lemma_proof.h b/src/proof/lemma_proof.h index 9c838cee7..9d9f11db5 100644 --- a/src/proof/lemma_proof.h +++ b/src/proof/lemma_proof.h @@ -1,11 +1,16 @@ /********************* */ /*! \file lemma_proof.h -** \verbatim -** -** \brief A class for recoding the steps required in order to prove a theory lemma. -** -** A class for recoding the steps required in order to prove a theory lemma. -** + ** \verbatim + ** Top contributors (to current version): + ** Guy Katz + ** 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 + ** + ** A class for recoding the steps required in order to prove a theory lemma. + **/ #include "cvc4_private.h" diff --git a/src/proof/proof.h b/src/proof/proof.h index af72ccfa8..cb769495b 100644 --- a/src/proof/proof.h +++ b/src/proof/proof.h @@ -2,9 +2,9 @@ /*! \file proof.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King, Morgan Deters + ** Liana Hadarean, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/proof_manager.cpp b/src/proof/proof_manager.cpp index 2bab09789..ba327f5f7 100644 --- a/src/proof/proof_manager.cpp +++ b/src/proof/proof_manager.cpp @@ -2,9 +2,9 @@ /*! \file proof_manager.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Guy Katz, Morgan Deters + ** Guy Katz, Liana Hadarean, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/proof_manager.h b/src/proof/proof_manager.h index 31638e8ee..f77a96726 100644 --- a/src/proof/proof_manager.h +++ b/src/proof/proof_manager.h @@ -2,9 +2,9 @@ /*! \file proof_manager.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Morgan Deters, Guy Katz + ** Liana Hadarean, Guy Katz, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,9 @@ #define __CVC4__PROOF_MANAGER_H #include <iosfwd> -#include <map> +#include <unordered_map> +#include <unordered_set> + #include "expr/node.h" #include "context/cdhashset.h" #include "context/cdhashmap.h" @@ -96,13 +98,11 @@ enum ProofFormat { std::string append(const std::string& str, uint64_t num); -typedef __gnu_cxx::hash_map < ClauseId, prop::SatClause* > IdToSatClause; -typedef __gnu_cxx::hash_set<Expr, ExprHashFunction> ExprSet; +typedef std::unordered_map<ClauseId, prop::SatClause*> IdToSatClause; typedef context::CDHashSet<Expr, ExprHashFunction> CDExprSet; -typedef __gnu_cxx::hash_set<Node, NodeHashFunction > NodeSet; -typedef __gnu_cxx::hash_map<Node, std::vector<Node>, NodeHashFunction > NodeToNodes; -typedef context::CDHashMap<Node, std::vector<Node>, NodeHashFunction > CDNodeToNodes; -typedef std::hash_set<ClauseId> IdHashSet; +typedef std::unordered_map<Node, std::vector<Node>, NodeHashFunction> NodeToNodes; +typedef context::CDHashMap<Node, std::vector<Node>, NodeHashFunction> CDNodeToNodes; +typedef std::unordered_set<ClauseId> IdHashSet; enum ProofRule { RULE_GIVEN, /* input assertion */ diff --git a/src/proof/proof_output_channel.cpp b/src/proof/proof_output_channel.cpp index c87ccd37c..819cc0102 100644 --- a/src/proof/proof_output_channel.cpp +++ b/src/proof/proof_output_channel.cpp @@ -1,10 +1,18 @@ /********************* */ /*! \file proof_output_channel.cpp -** \verbatim -** \brief [[ Add one-line brief description here ]] -** -** [[ Add lengthier description here ]] -** \todo document this file + ** \verbatim + ** Top contributors (to current version): + ** Guy Katz, Tim King + ** 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 + ** + ** [[ Add lengthier description here ]] + + ** \todo document this file + **/ #include "base/cvc4_assert.h" diff --git a/src/proof/proof_output_channel.h b/src/proof/proof_output_channel.h index b44689fe5..b114ec25f 100644 --- a/src/proof/proof_output_channel.h +++ b/src/proof/proof_output_channel.h @@ -1,6 +1,13 @@ /********************* */ /*! \file proof_output_channel.h ** \verbatim + ** Top contributors (to current version): + ** Guy Katz, Tim King + ** 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 ** **/ @@ -9,6 +16,8 @@ #ifndef __CVC4__PROOF_OUTPUT_CHANNEL_H #define __CVC4__PROOF_OUTPUT_CHANNEL_H +#include <unordered_set> + #include "theory/output_channel.h" namespace CVC4 { @@ -35,7 +44,7 @@ public: class MyPreRegisterVisitor { theory::Theory* d_theory; - __gnu_cxx::hash_set<TNode, TNodeHashFunction> d_visited; + std::unordered_set<TNode, TNodeHashFunction> d_visited; public: typedef void return_type; MyPreRegisterVisitor(theory::Theory* theory); diff --git a/src/proof/proof_utils.cpp b/src/proof/proof_utils.cpp index 3ace236b5..6e8ed01f5 100644 --- a/src/proof/proof_utils.cpp +++ b/src/proof/proof_utils.cpp @@ -2,9 +2,9 @@ /*! \file proof_utils.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean + ** Liana Hadarean, Guy Katz, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/proof_utils.h b/src/proof/proof_utils.h index a7590451d..7c0660a83 100644 --- a/src/proof/proof_utils.h +++ b/src/proof/proof_utils.h @@ -2,9 +2,9 @@ /*! \file proof_utils.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean + ** Liana Hadarean, Guy Katz, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,14 +20,16 @@ #pragma once #include <set> -#include <vector> #include <sstream> +#include <unordered_set> +#include <vector> + #include "expr/node_manager.h" namespace CVC4 { -typedef __gnu_cxx::hash_set<Expr, ExprHashFunction> ExprSet; -typedef __gnu_cxx::hash_set<Node, NodeHashFunction> NodeSet; +typedef std::unordered_set<Expr, ExprHashFunction> ExprSet; +typedef std::unordered_set<Node, NodeHashFunction> NodeSet; typedef std::pair<Node, Node> NodePair; typedef std::set<NodePair> NodePairSet; diff --git a/src/proof/sat_proof.h b/src/proof/sat_proof.h index 36de6278a..6b2b39fd4 100644 --- a/src/proof/sat_proof.h +++ b/src/proof/sat_proof.h @@ -2,9 +2,9 @@ /*! \file sat_proof.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Morgan Deters, Tim King + ** Tim King, Liana Hadarean, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -21,11 +21,10 @@ #include <stdint.h> -#include <ext/hash_map> -#include <ext/hash_set> #include <iosfwd> #include <set> #include <sstream> +#include <unordered_map> #include <vector> #include "context/cdhashmap.h" @@ -101,18 +100,18 @@ class TSatProof { typedef std::set<typename Solver::TLit> LitSet; typedef std::set<typename Solver::TVar> VarSet; - typedef std::hash_map<ClauseId, typename Solver::TCRef> IdCRefMap; - typedef std::hash_map<typename Solver::TCRef, ClauseId> ClauseIdMap; + typedef std::unordered_map<ClauseId, typename Solver::TCRef> IdCRefMap; + typedef std::unordered_map<typename Solver::TCRef, ClauseId> ClauseIdMap; typedef context::CDHashMap<ClauseId, typename Solver::TLit> IdUnitMap; typedef context::CDHashMap<int, ClauseId> UnitIdMap; typedef context::CDHashMap<ClauseId, ResolutionChain*> IdResMap; - typedef std::hash_map<ClauseId, uint64_t> IdProofRuleMap; + typedef std::unordered_map<ClauseId, uint64_t> IdProofRuleMap; typedef std::vector<ResolutionChain*> ResStack; typedef std::set<ClauseId> IdSet; typedef std::vector<typename Solver::TLit> LitVector; - typedef __gnu_cxx::hash_map<ClauseId, typename Solver::TClause&> + typedef std::unordered_map<ClauseId, typename Solver::TClause&> IdToMinisatClause; - typedef __gnu_cxx::hash_map<ClauseId, LitVector*> IdToConflicts; + typedef std::unordered_map<ClauseId, LitVector*> IdToConflicts; public: TSatProof(Solver* solver, context::Context* context, @@ -362,7 +361,7 @@ class TSatProof { IdToSatClause d_seenLemmas; private: - __gnu_cxx::hash_map<ClauseId, int> d_glueMap; + std::unordered_map<ClauseId, int> d_glueMap; struct Statistics { IntStat d_numLearnedClauses; IntStat d_numLearnedInProof; diff --git a/src/proof/sat_proof_implementation.h b/src/proof/sat_proof_implementation.h index 6cb10450a..c115bab4a 100644 --- a/src/proof/sat_proof_implementation.h +++ b/src/proof/sat_proof_implementation.h @@ -2,9 +2,9 @@ /*! \file sat_proof_implementation.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Guy Katz, Tim King + ** Liana Hadarean, Tim King, Guy Katz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -903,13 +903,11 @@ void TSatProof<Solver>::finalizeProof(typename Solver::TCRef conflict_ref) { ResChain<Solver>* res = new ResChain<Solver>(conflict_id); // Here, the call to resolveUnit() can reallocate memory in the // clause allocator. So reload conflict ptr each time. - size_t conflict_size = getClause(conflict_ref).size(); - for (size_t i = 0; i < conflict_size; ++i) { + for (size_t i = 0; i < getClause(conflict_ref).size(); ++i) { const typename Solver::TClause& conflict = getClause(conflict_ref); typename Solver::TLit lit = conflict[i]; ClauseId res_id = resolveUnit(~lit); res->addStep(lit, res_id, !sign(lit)); - conflict_size = conflict.size(); } registerResolution(d_emptyClauseId, res); diff --git a/src/proof/simplify_boolean_node.cpp b/src/proof/simplify_boolean_node.cpp index 34c3f526d..9aef51d78 100644 --- a/src/proof/simplify_boolean_node.cpp +++ b/src/proof/simplify_boolean_node.cpp @@ -1,10 +1,10 @@ /********************* */ -/*! \file simplify_boolean_node.h +/*! \file simplify_boolean_node.cpp ** \verbatim ** Top contributors (to current version): ** Guy Katz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/simplify_boolean_node.h b/src/proof/simplify_boolean_node.h index dcf7e93db..15eac2938 100644 --- a/src/proof/simplify_boolean_node.h +++ b/src/proof/simplify_boolean_node.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Guy Katz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/skolemization_manager.cpp b/src/proof/skolemization_manager.cpp index 12fea82ad..a666e23d3 100644 --- a/src/proof/skolemization_manager.cpp +++ b/src/proof/skolemization_manager.cpp @@ -2,9 +2,9 @@ /*! \file skolemization_manager.cpp ** \verbatim ** Top contributors (to current version): - ** Guy Katz + ** Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -57,11 +57,11 @@ void SkolemizationManager::clear() { d_skolemToDisequality.clear(); } -std::hash_map<Node, Node, NodeHashFunction>::const_iterator SkolemizationManager::begin() { +std::unordered_map<Node, Node, NodeHashFunction>::const_iterator SkolemizationManager::begin() { return d_disequalityToSkolem.begin(); } -std::hash_map<Node, Node, NodeHashFunction>::const_iterator SkolemizationManager::end() { +std::unordered_map<Node, Node, NodeHashFunction>::const_iterator SkolemizationManager::end() { return d_disequalityToSkolem.end(); } diff --git a/src/proof/skolemization_manager.h b/src/proof/skolemization_manager.h index b026e21c2..7ec594859 100644 --- a/src/proof/skolemization_manager.h +++ b/src/proof/skolemization_manager.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Guy Katz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -21,7 +21,8 @@ #define __CVC4__SKOLEMIZATION_MANAGER_H #include <iostream> -#include <map> +#include <unordered_map> + #include "proof/proof.h" #include "util/proof.h" #include "expr/node.h" @@ -39,12 +40,12 @@ public: bool isSkolem(Node skolem); void clear(); - std::hash_map<Node, Node, NodeHashFunction>::const_iterator begin(); - std::hash_map<Node, Node, NodeHashFunction>::const_iterator end(); + std::unordered_map<Node, Node, NodeHashFunction>::const_iterator begin(); + std::unordered_map<Node, Node, NodeHashFunction>::const_iterator end(); private: - std::hash_map<Node, Node, NodeHashFunction> d_disequalityToSkolem; - std::hash_map<Node, Node, NodeHashFunction> d_skolemToDisequality; + std::unordered_map<Node, Node, NodeHashFunction> d_disequalityToSkolem; + std::unordered_map<Node, Node, NodeHashFunction> d_skolemToDisequality; }; }/* CVC4 namespace */ diff --git a/src/proof/theory_proof.cpp b/src/proof/theory_proof.cpp index 1d694c947..7dee924be 100644 --- a/src/proof/theory_proof.cpp +++ b/src/proof/theory_proof.cpp @@ -2,9 +2,9 @@ /*! \file theory_proof.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Guy Katz, Morgan Deters + ** Guy Katz, Liana Hadarean, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/theory_proof.h b/src/proof/theory_proof.h index b9fb33406..15ac533b7 100644 --- a/src/proof/theory_proof.h +++ b/src/proof/theory_proof.h @@ -2,9 +2,9 @@ /*! \file theory_proof.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Guy Katz, Tim King + ** Guy Katz, Liana Hadarean, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,8 +20,9 @@ #ifndef __CVC4__THEORY_PROOF_H #define __CVC4__THEORY_PROOF_H -#include <ext/hash_set> #include <iosfwd> +#include <unordered_map> +#include <unordered_set> #include "expr/expr.h" #include "proof/clause_id.h" @@ -35,11 +36,11 @@ namespace theory { class Theory; } /* namespace CVC4::theory */ -typedef __gnu_cxx::hash_map < ClauseId, prop::SatClause* > IdToSatClause; +typedef std::unordered_map < ClauseId, prop::SatClause* > IdToSatClause; class TheoryProof; -typedef __gnu_cxx::hash_set<Expr, ExprHashFunction > ExprSet; +typedef std::unordered_set<Expr, ExprHashFunction > ExprSet; typedef std::map<theory::TheoryId, TheoryProof* > TheoryProofTable; typedef std::set<theory::TheoryId> TheoryIdSet; diff --git a/src/proof/uf_proof.cpp b/src/proof/uf_proof.cpp index cea873b6d..a24f58698 100644 --- a/src/proof/uf_proof.cpp +++ b/src/proof/uf_proof.cpp @@ -1,17 +1,17 @@ /********************* */ /*! \file uf_proof.cpp -** \verbatim -** Top contributors (to current version): -** Liana Hadarean, Guy Katz -** This file is part of the CVC4 project. -** Copyright (c) 2009-2016 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 -** -** [[ Add lengthier description here ]] - -** \todo document this file + ** \verbatim + ** Top contributors (to current version): + ** Liana Hadarean, Guy Katz, 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 + ** + ** [[ Add lengthier description here ]] + + ** \todo document this file **/ diff --git a/src/proof/uf_proof.h b/src/proof/uf_proof.h index c4bd28dc5..b817ceb69 100644 --- a/src/proof/uf_proof.h +++ b/src/proof/uf_proof.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Guy Katz, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,6 +19,8 @@ #ifndef __CVC4__UF__PROOF_H #define __CVC4__UF__PROOF_H +#include <unordered_set> + #include "expr/expr.h" #include "proof/proof_manager.h" #include "theory/uf/equality_engine.h" @@ -45,7 +47,7 @@ class TheoryUF; } } -typedef __gnu_cxx::hash_set<Type, TypeHashFunction > TypeSet; +typedef std::unordered_set<Type, TypeHashFunction > TypeSet; class UFProof : public TheoryProof { diff --git a/src/proof/unsat_core.cpp b/src/proof/unsat_core.cpp index 4c940e4be..b056e0ef4 100644 --- a/src/proof/unsat_core.cpp +++ b/src/proof/unsat_core.cpp @@ -2,9 +2,9 @@ /*! \file unsat_core.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Clark Barrett + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/proof/unsat_core.h b/src/proof/unsat_core.h index 50a01bedb..6f03dfa5e 100644 --- a/src/proof/unsat_core.h +++ b/src/proof/unsat_core.h @@ -2,9 +2,9 @@ /*! \file unsat_core.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Liana Hadarean + ** Morgan Deters, Paul Meng, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/prop/bvminisat/bvminisat.cpp b/src/prop/bvminisat/bvminisat.cpp index 368a79b80..21c41efd7 100644 --- a/src/prop/bvminisat/bvminisat.cpp +++ b/src/prop/bvminisat/bvminisat.cpp @@ -1,15 +1,13 @@ /********************* */ /*! \file bvminisat.cpp ** \verbatim - ** Original author: dejan - ** Major contributors: - ** Minor contributors (to current version): - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009-2014 The Analysis of Computer Systems Group (ACSys) - ** Courant Institute of Mathematical Sciences - ** New York University - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** Top contributors (to current version): + ** Dejan Jovanovic, Liana Hadarean, Tim King + ** 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 SAT Solver. ** diff --git a/src/prop/bvminisat/bvminisat.h b/src/prop/bvminisat/bvminisat.h index 732bd0313..54f4a9f71 100644 --- a/src/prop/bvminisat/bvminisat.h +++ b/src/prop/bvminisat/bvminisat.h @@ -1,15 +1,13 @@ /********************* */ /*! \file bvminisat.h ** \verbatim - ** Original author: dejan - ** Major contributors: - ** Minor contributors (to current version): - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009-2014 The Analysis of Computer Systems Group (ACSys) - ** Courant Institute of Mathematical Sciences - ** New York University - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** Top contributors (to current version): + ** Dejan Jovanovic, Liana Hadarean, Tim King + ** 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 SAT Solver. ** diff --git a/src/prop/bvminisat/core/Solver.cc b/src/prop/bvminisat/core/Solver.cc index d626a5d15..0213ef7e3 100644 --- a/src/prop/bvminisat/core/Solver.cc +++ b/src/prop/bvminisat/core/Solver.cc @@ -990,7 +990,7 @@ lbool Solver::search(int nof_conflicts, UIP uip) if(d_bvp){ ClauseId id = d_bvp->getSatProof()->registerClause(cr, LEARNT); PSTATS( - __gnu_cxx::hash_set<int> cl_levels; + std::unordered_set<int> cl_levels; for (int i = 0; i < learnt_clause.size(); ++i) { cl_levels.insert(level(var(learnt_clause[i]))); } diff --git a/src/prop/bvminisat/core/Solver.h b/src/prop/bvminisat/core/Solver.h index 555495149..485eb8535 100644 --- a/src/prop/bvminisat/core/Solver.h +++ b/src/prop/bvminisat/core/Solver.h @@ -21,7 +21,6 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef BVMinisat_Solver_h #define BVMinisat_Solver_h -#include <ext/hash_set> #include <vector> #include "context/context.h" diff --git a/src/prop/cnf_stream.cpp b/src/prop/cnf_stream.cpp index bc819801b..3c918ecde 100644 --- a/src/prop/cnf_stream.cpp +++ b/src/prop/cnf_stream.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Liana Hadarean, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/prop/cnf_stream.h b/src/prop/cnf_stream.h index a965018f8..80f8742a3 100644 --- a/src/prop/cnf_stream.h +++ b/src/prop/cnf_stream.h @@ -2,9 +2,9 @@ /*! \file cnf_stream.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Tim King, Dejan Jovanovic, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -25,8 +25,6 @@ #ifndef __CVC4__PROP__CNF_STREAM_H #define __CVC4__PROP__CNF_STREAM_H -#include <ext/hash_map> - #include "context/cdinsert_hashmap.h" #include "context/cdlist.h" #include "expr/node.h" diff --git a/src/prop/cryptominisat.cpp b/src/prop/cryptominisat.cpp index eff079cc9..6627e86bb 100644 --- a/src/prop/cryptominisat.cpp +++ b/src/prop/cryptominisat.cpp @@ -1,15 +1,13 @@ /********************* */ /*! \file cryptominisat.cpp ** \verbatim - ** Original author: lianah - ** Major contributors: - ** Minor contributors (to current version): - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009-2014 The Analysis of Computer Systems Group (ACSys) - ** Courant Institute of Mathematical Sciences - ** New York University - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** Top contributors (to current version): + ** Liana Hadarean, Tim King + ** 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 SAT Solver. ** diff --git a/src/prop/cryptominisat.h b/src/prop/cryptominisat.h index 7ad861def..bb2f47783 100644 --- a/src/prop/cryptominisat.h +++ b/src/prop/cryptominisat.h @@ -1,15 +1,13 @@ /********************* */ /*! \file cryptominisat.h ** \verbatim - ** Original author: lianah - ** Major contributors: - ** Minor contributors (to current version): - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009-2014 The Analysis of Computer Systems Group (ACSys) - ** Courant Institute of Mathematical Sciences - ** New York University - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** Top contributors (to current version): + ** Liana Hadarean, Tim King + ** 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 SAT Solver. ** diff --git a/src/prop/minisat/core/Solver.cc b/src/prop/minisat/core/Solver.cc index 0bf5d5d7c..2b58f2f17 100644 --- a/src/prop/minisat/core/Solver.cc +++ b/src/prop/minisat/core/Solver.cc @@ -23,6 +23,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include <math.h> #include <iostream> +#include <unordered_set> #include "base/output.h" #include "options/prop_options.h" @@ -1219,7 +1220,7 @@ lbool Solver::search(int nof_conflicts) PROOF( ClauseId id = ProofManager::getSatProof()->registerClause(cr, LEARNT); PSTATS( - __gnu_cxx::hash_set<int> cl_levels; + std::unordered_set<int> cl_levels; for (int i = 0; i < learnt_clause.size(); ++i) { cl_levels.insert(level(var(learnt_clause[i]))); } diff --git a/src/prop/minisat/minisat.cpp b/src/prop/minisat/minisat.cpp index a88a872c8..514338fd9 100644 --- a/src/prop/minisat/minisat.cpp +++ b/src/prop/minisat/minisat.cpp @@ -1,15 +1,13 @@ /********************* */ /*! \file minisat.cpp ** \verbatim - ** Original author: dejan - ** Major contributors: - ** Minor contributors (to current version): - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009-2014 The Analysis of Computer Systems Group (ACSys) - ** Courant Institute of Mathematical Sciences - ** New York University - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** Top contributors (to current version): + ** Dejan Jovanovic, Tim King, Morgan Deters + ** 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 SAT Solver. ** diff --git a/src/prop/minisat/minisat.h b/src/prop/minisat/minisat.h index 1627a6575..ca179fbc8 100644 --- a/src/prop/minisat/minisat.h +++ b/src/prop/minisat/minisat.h @@ -1,15 +1,13 @@ /********************* */ /*! \file minisat.h ** \verbatim - ** Original author: dejan - ** Major contributors: - ** Minor contributors (to current version): - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009-2014 The Analysis of Computer Systems Group (ACSys) - ** Courant Institute of Mathematical Sciences - ** New York University - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** Top contributors (to current version): + ** Dejan Jovanovic, Tim King, Morgan Deters + ** 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 SAT Solver. ** diff --git a/src/prop/prop_engine.cpp b/src/prop/prop_engine.cpp index 6cdf17f30..1a56fa141 100644 --- a/src/prop/prop_engine.cpp +++ b/src/prop/prop_engine.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/prop/prop_engine.h b/src/prop/prop_engine.h index f966def26..4802ae52c 100644 --- a/src/prop/prop_engine.h +++ b/src/prop/prop_engine.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/prop/registrar.h b/src/prop/registrar.h index bd8088921..ec774e979 100644 --- a/src/prop/registrar.h +++ b/src/prop/registrar.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/prop/sat_solver.h b/src/prop/sat_solver.h index 4afaea5a0..c790f59f6 100644 --- a/src/prop/sat_solver.h +++ b/src/prop/sat_solver.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Dejan Jovanovic, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/prop/sat_solver_factory.cpp b/src/prop/sat_solver_factory.cpp index 7fdc44e66..27e2daf11 100644 --- a/src/prop/sat_solver_factory.cpp +++ b/src/prop/sat_solver_factory.cpp @@ -2,9 +2,9 @@ /*! \file sat_solver_factory.cpp ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Tim King, Morgan Deters + ** Dejan Jovanovic, Tim King, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/prop/sat_solver_factory.h b/src/prop/sat_solver_factory.h index a04bcaaf4..fac8c9083 100644 --- a/src/prop/sat_solver_factory.h +++ b/src/prop/sat_solver_factory.h @@ -2,9 +2,9 @@ /*! \file sat_solver_factory.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Tim King, Morgan Deters + ** Dejan Jovanovic, Tim King, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/prop/sat_solver_types.h b/src/prop/sat_solver_types.h index 557f9af65..d2dbace1b 100644 --- a/src/prop/sat_solver_types.h +++ b/src/prop/sat_solver_types.h @@ -2,9 +2,9 @@ /*! \file sat_solver_types.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Kshitij Bansal, Tim King + ** Dejan Jovanovic, Kshitij Bansal, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/prop/theory_proxy.cpp b/src/prop/theory_proxy.cpp index 5f5eac733..8f74b716f 100644 --- a/src/prop/theory_proxy.cpp +++ b/src/prop/theory_proxy.cpp @@ -2,9 +2,9 @@ /*! \file theory_proxy.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Liana Hadarean + ** Morgan Deters, Tim King, Guy Katz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/prop/theory_proxy.h b/src/prop/theory_proxy.h index 88c6ca94a..67d3b3b7e 100644 --- a/src/prop/theory_proxy.h +++ b/src/prop/theory_proxy.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -24,6 +24,7 @@ #define __CVC4_USE_MINISAT #include <iosfwd> +#include <unordered_set> #include "context/cdqueue.h" #include "expr/expr_stream.h" @@ -138,7 +139,7 @@ public: * Set of all lemmas that have been "shared" in the portfolio---i.e., * all imported and exported lemmas. */ - std::hash_set<Node, NodeHashFunction> d_shared; + std::unordered_set<Node, NodeHashFunction> d_shared; /** * Statistic: the number of replayed decisions (via --replay). diff --git a/src/smt/command.cpp b/src/smt/command.cpp index 9c6a143c5..2ca8b1fe3 100644 --- a/src/smt/command.cpp +++ b/src/smt/command.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Francois Bobot ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/command.h b/src/smt/command.h index c4db23e04..36e679885 100644 --- a/src/smt/command.h +++ b/src/smt/command.h @@ -2,9 +2,9 @@ /*! \file command.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Francois Bobot + ** Morgan Deters, Andrew Reynolds, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/command_list.cpp b/src/smt/command_list.cpp index 78e5914aa..5bbae5fa8 100644 --- a/src/smt/command_list.cpp +++ b/src/smt/command_list.cpp @@ -2,9 +2,9 @@ /*! \file command_list.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/command_list.h b/src/smt/command_list.h index ea6b64940..098b2943b 100644 --- a/src/smt/command_list.h +++ b/src/smt/command_list.h @@ -2,9 +2,9 @@ /*! \file command_list.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/dump.cpp b/src/smt/dump.cpp index ce146da0e..7d7b6891b 100644 --- a/src/smt/dump.cpp +++ b/src/smt/dump.cpp @@ -2,9 +2,9 @@ /*! \file dump.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Kshitij Bansal + ** Tim King, Clark Barrett, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/dump.h b/src/smt/dump.h index 2abfe5408..3c4d14693 100644 --- a/src/smt/dump.h +++ b/src/smt/dump.h @@ -2,9 +2,9 @@ /*! \file dump.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/logic_exception.h b/src/smt/logic_exception.h index 93db29a9b..5d5b02162 100644 --- a/src/smt/logic_exception.h +++ b/src/smt/logic_exception.h @@ -2,9 +2,9 @@ /*! \file logic_exception.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/logic_request.cpp b/src/smt/logic_request.cpp index dc6a2d6b7..6f67393ee 100644 --- a/src/smt/logic_request.cpp +++ b/src/smt/logic_request.cpp @@ -2,9 +2,9 @@ /*! \file logic_request.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/logic_request.h b/src/smt/logic_request.h index 7b41886bd..91f49bc20 100644 --- a/src/smt/logic_request.h +++ b/src/smt/logic_request.h @@ -2,9 +2,9 @@ /*! \file logic_request.h ** \verbatim ** Top contributors (to current version): - ** Martin Brain, Tim King + ** Martin Brain, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/managed_ostreams.cpp b/src/smt/managed_ostreams.cpp index cae6ac67f..d4f23acb9 100644 --- a/src/smt/managed_ostreams.cpp +++ b/src/smt/managed_ostreams.cpp @@ -2,9 +2,9 @@ /*! \file managed_ostreams.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/managed_ostreams.h b/src/smt/managed_ostreams.h index 56c517a87..3114821b3 100644 --- a/src/smt/managed_ostreams.h +++ b/src/smt/managed_ostreams.h @@ -2,9 +2,9 @@ /*! \file managed_ostreams.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/model.cpp b/src/smt/model.cpp index a38862307..7bfe307c3 100644 --- a/src/smt/model.cpp +++ b/src/smt/model.cpp @@ -2,9 +2,9 @@ /*! \file model.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/model.h b/src/smt/model.h index 523751d9c..f379ae16d 100644 --- a/src/smt/model.h +++ b/src/smt/model.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp index 2de0114d0..cd2da586e 100644 --- a/src/smt/smt_engine.cpp +++ b/src/smt/smt_engine.cpp @@ -2,9 +2,9 @@ /*! \file smt_engine.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Clark Barrett, Tim King + ** Morgan Deters, Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -18,7 +18,8 @@ #include <algorithm> #include <cctype> -#include <ext/hash_map> +#include <unordered_map> +#include <unordered_set> #include <iterator> #include <sstream> #include <stack> @@ -90,6 +91,7 @@ #include "theory/quantifiers/fun_def_process.h" #include "theory/quantifiers/macros.h" #include "theory/quantifiers/quantifiers_rewriter.h" +#include "theory/quantifiers/term_database.h" #include "theory/sort_inference.h" #include "theory/strings/theory_strings.h" #include "theory/substitutions.h" @@ -468,8 +470,8 @@ class PrintSuccessListener : public Listener { class SmtEnginePrivate : public NodeManagerListener { SmtEngine& d_smt; - typedef hash_map<Node, Node, NodeHashFunction> NodeToNodeHashMap; - typedef hash_map<Node, bool, NodeHashFunction> NodeToBoolHashMap; + typedef unordered_map<Node, Node, NodeHashFunction> NodeToNodeHashMap; + typedef unordered_map<Node, bool, NodeHashFunction> NodeToBoolHashMap; /** * Manager for limiting time and abstract resource usage. @@ -550,8 +552,6 @@ class SmtEnginePrivate : public NodeManagerListener { /** TODO: whether certain preprocess steps are necessary */ //bool d_needsExpandDefs; - //bool d_needsRewriteBoolTerms; - //bool d_needsConstrainSubTypes; public: /** @@ -613,14 +613,6 @@ private: void compressBeforeRealAssertions(size_t before); /** - * Any variable in an assertion that is declared as a subtype type - * (predicate subtype or integer subrange type) must be constrained - * to be in that type. - */ - void constrainSubtypes(TNode n, AssertionPipeline& assertions) - throw(); - - /** * Trace nodes back to their assertions using CircuitPropagator's * BackEdgesMap. */ @@ -632,7 +624,7 @@ private: * conjuncts. */ size_t removeFromConjunction(Node& n, - const std::hash_set<unsigned long>& toRemove); + const std::unordered_set<unsigned long>& toRemove); /** Scrub miplib encodings. */ void doMiplibTrick(); @@ -667,9 +659,7 @@ public: d_abstractValueMap(&d_fakeContext), d_abstractValues(), d_simplifyAssertionsDepth(0), - //d_needsExpandDefs(true), - //d_needsRewriteBoolTerms(true), - //d_needsConstrainSubTypes(true), //TODO + //d_needsExpandDefs(true), //TODO? d_iteSkolemMap(), d_iteRemover(smt.d_userContext), d_pbsProcessor(smt.d_userContext), @@ -794,9 +784,7 @@ public: } } - void nmNotifyDeleteNode(TNode n) { - d_smt.d_smtAttributes->deleteAllAttributes(n); - } + void nmNotifyDeleteNode(TNode n) {} Node applySubstitutions(TNode node) const { return Rewriter::rewrite(d_topLevelSubstitutions.apply(node)); @@ -981,14 +969,12 @@ SmtEngine::SmtEngine(ExprManager* em) throw() : d_status(), d_replayStream(NULL), d_private(NULL), - d_smtAttributes(NULL), d_statisticsRegistry(NULL), d_stats(NULL), d_channels(new LemmaChannels()) { SmtScope smts(this); d_originalOptions.copyValues(em->getOptions()); - d_smtAttributes = new expr::attr::SmtAttributes(d_context); d_private = new smt::SmtEnginePrivate(*this); d_statisticsRegistry = new StatisticsRegistry(); d_stats = new SmtEngineStatistics(); @@ -1204,9 +1190,6 @@ SmtEngine::~SmtEngine() throw() { delete d_private; d_private = NULL; - delete d_smtAttributes; - d_smtAttributes = NULL; - delete d_userContext; d_userContext = NULL; delete d_context; @@ -2262,7 +2245,7 @@ bool SmtEngine::isDefinedFunction( Expr func ){ return d_definedFunctions->find(nf) != d_definedFunctions->end(); } -Node SmtEnginePrivate::expandDefinitions(TNode n, hash_map<Node, Node, NodeHashFunction>& cache, bool expandOnly) +Node SmtEnginePrivate::expandDefinitions(TNode n, unordered_map<Node, Node, NodeHashFunction>& cache, bool expandOnly) throw(TypeCheckingException, LogicException, UnsafeInterruptException) { stack< triple<Node, Node, bool> > worklist; @@ -2302,7 +2285,7 @@ Node SmtEnginePrivate::expandDefinitions(TNode n, hash_map<Node, Node, NodeHashF } // maybe it's in the cache - hash_map<Node, Node, NodeHashFunction>::iterator cacheHit = cache.find(n); + unordered_map<Node, Node, NodeHashFunction>::iterator cacheHit = cache.find(n); if(cacheHit != cache.end()) { TNode ret = (*cacheHit).second; result.push(ret.isNull() ? n : ret); @@ -2426,8 +2409,7 @@ Node SmtEnginePrivate::expandDefinitions(TNode n, hash_map<Node, Node, NodeHashF return result.top(); } -//TODO: clean this up -typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap; +typedef std::unordered_map<Node, Node, NodeHashFunction> NodeMap; void SmtEnginePrivate::removeITEs() { d_smt.finalOptionsAreSet(); @@ -2678,7 +2660,7 @@ bool SmtEnginePrivate::nonClausalSimplify() { Trace("simplify") << "Resize non-clausal learned literals to " << j << std::endl; d_nonClausalLearnedLiterals.resize(j); - hash_set<TNode, TNodeHashFunction> s; + unordered_set<TNode, TNodeHashFunction> s; Trace("debugging") << "NonClausal simplify pre-preprocess\n"; for (unsigned i = 0; i < d_assertions.size(); ++ i) { Node assertion = d_assertions[i]; @@ -2854,63 +2836,6 @@ void SmtEnginePrivate::compressBeforeRealAssertions(size_t before){ Assert(d_assertions.size() == before); } -void SmtEnginePrivate::constrainSubtypes(TNode top, AssertionPipeline& assertions) - throw() { - - Trace("constrainSubtypes") << "constrainSubtypes(): looking at " << top << endl; - - set<TNode> done; - stack<TNode> worklist; - worklist.push(top); - done.insert(top); - - do { - TNode n = worklist.top(); - worklist.pop(); - - TypeNode t = n.getType(); - if(t.isPredicateSubtype()) { - WarningOnce() << "Warning: CVC4 doesn't yet do checking that predicate subtypes are nonempty domains" << endl; - Node pred = t.getSubtypePredicate(); - Kind k; - // pred can be a LAMBDA, a function constant, or a datatype tester - Trace("constrainSubtypes") << "constrainSubtypes(): pred.getType() == " << pred.getType() << endl; - if(d_smt.d_definedFunctions->find(pred) != d_smt.d_definedFunctions->end()) { - k = kind::APPLY; - } else if(pred.getType().isTester()) { - k = kind::APPLY_TESTER; - } else { - k = kind::APPLY_UF; - } - Node app = NodeManager::currentNM()->mkNode(k, pred, n); - Trace("constrainSubtypes") << "constrainSubtypes(): assert(" << k << ") " << app << endl; - assertions.push_back(app); - } else if(t.isSubrange()) { - SubrangeBounds bounds = t.getSubrangeBounds(); - Trace("constrainSubtypes") << "constrainSubtypes(): got bounds " << bounds << endl; - if(bounds.lower.hasBound()) { - Node c = NodeManager::currentNM()->mkConst(Rational(bounds.lower.getBound())); - Node lb = NodeManager::currentNM()->mkNode(kind::LEQ, c, n); - Trace("constrainSubtypes") << "constrainSubtypes(): assert " << lb << endl; - assertions.push_back(lb); - } - if(bounds.upper.hasBound()) { - Node c = NodeManager::currentNM()->mkConst(Rational(bounds.upper.getBound())); - Node ub = NodeManager::currentNM()->mkNode(kind::LEQ, n, c); - Trace("constrainSubtypes") << "constrainSubtypes(): assert " << ub << endl; - assertions.push_back(ub); - } - } - - for(TNode::iterator i = n.begin(); i != n.end(); ++i) { - if(done.find(*i) == done.end()) { - worklist.push(*i); - done.insert(*i); - } - } - } while(! worklist.empty()); -} - void SmtEnginePrivate::traceBackToAssertions(const std::vector<Node>& nodes, std::vector<TNode>& assertions) { const booleans::CircuitPropagator::BackEdgesMap& backEdges = d_propagator.getBackEdges(); for(vector<Node>::const_iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -2926,7 +2851,7 @@ void SmtEnginePrivate::traceBackToAssertions(const std::vector<Node>& nodes, std } } -size_t SmtEnginePrivate::removeFromConjunction(Node& n, const std::hash_set<unsigned long>& toRemove) { +size_t SmtEnginePrivate::removeFromConjunction(Node& n, const std::unordered_set<unsigned long>& toRemove) { Assert(n.getKind() == kind::AND); size_t removals = 0; for(Node::iterator j = n.begin(); j != n.end(); ++j) { @@ -2980,12 +2905,12 @@ void SmtEnginePrivate::doMiplibTrick() { Assert(!options::incrementalSolving()); const booleans::CircuitPropagator::BackEdgesMap& backEdges = d_propagator.getBackEdges(); - hash_set<unsigned long> removeAssertions; + unordered_set<unsigned long> removeAssertions; NodeManager* nm = NodeManager::currentNM(); Node zero = nm->mkConst(Rational(0)), one = nm->mkConst(Rational(1)); - hash_map<TNode, Node, TNodeHashFunction> intVars; + unordered_map<TNode, Node, TNodeHashFunction> intVars; for(vector<Node>::const_iterator i = d_boolVars.begin(); i != d_boolVars.end(); ++i) { if(d_propagator.isAssigned(*i)) { Debug("miplib") << "ineligible: " << *i << " because assigned " << d_propagator.getAssignment(*i) << endl; @@ -3480,9 +3405,9 @@ Result SmtEngine::quickCheck() { } -void SmtEnginePrivate::collectSkolems(TNode n, set<TNode>& skolemSet, hash_map<Node, bool, NodeHashFunction>& cache) +void SmtEnginePrivate::collectSkolems(TNode n, set<TNode>& skolemSet, unordered_map<Node, bool, NodeHashFunction>& cache) { - hash_map<Node, bool, NodeHashFunction>::iterator it; + unordered_map<Node, bool, NodeHashFunction>::iterator it; it = cache.find(n); if (it != cache.end()) { return; @@ -3505,9 +3430,9 @@ void SmtEnginePrivate::collectSkolems(TNode n, set<TNode>& skolemSet, hash_map<N cache[n] = true; } -bool SmtEnginePrivate::checkForBadSkolems(TNode n, TNode skolem, hash_map<Node, bool, NodeHashFunction>& cache) +bool SmtEnginePrivate::checkForBadSkolems(TNode n, TNode skolem, unordered_map<Node, bool, NodeHashFunction>& cache) { - hash_map<Node, bool, NodeHashFunction>::iterator it; + unordered_map<Node, bool, NodeHashFunction>::iterator it; it = cache.find(n); if (it != cache.end()) { return (*it).second; @@ -3575,8 +3500,8 @@ void SmtEnginePrivate::processAssertions() { Trace("smt-proc") << "SmtEnginePrivate::processAssertions() : pre-definition-expansion" << endl; dumpAssertions("pre-definition-expansion", d_assertions); { - preproc::ExpandingDefinitionsPass pass(d_resourceManager, &d_smt, d_smt.d_stats->d_definitionExpansionTime); - pass.apply(&d_assertions); + preproc::ExpandingDefinitionsPass pass(d_resourceManager, &d_smt, d_smt.d_stats->d_definitionExpansionTime); + pass.apply(&d_assertions); } Trace("smt-proc") << "SmtEnginePrivate::processAssertions() : post-definition-expansion" << endl; @@ -3636,18 +3561,7 @@ void SmtEnginePrivate::processAssertions() { pass1.apply(&d_assertions); } - Debug("smt") << " d_assertions : " << d_assertions.size() << endl; - - dumpAssertions("pre-constrain-subtypes", d_assertions); - { - preproc::ConstrainSubtypesPass pass(d_resourceManager, &d_smt); - pass.apply(&d_assertions); - } - dumpAssertions("post-constrain-subtypes", d_assertions); - - Debug("smt") << " d_assertions : " << d_assertions.size() << endl; - - bool noConflict = true; + bool noConflict = true; // Unconstrained simplification if(options::unconstrainedSimp()) { @@ -3781,7 +3695,7 @@ void SmtEnginePrivate::processAssertions() { // For each skolem variable sk, let iteExpr = iteMap(sk) be the ite expr mapped to by sk. // cache for expression traversal - hash_map<Node, bool, NodeHashFunction> cache; + unordered_map<Node, bool, NodeHashFunction> cache; // First, find all skolems that appear in the substitution map - their associated iteExpr will need // to be moved to the main assertion set @@ -4072,11 +3986,17 @@ Result SmtEngine::checkSynth(const Expr& e) throw(TypeCheckingException, ModalEx if( conj.getKind()==kind::FORALL ){ //possibly run quantifier elimination to make formula into single invocation if( conj[1].getKind()==kind::EXISTS ){ - Node conj_se = conj[1][1]; + Node conj_se = Node::fromExpr( expandDefinitions( conj[1][1].toExpr() ) ); Trace("smt-synth") << "Compute single invocation for " << conj_se << "..." << std::endl; - quantifiers::SingleInvocationPartition sip( kind::APPLY ); - sip.init( conj_se ); + quantifiers::SingleInvocationPartition sip; + std::vector< Node > funcs; + for( unsigned i=0; i<conj[0].getNumChildren(); i++ ){ + Node sf = conj[0][i].getAttribute(theory::SygusSynthFunAttribute()); + Assert( !sf.isNull() ); + funcs.push_back( sf ); + } + sip.init( funcs, conj_se ); Trace("smt-synth") << "...finished, got:" << std::endl; sip.debugPrint("smt-synth"); @@ -4209,7 +4129,7 @@ Expr SmtEngine::expandDefinitions(const Expr& ex) throw(TypeCheckingException, L if(Dump.isOn("benchmark")) { Dump("benchmark") << ExpandDefinitionsCommand(e); } - hash_map<Node, Node, NodeHashFunction> cache; + unordered_map<Node, Node, NodeHashFunction> cache; Node n = d_private->expandDefinitions(Node::fromExpr(e), cache, /* expandOnly = */ true); n = postprocess(n, TypeNode::fromType(e.getType())); @@ -4235,7 +4155,9 @@ Expr SmtEngine::getValue(const Expr& ex) const throw(ModalException, TypeCheckin d_problemExtended) { const char* msg = "Cannot get value unless immediately preceded by SAT/INVALID or UNKNOWN response."; - throw ModalException(msg); + //throw ModalException(msg); + Warning() << CommandFailure(msg); + return ex; } // Substitute out any abstract values in ex. @@ -4252,7 +4174,7 @@ Expr SmtEngine::getValue(const Expr& ex) const throw(ModalException, TypeCheckin TypeNode expectedType = n.getType(); // Expand, then normalize - hash_map<Node, Node, NodeHashFunction> cache; + unordered_map<Node, Node, NodeHashFunction> cache; n = d_private->expandDefinitions(n, cache); // There are two ways model values for terms are computed (for historical // reasons). One way is that used in check-model; the other is that @@ -4344,7 +4266,9 @@ CVC4::SExpr SmtEngine::getAssignment() { const char* msg = "Cannot get the current assignment unless immediately " "preceded by SAT/INVALID or UNKNOWN response."; - throw ModalException(msg); + //throw ModalException(msg); + Warning() << CommandFailure(msg); + return SExpr(vector<SExpr>()); } if(d_assignments == NULL) { @@ -4363,7 +4287,7 @@ CVC4::SExpr SmtEngine::getAssignment() { Trace("smt") << "--- getting value of " << *i << endl; // Expand, then normalize - hash_map<Node, Node, NodeHashFunction> cache; + unordered_map<Node, Node, NodeHashFunction> cache; Node n = d_private->expandDefinitions(*i, cache); n = Rewriter::rewrite(n); @@ -4439,7 +4363,9 @@ Model* SmtEngine::getModel() { const char* msg = "Cannot get the current model unless immediately " "preceded by SAT/INVALID or UNKNOWN response."; - throw ModalException(msg); + //throw ModalException(msg); + Warning() << CommandFailure(msg); + return NULL; } if(!options::produceModels()) { const char* msg = @@ -4603,7 +4529,7 @@ void SmtEngine::checkModel(bool hardFailure) { // Apply any define-funs from the problem. { - hash_map<Node, Node, NodeHashFunction> cache; + unordered_map<Node, Node, NodeHashFunction> cache; n = d_private->expandDefinitions(n, cache); } Notice() << "SmtEngine::checkModel(): -- expands to " << n << endl; @@ -4699,7 +4625,9 @@ UnsatCore SmtEngine::getUnsatCore() { if(d_status.isNull() || d_status.asSatisfiabilityResult() != Result::UNSAT || d_problemExtended) { - throw ModalException("Cannot get an unsat core unless immediately preceded by UNSAT/VALID response."); + //throw ModalException("Cannot get an unsat core unless immediately preceded by UNSAT/VALID response."); + Warning() << CommandFailure("Cannot get an unsat core unless immediately preceded by UNSAT/VALID response."); + return UnsatCore(); } d_proofManager->traceUnsatCore();// just to trigger core creation @@ -4723,7 +4651,9 @@ Proof* SmtEngine::getProof() { if(d_status.isNull() || d_status.asSatisfiabilityResult() != Result::UNSAT || d_problemExtended) { - throw ModalException("Cannot get a proof unless immediately preceded by UNSAT/VALID response."); + //throw ModalException("Cannot get a proof unless immediately preceded by UNSAT/VALID response."); + Warning() << CommandFailure("Cannot get a proof unless immediately preceded by UNSAT/VALID response."); + return NULL; } return ProofManager::getProof(this); diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h index 6e23c493d..06b5a4b81 100644 --- a/src/smt/smt_engine.h +++ b/src/smt/smt_engine.h @@ -2,9 +2,9 @@ /*! \file smt_engine.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -74,13 +74,6 @@ namespace prop { class PropEngine; }/* CVC4::prop namespace */ -namespace expr { - namespace attr { - class AttributeManager; - struct SmtAttributes; - }/* CVC4::expr::attr namespace */ -}/* CVC4::expr namespace */ - namespace smt { /** * Representation of a defined function. We keep these around in @@ -372,20 +365,9 @@ class CVC4_PUBLIC SmtEngine { // to access d_modelCommands friend class ::CVC4::Model; friend class ::CVC4::theory::TheoryModel; - // to access SmtAttributes - friend class expr::attr::AttributeManager; // to access getModel(), which is private (for now) friend class GetModelCommand; - /** - * There's something of a handshake between the expr package's - * AttributeManager and the SmtEngine because the expr package - * doesn't have a Context on its own (that's owned by the - * SmtEngine). Thus all context-dependent attributes are stored - * here. - */ - expr::attr::SmtAttributes* d_smtAttributes; - StatisticsRegistry* d_statisticsRegistry; smt::SmtEngineStatistics* d_stats; diff --git a/src/smt/smt_engine_check_proof.cpp b/src/smt/smt_engine_check_proof.cpp index 808f5162c..9a336dd4d 100644 --- a/src/smt/smt_engine_check_proof.cpp +++ b/src/smt/smt_engine_check_proof.cpp @@ -2,9 +2,9 @@ /*! \file smt_engine_check_proof.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Guy Katz + ** Morgan Deters, Guy Katz, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/smt_engine_scope.cpp b/src/smt/smt_engine_scope.cpp index c31ea5736..87823775a 100644 --- a/src/smt/smt_engine_scope.cpp +++ b/src/smt/smt_engine_scope.cpp @@ -2,9 +2,9 @@ /*! \file smt_engine_scope.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/smt_engine_scope.h b/src/smt/smt_engine_scope.h index 9407ff498..a3f716238 100644 --- a/src/smt/smt_engine_scope.h +++ b/src/smt/smt_engine_scope.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/smt_statistics_registry.cpp b/src/smt/smt_statistics_registry.cpp index d34498697..caf3c0f5e 100644 --- a/src/smt/smt_statistics_registry.cpp +++ b/src/smt/smt_statistics_registry.cpp @@ -2,9 +2,9 @@ /*! \file smt_statistics_registry.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/smt_statistics_registry.h b/src/smt/smt_statistics_registry.h index 7483e8215..b9f607fbb 100644 --- a/src/smt/smt_statistics_registry.h +++ b/src/smt/smt_statistics_registry.h @@ -2,9 +2,9 @@ /*! \file smt_statistics_registry.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/term_formula_removal.cpp b/src/smt/term_formula_removal.cpp index bd133b0af..a008868c7 100644 --- a/src/smt/term_formula_removal.cpp +++ b/src/smt/term_formula_removal.cpp @@ -2,9 +2,9 @@ /*! \file term_formula_removal.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Andrew Reynolds, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt/term_formula_removal.h b/src/smt/term_formula_removal.h index 9c96bbf15..854ddc61e 100644 --- a/src/smt/term_formula_removal.h +++ b/src/smt/term_formula_removal.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -18,6 +18,7 @@ #pragma once +#include <unordered_map> #include <vector> #include "context/cdinsert_hashmap.h" @@ -33,7 +34,7 @@ namespace theory { class ContainsTermITEVisitor; }/* CVC4::theory namespace */ -typedef std::hash_map<Node, unsigned, NodeHashFunction> IteSkolemMap; +typedef std::unordered_map<Node, unsigned, NodeHashFunction> IteSkolemMap; class RemoveTermFormulas { typedef context::CDInsertHashMap< std::pair<Node, int>, Node, PairHashFunction<Node, int, NodeHashFunction, BoolHashFunction> > ITECache; diff --git a/src/smt/update_ostream.h b/src/smt/update_ostream.h index 9574c5460..ce4504279 100644 --- a/src/smt/update_ostream.h +++ b/src/smt/update_ostream.h @@ -2,9 +2,9 @@ /*! \file update_ostream.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt_util/boolean_simplification.cpp b/src/smt_util/boolean_simplification.cpp index c5c169301..40f96a47c 100644 --- a/src/smt_util/boolean_simplification.cpp +++ b/src/smt_util/boolean_simplification.cpp @@ -2,9 +2,9 @@ /*! \file boolean_simplification.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt_util/boolean_simplification.h b/src/smt_util/boolean_simplification.h index 7207dc336..2d350c9d9 100644 --- a/src/smt_util/boolean_simplification.h +++ b/src/smt_util/boolean_simplification.h @@ -2,9 +2,9 @@ /*! \file boolean_simplification.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt_util/lemma_channels.cpp b/src/smt_util/lemma_channels.cpp index 083c4adfb..020a87589 100644 --- a/src/smt_util/lemma_channels.cpp +++ b/src/smt_util/lemma_channels.cpp @@ -2,9 +2,9 @@ /*! \file lemma_channels.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt_util/lemma_channels.h b/src/smt_util/lemma_channels.h index 54a9db137..4d31cefdd 100644 --- a/src/smt_util/lemma_channels.h +++ b/src/smt_util/lemma_channels.h @@ -2,9 +2,9 @@ /*! \file lemma_channels.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt_util/lemma_input_channel.h b/src/smt_util/lemma_input_channel.h index 5d2b092e1..af2ac6442 100644 --- a/src/smt_util/lemma_input_channel.h +++ b/src/smt_util/lemma_input_channel.h @@ -2,9 +2,9 @@ /*! \file lemma_input_channel.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt_util/lemma_output_channel.h b/src/smt_util/lemma_output_channel.h index 6664b0d48..0e49e99cb 100644 --- a/src/smt_util/lemma_output_channel.h +++ b/src/smt_util/lemma_output_channel.h @@ -2,9 +2,9 @@ /*! \file lemma_output_channel.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt_util/nary_builder.cpp b/src/smt_util/nary_builder.cpp index 686dcf506..22fd6c6b8 100644 --- a/src/smt_util/nary_builder.cpp +++ b/src/smt_util/nary_builder.cpp @@ -2,9 +2,9 @@ /*! \file nary_builder.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/smt_util/nary_builder.h b/src/smt_util/nary_builder.h index d8201fbc5..dde7e1ccd 100644 --- a/src/smt_util/nary_builder.h +++ b/src/smt_util/nary_builder.h @@ -2,9 +2,9 @@ /*! \file nary_builder.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,9 @@ #pragma once +#include <unordered_map> #include <vector> + #include "expr/node.h" namespace CVC4{ @@ -47,7 +49,7 @@ private: Node case_assoccomm(TNode n); Node case_other(TNode n); - typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeMap; NodeMap d_cache; };/* class RePairAssocCommutativeOperators */ diff --git a/src/smt_util/node_visitor.h b/src/smt_util/node_visitor.h index 1906124ab..8c02af82d 100644 --- a/src/smt_util/node_visitor.h +++ b/src/smt_util/node_visitor.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Morgan Deters, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/approx_simplex.cpp b/src/theory/arith/approx_simplex.cpp index 9b8efb783..a500ec55d 100644 --- a/src/theory/arith/approx_simplex.cpp +++ b/src/theory/arith/approx_simplex.cpp @@ -2,9 +2,9 @@ /*! \file approx_simplex.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/approx_simplex.h b/src/theory/arith/approx_simplex.h index 8832fce71..234fd10c0 100644 --- a/src/theory/arith/approx_simplex.h +++ b/src/theory/arith/approx_simplex.h @@ -2,9 +2,9 @@ /*! \file approx_simplex.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/arith_ite_utils.cpp b/src/theory/arith/arith_ite_utils.cpp index 6695e641f..3e767b6db 100644 --- a/src/theory/arith/arith_ite_utils.cpp +++ b/src/theory/arith/arith_ite_utils.cpp @@ -2,9 +2,9 @@ /*! \file arith_ite_utils.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Kshitij Bansal + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/arith_ite_utils.h b/src/theory/arith/arith_ite_utils.h index 44c3c080b..e2d0d2baf 100644 --- a/src/theory/arith/arith_ite_utils.h +++ b/src/theory/arith/arith_ite_utils.h @@ -2,9 +2,9 @@ /*! \file arith_ite_utils.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -15,11 +15,6 @@ ** \todo document this file **/ - - - - - // Pass 1: label the ite as (constant) or (+ constant variable) #include "cvc4_private.h" @@ -27,9 +22,9 @@ #ifndef __CVC4__THEORY__ARITH__ARITH_ITE_UTILS_H #define __CVC4__THEORY__ARITH__ARITH_ITE_UTILS_H +#include <unordered_map> + #include "expr/node.h" -#include <ext/hash_map> -#include <ext/hash_set> #include "context/cdo.h" #include "context/cdtrail_hashmap.h" @@ -46,7 +41,7 @@ class ArithIteUtils { SubstitutionMap* d_subs; TheoryModel* d_model; - typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeMap; // cache for reduce vars NodeMap d_reduceVar; // if reduceVars[n].isNull(), treat reduceVars[n] == n @@ -56,7 +51,7 @@ class ArithIteUtils { NodeMap d_reduceGcd; - typedef std::hash_map<Node, Integer, NodeHashFunction> NodeIntegerMap; + typedef std::unordered_map<Node, Integer, NodeHashFunction> NodeIntegerMap; NodeIntegerMap d_gcds; Integer d_one; diff --git a/src/theory/arith/arith_rewriter.cpp b/src/theory/arith/arith_rewriter.cpp index 4d7e9deef..57428d209 100644 --- a/src/theory/arith/arith_rewriter.cpp +++ b/src/theory/arith/arith_rewriter.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -101,7 +101,12 @@ RewriteResponse ArithRewriter::preRewriteTerm(TNode t){ return preRewritePlus(t); case kind::MULT: case kind::NONLINEAR_MULT: - return preRewriteMult(t); + return preRewriteMult(t); + case kind::EXPONENTIAL: + case kind::SINE: + case kind::COSINE: + case kind::TANGENT: + return preRewriteTranscendental(t); case kind::INTS_DIVISION: case kind::INTS_MODULUS: return RewriteResponse(REWRITE_DONE, t); @@ -126,6 +131,8 @@ RewriteResponse ArithRewriter::preRewriteTerm(TNode t){ return RewriteResponse(REWRITE_DONE, t[0]); case kind::POW: return RewriteResponse(REWRITE_DONE, t); + case kind::PI: + return RewriteResponse(REWRITE_DONE, t); default: Unhandled(k); } @@ -150,7 +157,12 @@ RewriteResponse ArithRewriter::postRewriteTerm(TNode t){ return postRewritePlus(t); case kind::MULT: case kind::NONLINEAR_MULT: - return postRewriteMult(t); + return postRewriteMult(t); + case kind::EXPONENTIAL: + case kind::SINE: + case kind::COSINE: + case kind::TANGENT: + return postRewriteTranscendental(t); case kind::INTS_DIVISION: case kind::INTS_MODULUS: return RewriteResponse(REWRITE_DONE, t); @@ -197,15 +209,21 @@ RewriteResponse ArithRewriter::postRewriteTerm(TNode t){ if(exp.sgn() == 0){ return RewriteResponse(REWRITE_DONE, mkRationalNode(Rational(1))); }else if(exp.sgn() > 0 && exp.isIntegral()){ - Integer num = exp.getNumerator(); - NodeBuilder<> nb(kind::MULT); - Integer one(1); - for(Integer i(0); i < num; i = i + one){ - nb << base; + CVC4::Rational r(INT_MAX); + if( exp<r ){ + unsigned num = exp.getNumerator().toUnsignedInt(); + if( num==1 ){ + return RewriteResponse(REWRITE_AGAIN, base); + }else{ + NodeBuilder<> nb(kind::MULT); + for(unsigned i=0; i < num; ++i){ + nb << base; + } + Assert(nb.getNumChildren() > 0); + Node mult = nb; + return RewriteResponse(REWRITE_AGAIN, mult); + } } - Assert(nb.getNumChildren() > 0); - Node mult = nb; - return RewriteResponse(REWRITE_AGAIN, mult); } } @@ -216,6 +234,8 @@ RewriteResponse ArithRewriter::postRewriteTerm(TNode t){ ss << " " << t; throw LogicException(ss.str()); } + case kind::PI: + return RewriteResponse(REWRITE_DONE, t); default: Unreachable(); } @@ -332,6 +352,100 @@ RewriteResponse ArithRewriter::postRewriteMult(TNode t){ return RewriteResponse(REWRITE_DONE, res.getNode()); } + +RewriteResponse ArithRewriter::preRewriteTranscendental(TNode t) { + return RewriteResponse(REWRITE_DONE, t); +} + +RewriteResponse ArithRewriter::postRewriteTranscendental(TNode t) { + Trace("arith-tf-rewrite") << "Rewrite transcendental function : " << t << std::endl; + switch( t.getKind() ){ + case kind::EXPONENTIAL: { + if(t[0].getKind() == kind::CONST_RATIONAL){ + Node one = NodeManager::currentNM()->mkConst(Rational(1)); + if(t[0].getConst<Rational>().sgn()>=0 && t[0].getType().isInteger() && t[0]!=one){ + return RewriteResponse(REWRITE_AGAIN, NodeManager::currentNM()->mkNode(kind::POW, NodeManager::currentNM()->mkNode( kind::EXPONENTIAL, one ), t[0])); + }else{ + return RewriteResponse(REWRITE_DONE, t); + } + }else if(t[0].getKind() == kind::PLUS ){ + std::vector<Node> product; + for( unsigned i=0; i<t[0].getNumChildren(); i++ ){ + product.push_back( NodeManager::currentNM()->mkNode( kind::EXPONENTIAL, t[0][i] ) ); + } + return RewriteResponse(REWRITE_AGAIN, NodeManager::currentNM()->mkNode(kind::MULT, product)); + } + } + break; + case kind::SINE: + if(t[0].getKind() == kind::CONST_RATIONAL){ + const Rational& rat = t[0].getConst<Rational>(); + if(rat.sgn() == 0){ + return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(Rational(0))); + } + }else{ + Node pi_factor; + Node pi; + if( t[0].getKind()==kind::PI ){ + pi_factor = NodeManager::currentNM()->mkConst(Rational(1)); + pi = t[0]; + }else if( t[0].getKind()==kind::MULT && t[0][0].isConst() && t[0][1].getKind()==kind::PI ){ + pi_factor = t[0][0]; + pi = t[0][1]; + } + if( !pi_factor.isNull() ){ + Trace("arith-tf-rewrite-debug") << "Process pi factor = " << pi_factor << std::endl; + Rational r = pi_factor.getConst<Rational>(); + Rational ra = r.abs(); + Rational rone = Rational(1); + Node ntwo = NodeManager::currentNM()->mkConst( Rational(2) ); + if( ra > rone ){ + //add/substract 2*pi beyond scope + Node ra_div_two = NodeManager::currentNM()->mkNode( kind::INTS_DIVISION, NodeManager::currentNM()->mkConst( ra + rone ), ntwo ); + Node new_pi_factor; + if( r.sgn()==1 ){ + new_pi_factor = NodeManager::currentNM()->mkNode( kind::MINUS, pi_factor, NodeManager::currentNM()->mkNode( kind::MULT, ntwo, ra_div_two ) ); + }else{ + Assert( r.sgn()==-1 ); + new_pi_factor = NodeManager::currentNM()->mkNode( kind::PLUS, pi_factor, NodeManager::currentNM()->mkNode( kind::MULT, ntwo, ra_div_two ) ); + } + return RewriteResponse(REWRITE_AGAIN_FULL, NodeManager::currentNM()->mkNode( kind::SINE, + NodeManager::currentNM()->mkNode( kind::MULT, new_pi_factor, pi ) ) ); + }else if( ra == rone ){ + return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(Rational(0))); + }else{ + Integer one = Integer(1); + Integer two = Integer(2); + Integer six = Integer(6); + if( ra.getDenominator()==two ){ + return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst( Rational( r.sgn() ) ) ); + }else if( ra.getDenominator()==six ){ + Integer five = Integer(5); + if( ra.getNumerator()==one || ra.getNumerator()==five ){ + return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst( Rational( r.sgn() )/Rational(2) ) ); + } + } + } + } + } + break; + case kind::COSINE: { + return RewriteResponse(REWRITE_AGAIN_FULL, NodeManager::currentNM()->mkNode( kind::SINE, + NodeManager::currentNM()->mkNode( kind::MINUS, + NodeManager::currentNM()->mkNode( kind::MULT, + NodeManager::currentNM()->mkConst( Rational(1)/Rational(2) ), + NodeManager::currentNM()->mkNullaryOperator( NodeManager::currentNM()->realType(), kind::PI ) ), + t[0] ) ) ); + } break; + case kind::TANGENT: + return RewriteResponse(REWRITE_AGAIN_FULL, NodeManager::currentNM()->mkNode(kind::DIVISION, NodeManager::currentNM()->mkNode( kind::SINE, t[0] ), + NodeManager::currentNM()->mkNode( kind::COSINE, t[0] ) )); + default: + break; + } + return RewriteResponse(REWRITE_DONE, t); +} + RewriteResponse ArithRewriter::postRewriteAtom(TNode atom){ if(atom.getKind() == kind::IS_INTEGER) { if(atom[0].isConst()) { @@ -440,7 +554,6 @@ Node ArithRewriter::makeSubtractionNode(TNode l, TNode r){ RewriteResponse ArithRewriter::rewriteDiv(TNode t, bool pre){ Assert(t.getKind() == kind::DIVISION_TOTAL || t.getKind()== kind::DIVISION); - Node left = t[0]; Node right = t[1]; if(right.getKind() == kind::CONST_RATIONAL){ diff --git a/src/theory/arith/arith_rewriter.h b/src/theory/arith/arith_rewriter.h index 3cb502249..a4472d6c3 100644 --- a/src/theory/arith/arith_rewriter.h +++ b/src/theory/arith/arith_rewriter.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Dejan Jovanovic, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -57,7 +57,9 @@ private: static RewriteResponse preRewriteMult(TNode t); static RewriteResponse postRewriteMult(TNode t); - + + static RewriteResponse preRewriteTranscendental(TNode t); + static RewriteResponse postRewriteTranscendental(TNode t); static RewriteResponse preRewriteAtom(TNode t); static RewriteResponse postRewriteAtom(TNode t); diff --git a/src/theory/arith/arith_static_learner.cpp b/src/theory/arith/arith_static_learner.cpp index 7c648c941..478f0f94c 100644 --- a/src/theory/arith/arith_static_learner.cpp +++ b/src/theory/arith/arith_static_learner.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Dejan Jovanovic, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -18,7 +18,6 @@ #include <vector> #include "base/output.h" -#include "expr/convenience_node_builders.h" #include "expr/expr.h" #include "options/arith_options.h" #include "smt/smt_statistics_registry.h" diff --git a/src/theory/arith/arith_static_learner.h b/src/theory/arith/arith_static_learner.h index 4951d34d7..cca4b2285 100644 --- a/src/theory/arith/arith_static_learner.h +++ b/src/theory/arith/arith_static_learner.h @@ -2,9 +2,9 @@ /*! \file arith_static_learner.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Dejan Jovanovic + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/arith_utilities.h b/src/theory/arith/arith_utilities.h index ba1a9b037..4a9539d49 100644 --- a/src/theory/arith/arith_utilities.h +++ b/src/theory/arith/arith_utilities.h @@ -2,9 +2,9 @@ /*! \file arith_utilities.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Dejan Jovanovic + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,7 +19,8 @@ #ifndef __CVC4__THEORY__ARITH__ARITH_UTILITIES_H #define __CVC4__THEORY__ARITH__ARITH_UTILITIES_H -#include <ext/hash_map> +#include <unordered_map> +#include <unordered_set> #include <vector> #include "context/cdhashset.h" @@ -35,12 +36,12 @@ namespace theory { namespace arith { //Sets of Nodes -typedef __gnu_cxx::hash_set<Node, NodeHashFunction> NodeSet; -typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet; +typedef std::unordered_set<Node, NodeHashFunction> NodeSet; +typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; typedef context::CDHashSet<Node, NodeHashFunction> CDNodeSet; //Maps from Nodes -> ArithVars, and vice versa -typedef __gnu_cxx::hash_map<Node, ArithVar, NodeHashFunction> NodeToArithVarMap; +typedef std::unordered_map<Node, ArithVar, NodeHashFunction> NodeToArithVarMap; typedef DenseMap<Node> ArithVarToNodeMap; inline Node mkRationalNode(const Rational& q){ diff --git a/src/theory/arith/arithvar.cpp b/src/theory/arith/arithvar.cpp index 1ab125a47..d63dc6fca 100644 --- a/src/theory/arith/arithvar.cpp +++ b/src/theory/arith/arithvar.cpp @@ -2,9 +2,9 @@ /*! \file arithvar.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/arithvar.h b/src/theory/arith/arithvar.h index f9ff6da26..d1f71803f 100644 --- a/src/theory/arith/arithvar.h +++ b/src/theory/arith/arithvar.h @@ -2,9 +2,9 @@ /*! \file arithvar.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/arithvar_node_map.h b/src/theory/arith/arithvar_node_map.h index da0b03ef2..62a8301e7 100644 --- a/src/theory/arith/arithvar_node_map.h +++ b/src/theory/arith/arithvar_node_map.h @@ -2,9 +2,9 @@ /*! \file arithvar_node_map.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Dejan Jovanovic + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/attempt_solution_simplex.cpp b/src/theory/arith/attempt_solution_simplex.cpp index 333b0bfae..fe6755951 100644 --- a/src/theory/arith/attempt_solution_simplex.cpp +++ b/src/theory/arith/attempt_solution_simplex.cpp @@ -2,9 +2,9 @@ /*! \file attempt_solution_simplex.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/attempt_solution_simplex.h b/src/theory/arith/attempt_solution_simplex.h index 00df8c075..73798f94c 100644 --- a/src/theory/arith/attempt_solution_simplex.h +++ b/src/theory/arith/attempt_solution_simplex.h @@ -2,9 +2,9 @@ /*! \file attempt_solution_simplex.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/bound_counts.h b/src/theory/arith/bound_counts.h index b6417ed63..70ddc2bfa 100644 --- a/src/theory/arith/bound_counts.h +++ b/src/theory/arith/bound_counts.h @@ -2,9 +2,9 @@ /*! \file bound_counts.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Clark Barrett + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/callbacks.cpp b/src/theory/arith/callbacks.cpp index 766c7424a..73aa5c34e 100644 --- a/src/theory/arith/callbacks.cpp +++ b/src/theory/arith/callbacks.cpp @@ -2,9 +2,9 @@ /*! \file callbacks.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/callbacks.h b/src/theory/arith/callbacks.h index 606f4111b..3710ac5c0 100644 --- a/src/theory/arith/callbacks.h +++ b/src/theory/arith/callbacks.h @@ -2,9 +2,9 @@ /*! \file callbacks.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Clark Barrett + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/congruence_manager.cpp b/src/theory/arith/congruence_manager.cpp index 25822afdf..f6e702f5b 100644 --- a/src/theory/arith/congruence_manager.cpp +++ b/src/theory/arith/congruence_manager.cpp @@ -2,9 +2,9 @@ /*! \file congruence_manager.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Dejan Jovanovic, Morgan Deters, Andrew Reynolds + ** Tim King, Paul Meng, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -43,6 +43,8 @@ ArithCongruenceManager::ArithCongruenceManager(context::Context* c, ConstraintDa d_ee(d_notify, c, "theory::arith::ArithCongruenceManager", true) { d_ee.addFunctionKind(kind::NONLINEAR_MULT); + d_ee.addFunctionKind(kind::EXPONENTIAL); + d_ee.addFunctionKind(kind::SINE); //module to infer additional equalities based on normalization if( options::sNormInferEq() ){ d_eq_infer = new quantifiers::EqualityInference(c, true); diff --git a/src/theory/arith/congruence_manager.h b/src/theory/arith/congruence_manager.h index 8d92a4153..228f29838 100644 --- a/src/theory/arith/congruence_manager.h +++ b/src/theory/arith/congruence_manager.h @@ -2,9 +2,9 @@ /*! \file congruence_manager.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Dejan Jovanovic, Andrew Reynolds + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/constraint.cpp b/src/theory/arith/constraint.cpp index a82ec4c95..3427edbd3 100644 --- a/src/theory/arith/constraint.cpp +++ b/src/theory/arith/constraint.cpp @@ -2,9 +2,9 @@ /*! \file constraint.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Dejan Jovanovic + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -16,8 +16,9 @@ **/ #include "theory/arith/constraint.h" -#include <ostream> #include <algorithm> +#include <ostream> +#include <unordered_set> #include "base/output.h" #include "proof/proof.h" @@ -1333,7 +1334,7 @@ struct ConstraintCPHash { }; void Constraint::assertionFringe(ConstraintCPVec& v){ - hash_set<ConstraintCP, ConstraintCPHash> visited; + unordered_set<ConstraintCP, ConstraintCPHash> visited; size_t writePos = 0; if(!v.empty()){ diff --git a/src/theory/arith/constraint.h b/src/theory/arith/constraint.h index 3ae2d0b29..25f838567 100644 --- a/src/theory/arith/constraint.h +++ b/src/theory/arith/constraint.h @@ -2,9 +2,9 @@ /*! \file constraint.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -75,7 +75,7 @@ #ifndef __CVC4__THEORY__ARITH__CONSTRAINT_H #define __CVC4__THEORY__ARITH__CONSTRAINT_H -#include <ext/hash_map> +#include <unordered_map> #include <list> #include <set> #include <vector> @@ -145,7 +145,7 @@ enum ConstraintType {LowerBound, Equality, UpperBound, Disequality}; typedef context::CDList<ConstraintCP> CDConstraintList; -typedef __gnu_cxx::hash_map<Node, ConstraintP, NodeHashFunction> NodetoConstraintMap; +typedef std::unordered_map<Node, ConstraintP, NodeHashFunction> NodetoConstraintMap; typedef size_t ConstraintRuleID; static const ConstraintRuleID ConstraintRuleIdSentinel = std::numeric_limits<ConstraintRuleID>::max(); diff --git a/src/theory/arith/constraint_forward.h b/src/theory/arith/constraint_forward.h index 1ebffc1b0..80a0fa0a4 100644 --- a/src/theory/arith/constraint_forward.h +++ b/src/theory/arith/constraint_forward.h @@ -2,9 +2,9 @@ /*! \file constraint_forward.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/cut_log.cpp b/src/theory/arith/cut_log.cpp index 3af2a7178..ad04cfe22 100644 --- a/src/theory/arith/cut_log.cpp +++ b/src/theory/arith/cut_log.cpp @@ -2,9 +2,9 @@ /*! \file cut_log.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/cut_log.h b/src/theory/arith/cut_log.h index e6475b58e..7d41666e7 100644 --- a/src/theory/arith/cut_log.h +++ b/src/theory/arith/cut_log.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Kshitij Bansal ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,7 @@ #pragma once -#include <ext/hash_map> +#include <unordered_map> #include <map> #include <set> #include <vector> @@ -179,7 +179,7 @@ private: int d_upId; public: - typedef __gnu_cxx::hash_map<int, ArithVar> RowIdMap; + typedef std::unordered_map<int, ArithVar> RowIdMap; private: RowIdMap d_rowId2ArithVar; diff --git a/src/theory/arith/delta_rational.cpp b/src/theory/arith/delta_rational.cpp index 207fd79a4..467f868a3 100644 --- a/src/theory/arith/delta_rational.cpp +++ b/src/theory/arith/delta_rational.cpp @@ -2,9 +2,9 @@ /*! \file delta_rational.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/delta_rational.h b/src/theory/arith/delta_rational.h index afe4c0eb0..b0ea8a9c1 100644 --- a/src/theory/arith/delta_rational.h +++ b/src/theory/arith/delta_rational.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/dio_solver.cpp b/src/theory/arith/dio_solver.cpp index f34bbc67a..5b61385f3 100644 --- a/src/theory/arith/dio_solver.cpp +++ b/src/theory/arith/dio_solver.cpp @@ -2,9 +2,9 @@ /*! \file dio_solver.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Dejan Jovanovic + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -304,7 +304,7 @@ bool DioSolver::queueEmpty() const{ } Node DioSolver::columnGcdIsOne() const{ - std::hash_map<Node, Integer, NodeHashFunction> gcdMap; + std::unordered_map<Node, Integer, NodeHashFunction> gcdMap; std::deque<TrailIndex>::const_iterator iter, end; for(iter = d_currentF.begin(), end = d_currentF.end(); iter != end; ++iter){ diff --git a/src/theory/arith/dio_solver.h b/src/theory/arith/dio_solver.h index 6c53d6ad0..292f2b856 100644 --- a/src/theory/arith/dio_solver.h +++ b/src/theory/arith/dio_solver.h @@ -2,9 +2,9 @@ /*! \file dio_solver.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,6 +20,7 @@ #ifndef __CVC4__THEORY__ARITH__DIO_SOLVER_H #define __CVC4__THEORY__ARITH__DIO_SOLVER_H +#include <unordered_map> #include <utility> #include <vector> @@ -68,7 +69,7 @@ private: * We maintain a map from the variables associated with proofs to an input constraint. * These variables can then be used in polynomial manipulations. */ - typedef std::hash_map<Node, InputConstraintIndex, NodeHashFunction> NodeToInputConstraintIndexMap; + typedef std::unordered_map<Node, InputConstraintIndex, NodeHashFunction> NodeToInputConstraintIndexMap; NodeToInputConstraintIndexMap d_varToInputConstraintMap; Node proofVariableToReason(const Variable& v) const{ diff --git a/src/theory/arith/dual_simplex.cpp b/src/theory/arith/dual_simplex.cpp index 72d7a8602..a40db89a7 100644 --- a/src/theory/arith/dual_simplex.cpp +++ b/src/theory/arith/dual_simplex.cpp @@ -2,9 +2,9 @@ /*! \file dual_simplex.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/dual_simplex.h b/src/theory/arith/dual_simplex.h index 25461972c..2911592c7 100644 --- a/src/theory/arith/dual_simplex.h +++ b/src/theory/arith/dual_simplex.h @@ -2,9 +2,9 @@ /*! \file dual_simplex.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/error_set.cpp b/src/theory/arith/error_set.cpp index 7c8efc4e8..0bd283252 100644 --- a/src/theory/arith/error_set.cpp +++ b/src/theory/arith/error_set.cpp @@ -2,9 +2,9 @@ /*! \file error_set.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/error_set.h b/src/theory/arith/error_set.h index 4b88e3f50..e09a85aaf 100644 --- a/src/theory/arith/error_set.h +++ b/src/theory/arith/error_set.h @@ -2,9 +2,9 @@ /*! \file error_set.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/fc_simplex.cpp b/src/theory/arith/fc_simplex.cpp index ef5ff93c7..59bb35293 100644 --- a/src/theory/arith/fc_simplex.cpp +++ b/src/theory/arith/fc_simplex.cpp @@ -2,9 +2,9 @@ /*! \file fc_simplex.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/fc_simplex.h b/src/theory/arith/fc_simplex.h index ca1e666fc..c4f996f9f 100644 --- a/src/theory/arith/fc_simplex.h +++ b/src/theory/arith/fc_simplex.h @@ -2,9 +2,9 @@ /*! \file fc_simplex.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/infer_bounds.cpp b/src/theory/arith/infer_bounds.cpp index 96b2a6189..e9a85d7d7 100644 --- a/src/theory/arith/infer_bounds.cpp +++ b/src/theory/arith/infer_bounds.cpp @@ -2,9 +2,9 @@ /*! \file infer_bounds.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/infer_bounds.h b/src/theory/arith/infer_bounds.h index f65952f7c..720b5704d 100644 --- a/src/theory/arith/infer_bounds.h +++ b/src/theory/arith/infer_bounds.h @@ -2,9 +2,9 @@ /*! \file infer_bounds.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/kinds b/src/theory/arith/kinds index 61029ac48..34ae30f4c 100644 --- a/src/theory/arith/kinds +++ b/src/theory/arith/kinds @@ -27,6 +27,11 @@ operator ABS 1 "absolute value" parameterized DIVISIBLE DIVISIBLE_OP 1 "divisibility-by-k predicate; first parameter is a DIVISIBLE_OP, second is integer term" operator POW 2 "arithmetic power" +operator EXPONENTIAL 1 "exponential" +operator SINE 1 "sine" +operator COSINE 1 "consine" +operator TANGENT 1 "tangent" + constant DIVISIBLE_OP \ ::CVC4::Divisible \ ::CVC4::DivisibleHashFunction \ @@ -46,19 +51,6 @@ sort INTEGER_TYPE \ "expr/node_manager.h" \ "integer type" -constant SUBRANGE_TYPE \ - ::CVC4::SubrangeBounds \ - ::CVC4::SubrangeBoundsHashFunction \ - "util/subrange_bound.h" \ - "the type of an integer subrange" -cardinality SUBRANGE_TYPE \ - "::CVC4::theory::arith::SubrangeProperties::computeCardinality(%TYPE%)" \ - "theory/arith/theory_arith_type_rules.h" -well-founded SUBRANGE_TYPE \ - true \ - "::CVC4::theory::arith::SubrangeProperties::mkGroundTerm(%TYPE%)" \ - "theory/arith/theory_arith_type_rules.h" - constant CONST_RATIONAL \ ::CVC4::Rational \ ::CVC4::RationalHashFunction \ @@ -71,9 +63,6 @@ enumerator REAL_TYPE \ enumerator INTEGER_TYPE \ "::CVC4::theory::arith::IntegerEnumerator" \ "theory/arith/type_enumerator.h" -enumerator SUBRANGE_TYPE \ - "::CVC4::theory::arith::SubrangeEnumerator" \ - "theory/arith/type_enumerator.h" operator LT 2 "less than, x < y" operator LEQ 2 "less than or equal, x <= y" @@ -112,4 +101,13 @@ typerule DIVISION_TOTAL ::CVC4::theory::arith::ArithOperatorTypeRule typerule INTS_DIVISION_TOTAL ::CVC4::theory::arith::IntOperatorTypeRule typerule INTS_MODULUS_TOTAL ::CVC4::theory::arith::IntOperatorTypeRule +typerule EXPONENTIAL ::CVC4::theory::arith::RealOperatorTypeRule +typerule SINE ::CVC4::theory::arith::RealOperatorTypeRule +typerule COSINE ::CVC4::theory::arith::RealOperatorTypeRule +typerule TANGENT ::CVC4::theory::arith::RealOperatorTypeRule + +nullaryoperator PI "pi" + +typerule PI ::CVC4::theory::arith::RealNullaryOperatorTypeRule + endtheory diff --git a/src/theory/arith/linear_equality.cpp b/src/theory/arith/linear_equality.cpp index 7e1d84ebb..9d414fcd7 100644 --- a/src/theory/arith/linear_equality.cpp +++ b/src/theory/arith/linear_equality.cpp @@ -2,9 +2,9 @@ /*! \file linear_equality.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/linear_equality.h b/src/theory/arith/linear_equality.h index aa6b10c5e..c2fa99e31 100644 --- a/src/theory/arith/linear_equality.h +++ b/src/theory/arith/linear_equality.h @@ -2,9 +2,9 @@ /*! \file linear_equality.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Clark Barrett, Morgan Deters + ** Tim King, Paul Meng, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/matrix.cpp b/src/theory/arith/matrix.cpp index 25ed96b0c..2817a1dca 100644 --- a/src/theory/arith/matrix.cpp +++ b/src/theory/arith/matrix.cpp @@ -2,9 +2,9 @@ /*! \file matrix.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/matrix.h b/src/theory/arith/matrix.h index f0d4ec42c..2e0a1ebb2 100644 --- a/src/theory/arith/matrix.h +++ b/src/theory/arith/matrix.h @@ -2,9 +2,9 @@ /*! \file matrix.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Clark Barrett + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/nonlinear_extension.cpp b/src/theory/arith/nonlinear_extension.cpp index 26f232142..42f9636dc 100644 --- a/src/theory/arith/nonlinear_extension.cpp +++ b/src/theory/arith/nonlinear_extension.cpp @@ -1,10 +1,10 @@ /********************* */ -/*! \file nl_alg.cpp +/*! \file nonlinear_extension.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds + ** Tim King, Andrew Reynolds, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -217,6 +217,7 @@ NonlinearExtension::NonlinearExtension(TheoryArith& containing, eq::EqualityEngine* ee) : d_lemmas(containing.getUserContext()), d_zero_split(containing.getUserContext()), + d_skolem_atoms(containing.getUserContext()), d_containing(containing), d_ee(ee), d_needsLastCall(false) { @@ -235,7 +236,7 @@ NonlinearExtension::~NonlinearExtension() {} // Returns a reference to either map[key] if it exists in the map // or to a default value otherwise. // -// Warning: special care must be taken if value is a temporary object. +// Warning: sped_cial care must be taken if value is a temporary object. template <class MapType, class Key, class Value> const Value& FindWithDefault(const MapType& map, const Key& key, const Value& value) { @@ -699,49 +700,58 @@ Node NonlinearExtension::computeModelValue(Node n, unsigned index) { if (it != d_mv[index].end()) { return it->second; } else { - Trace("nl-ext-debug") << "computeModelValue " << n << std::endl; + Trace("nl-ext-mv-debug") << "computeModelValue " << n << ", index=" << index << std::endl; Node ret; if (n.isConst()) { ret = n; - } else { - if (n.getNumChildren() == 0) { - ret = d_containing.getValuation().getModel()->getValue(n); + } else if (index == 1 && ( n.getKind() == kind::NONLINEAR_MULT || isTranscendentalKind( n.getKind() ) )) { + if (d_containing.getValuation().getModel()->hasTerm(n)) { + // use model value for abstraction + ret = d_containing.getValuation().getModel()->getRepresentative(n); } else { - if (index == 1 && n.getKind() == kind::NONLINEAR_MULT) { - if (d_containing.getValuation().getModel()->hasTerm(n)) { - // use model value for abstraction - ret = d_containing.getValuation().getModel()->getRepresentative(n); - } else { - // abstraction does not exist, use concrete - ret = computeModelValue(n, 0); - } - } else { - // otherwise, compute true value - std::vector<Node> children; - if (n.getMetaKind() == kind::metakind::PARAMETERIZED) { - children.push_back(n.getOperator()); - } - for (unsigned i = 0; i < n.getNumChildren(); i++) { - Node mc = computeModelValue(n[i], index); - children.push_back(mc); - } - ret = Rewriter::rewrite( - NodeManager::currentNM()->mkNode(n.getKind(), children)); - if (!ret.isConst()) { - Trace("nl-ext-debug") << "...got non-constant : " << ret << " for " - << n << ", ask model directly." << std::endl; - ret = d_containing.getValuation().getModel()->getValue(ret); - } - } + // abstraction does not exist, use model value + //ret = computeModelValue(n, 0); + ret = d_containing.getValuation().getModel()->getValue(n); } - if (ret.getType().isReal() && !isArithKind(n.getKind())) { - // Trace("nl-ext-mv-debug") << ( index==0 ? "M" : "M_A" ) << "[ " << n - // << " ] -> " << ret << std::endl; - Assert(ret.isConst()); + //Assert( ret.isConst() ); + } else if (n.getNumChildren() == 0) { + if( n.getKind()==kind::PI ){ + ret = n; + }else{ + ret = d_containing.getValuation().getModel()->getValue(n); + } + } else { + // otherwise, compute true value + std::vector<Node> children; + if (n.getMetaKind() == kind::metakind::PARAMETERIZED) { + children.push_back(n.getOperator()); + } + for (unsigned i = 0; i < n.getNumChildren(); i++) { + Node mc = computeModelValue(n[i], index); + children.push_back(mc); + } + ret = NodeManager::currentNM()->mkNode(n.getKind(), children); + if( n.getKind()==kind::APPLY_UF ){ + ret = d_containing.getValuation().getModel()->getValue(ret); + }else{ + ret = Rewriter::rewrite(ret); + } + /* + if (!ret.isConst()) { + Trace("nl-ext-debug") << "...got non-constant : " << ret << " for " + << n << ", ask model directly." << std::endl; + ret = d_containing.getValuation().getModel()->getValue(ret); } + */ } - Trace("nl-ext-debug") << "computed " << (index == 0 ? "M" : "M_A") << "[" - << n << "] = " << ret << std::endl; + //if (ret.getType().isReal() && !isArithKind(n.getKind())) { + // Trace("nl-ext-mv-debug") << ( index==0 ? "M" : "M_A" ) << "[ " << n + // << " ] -> " << ret << std::endl; + //may involve transcendental functions + //Assert(ret.isConst()); + //} + Trace("nl-ext-mv-debug") << "computed " << (index == 0 ? "M" : "M_A") << "[" + << n << "] = " << ret << std::endl; d_mv[index][n] = ret; return ret; } @@ -898,6 +908,16 @@ Node NonlinearExtension::mkAbs(Node a) { } } +Node NonlinearExtension::mkValidPhase(Node a, Node pi) { + return mkBounded( NodeManager::currentNM()->mkNode( kind::MULT, mkRationalNode(-1), pi ), a, pi ); +} + +Node NonlinearExtension::mkBounded( Node l, Node a, Node u ) { + return NodeManager::currentNM()->mkNode( kind::AND, + NodeManager::currentNM()->mkNode( kind::GEQ, a, l ), + NodeManager::currentNM()->mkNode( kind::LEQ, a, u ) ); +} + // by a <k1> b, a <k2> b, we know a <ret> b Kind NonlinearExtension::joinKinds(Kind k1, Kind k2) { if (k2 < k1) { @@ -956,6 +976,11 @@ Kind NonlinearExtension::transKinds(Kind k1, Kind k2) { } } +bool NonlinearExtension::isTranscendentalKind(Kind k) { + Assert( k != kind::TANGENT && k != kind::COSINE ); //eliminated + return k==kind::EXPONENTIAL || k==kind::SINE || k==kind::PI; +} + Node NonlinearExtension::mkMonomialRemFactor( Node n, const NodeMultiset& n_exp_rem) const { std::vector<Node> children; @@ -1033,27 +1058,26 @@ std::set<Node> NonlinearExtension::getFalseInModel( std::set<Node> false_asserts; for (size_t i = 0; i < assertions.size(); ++i) { Node lit = assertions[i]; - Node litv = computeModelValue(lit); - Trace("nl-ext-mv") << "M[[ " << lit << " ]] -> " << litv; - if (litv != d_true) { - Trace("nl-ext-mv") << " [model-false]" << std::endl; - Assert(litv == d_false); - false_asserts.insert(lit); - } else { - Trace("nl-ext-mv") << std::endl; + Node atom = lit.getKind()==NOT ? lit[0] : lit; + if( d_skolem_atoms.find( atom )==d_skolem_atoms.end() ){ + Node litv = computeModelValue(lit); + Trace("nl-ext-mv") << "M[[ " << lit << " ]] -> " << litv; + if (litv != d_true) { + Trace("nl-ext-mv") << " [model-false]" << std::endl; + //Assert(litv == d_false); + false_asserts.insert(lit); + } else { + Trace("nl-ext-mv") << std::endl; + } } } return false_asserts; } -std::vector<Node> NonlinearExtension::splitOnZeros( - const std::vector<Node>& ms_vars) { +std::vector<Node> NonlinearExtension::checkSplitZero() { std::vector<Node> lemmas; - if (!options::nlExtSplitZero()) { - return lemmas; - } - for (unsigned i = 0; i < ms_vars.size(); i++) { - Node v = ms_vars[i]; + for (unsigned i = 0; i < d_ms_vars.size(); i++) { + Node v = d_ms_vars[i]; if (d_zero_split.insert(v)) { Node lem = v.eqNode(d_zero); lem = Rewriter::rewrite(lem); @@ -1067,50 +1091,123 @@ std::vector<Node> NonlinearExtension::splitOnZeros( } void NonlinearExtension::checkLastCall(const std::vector<Node>& assertions, - const std::set<Node>& false_asserts) { - // processed monomials - std::map<Node, bool> ms_proc; - - // list of monomials - std::vector<Node> ms; - d_containing.getExtTheory()->getTerms(ms); - // list of variables occurring in monomials - std::vector<Node> ms_vars; - - // register monomials - Trace("nl-ext-mv") << "Monomials : " << std::endl; - for (unsigned j = 0; j < ms.size(); j++) { - Node a = ms[j]; - registerMonomial(a); + const std::set<Node>& false_asserts, + const std::vector<Node>& xts) { + d_ms_vars.clear(); + d_ms_proc.clear(); + d_ms.clear(); + d_mterms.clear(); + d_m_nconst_factor.clear(); + d_tplane_refine_dir.clear(); + d_ci.clear(); + d_ci_exp.clear(); + d_ci_max.clear(); + d_tf_rep_map.clear(); + + int lemmas_proc = 0; + std::vector<Node> lemmas; + + Trace("nl-ext-mv") << "Extended terms : " << std::endl; + // register the extended function terms + std::map< Node, Node > mvarg_to_term; + for( unsigned i=0; i<xts.size(); i++ ){ + Node a = xts[i]; computeModelValue(a, 0); computeModelValue(a, 1); - Assert(d_mv[1][a].isConst()); - Assert(d_mv[0][a].isConst()); - Trace("nl-ext-mv") << " " << a << " -> " << d_mv[1][a] << " [" - << d_mv[0][a] << "]" << std::endl; - - std::map<Node, std::vector<Node> >::iterator itvl = d_m_vlist.find(a); - Assert(itvl != d_m_vlist.end()); - for (unsigned k = 0; k < itvl->second.size(); k++) { - if (!IsInVector(ms_vars, itvl->second[k])) { - ms_vars.push_back(itvl->second[k]); + Trace("nl-ext-mv") << " " << a << " -> " << d_mv[1][a] << " [actual: " + << d_mv[0][a] << " ]" << std::endl; + //Assert(d_mv[1][a].isConst()); + //Assert(d_mv[0][a].isConst()); + + if( a.getKind()==kind::NONLINEAR_MULT ){ + d_ms.push_back( a ); + + //context-independent registration + registerMonomial(a); + + std::map<Node, std::vector<Node> >::iterator itvl = d_m_vlist.find(a); + Assert(itvl != d_m_vlist.end()); + for (unsigned k = 0; k < itvl->second.size(); k++) { + if (!IsInVector(d_ms_vars, itvl->second[k])) { + d_ms_vars.push_back(itvl->second[k]); + } + Node mvk = computeModelValue( itvl->second[k], 1 ); + if( !mvk.isConst() ){ + d_m_nconst_factor[a] = true; + } } - } - /* - //mark processed if has a "one" factor (will look at reduced monomial) - std::map< Node, std::map< Node, unsigned > >::iterator itme = - d_m_exp.find( a ); Assert( itme!=d_m_exp.end() ); for( std::map< Node, - unsigned >::iterator itme2 = itme->second.begin(); itme2 != - itme->second.end(); ++itme2 ){ Node v = itme->first; Assert( - d_mv[0].find( v )!=d_mv[0].end() ); Node mvv = d_mv[0][ v ]; if( - mvv==d_one || mvv==d_neg_one ){ ms_proc[ a ] = true; - Trace("nl-ext-mv") - << "...mark " << a << " reduced since has 1 factor." << std::endl; - break; + /* + //mark processed if has a "one" factor (will look at reduced monomial) + std::map< Node, std::map< Node, unsigned > >::iterator itme = + d_m_exp.find( a ); Assert( itme!=d_m_exp.end() ); for( std::map< Node, + unsigned >::iterator itme2 = itme->second.begin(); itme2 != + itme->second.end(); ++itme2 ){ Node v = itme->first; Assert( + d_mv[0].find( v )!=d_mv[0].end() ); Node mvv = d_mv[0][ v ]; if( + mvv==d_one || mvv==d_neg_one ){ ms_proc[ a ] = true; + Trace("nl-ext-mv") + << "...mark " << a << " reduced since has 1 factor." << std::endl; + break; + } + } + */ + }else if( a.getNumChildren()==1 ){ + bool consider = true; + // get shifted version + if( a.getKind()==kind::SINE ){ + if( d_trig_is_base.find( a )==d_trig_is_base.end() ){ + consider = false; + if( d_trig_base.find( a )==d_trig_base.end() ){ + Node y = NodeManager::currentNM()->mkSkolem("y",NodeManager::currentNM()->realType(),"phase shifted trigonometric arg"); + Node new_a = NodeManager::currentNM()->mkNode( a.getKind(), y ); + d_trig_is_base[new_a] = true; + d_trig_base[a] = new_a; + Trace("nl-ext-tf") << "Basis sine : " << new_a << " for " << a << std::endl; + if( d_pi.isNull() ){ + mkPi(); + getCurrentPiBounds( lemmas ); + } + Node shift = NodeManager::currentNM()->mkSkolem( "s", NodeManager::currentNM()->integerType(), "number of shifts" ); + Node shift_lem = NodeManager::currentNM()->mkNode( kind::AND, mkValidPhase( y, d_pi ), + a[0].eqNode( NodeManager::currentNM()->mkNode( kind::PLUS, y, + NodeManager::currentNM()->mkNode( kind::MULT, NodeManager::currentNM()->mkConst( Rational(2) ), shift, d_pi ) ) ), + //particular case of above for shift=0 + NodeManager::currentNM()->mkNode( kind::IMPLIES, mkValidPhase( a[0], d_pi ), a[0].eqNode( y ) ), + new_a.eqNode( a ) ); + //must do preprocess on this one + Trace("nl-ext-lemma") << "NonlinearExtension::Lemma : shift : " << shift_lem << std::endl; + d_containing.getOutputChannel().lemma(shift_lem, false, true); + lemmas_proc++; + } + } } + if( consider ){ + Node r = d_containing.getValuation().getModel()->getRepresentative(a[0]); + std::map< Node, Node >::iterator itrm = d_tf_rep_map[a.getKind()].find( r ); + if( itrm!=d_tf_rep_map[a.getKind()].end() ){ + //verify they have the same model value + if( d_mv[1][a]!=d_mv[1][itrm->second] ){ + //congruence lemma + Node cong_lemma = NodeManager::currentNM()->mkNode( kind::IMPLIES, a[0].eqNode( itrm->second[0] ), a.eqNode( itrm->second ) ); + lemmas.push_back( cong_lemma ); + //Assert( false ); + } + }else{ + d_tf_rep_map[a.getKind()][r] = a; + } + } + }else if( a.getKind()==kind::PI ){ + //TODO? + }else{ + Assert( false ); } - */ } + + lemmas_proc = flushLemmas(lemmas); + if (lemmas_proc > 0) { + Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas during registration." << std::endl; + return; + } + // register constants registerMonomial(d_one); @@ -1120,471 +1217,92 @@ void NonlinearExtension::checkLastCall(const std::vector<Node>& assertions, computeModelValue(c, 1); } - int lemmas_proc; - std::vector<Node> lemmas; - // register variables - Trace("nl-ext-mv") << "Variables : " << std::endl; - Trace("nl-ext") << "Get zero split lemmas..." << std::endl; - for (unsigned i = 0; i < ms_vars.size(); i++) { - Node v = ms_vars[i]; + Trace("nl-ext-mv") << "Variables in monomials : " << std::endl; + for (unsigned i = 0; i < d_ms_vars.size(); i++) { + Node v = d_ms_vars[i]; registerMonomial(v); computeModelValue(v, 0); computeModelValue(v, 1); - Trace("nl-ext-mv") << " " << v << " -> " << d_mv[0][v] << std::endl; + Trace("nl-ext-mv") << " " << v << " -> " << d_mv[1][v] << " [actual: " << d_mv[0][v] << " ]" << std::endl; } - // possibly split on zero? - lemmas = splitOnZeros(ms_vars); + //----------------------------------- possibly split on zero + if (options::nlExtSplitZero()) { + Trace("nl-ext") << "Get zero split lemmas..." << std::endl; + lemmas = checkSplitZero(); + lemmas_proc = flushLemmas(lemmas); + if (lemmas_proc > 0) { + Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." << std::endl; + return; + } + } + + //-----------------------------------initial lemmas for transcendental functions + lemmas = checkTranscendentalInitialRefine(); lemmas_proc = flushLemmas(lemmas); if (lemmas_proc > 0) { - Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." - << std::endl; + Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." << std::endl; return; } - + //-----------------------------------lemmas based on sign (comparison to zero) - std::map<Node, int> signs; - Trace("nl-ext") << "Get sign lemmas..." << std::endl; - for (unsigned j = 0; j < ms.size(); j++) { - Node a = ms[j]; - if (ms_proc.find(a) == ms_proc.end()) { - std::vector<Node> exp; - Trace("nl-ext-debug") << " process " << a << "..." << std::endl; - signs[a] = compareSign(a, a, 0, 1, exp, lemmas); - if (signs[a] == 0) { - ms_proc[a] = true; - Trace("nl-ext-mv") << "...mark " << a - << " reduced since its value is 0." << std::endl; - } - } + lemmas = checkMonomialSign(); + lemmas_proc = flushLemmas(lemmas); + if (lemmas_proc > 0) { + Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." << std::endl; + return; } + + //-----------------------------------monotonicity of transdental functions + lemmas = checkTranscendentalMonotonic(); lemmas_proc = flushLemmas(lemmas); if (lemmas_proc > 0) { - Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." - << std::endl; + Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." << std::endl; return; } - //-----------------------------lemmas based on magnitude of non-zero monomials - for (unsigned r = 1; r <= 1; r++) { - assignOrderIds(ms_vars, d_order_vars[r], r); - - // sort individual variable lists - SortNonlinearExtension smv; - smv.d_nla = this; - smv.d_order_type = r; - smv.d_reverse_order = true; - for (unsigned j = 0; j < ms.size(); j++) { - std::sort(d_m_vlist[ms[j]].begin(), d_m_vlist[ms[j]].end(), smv); - } - for (unsigned c = 0; c < 3; c++) { - // if (x,y,L) in cmp_infers, then x > y inferred as conclusion of L - // in lemmas - std::map<int, std::map<Node, std::map<Node, Node> > > cmp_infers; - Trace("nl-ext") << "Get comparison lemmas (order=" << r - << ", compare=" << c << ")..." << std::endl; - for (unsigned j = 0; j < ms.size(); j++) { - Node a = ms[j]; - if (ms_proc.find(a) == ms_proc.end()) { - if (c == 0) { - // compare magnitude against 1 - std::vector<Node> exp; - NodeMultiset a_exp_proc; - NodeMultiset b_exp_proc; - compareMonomial(a, a, a_exp_proc, d_one, d_one, b_exp_proc, exp, - lemmas, cmp_infers); - } else { - std::map<Node, NodeMultiset>::iterator itmea = d_m_exp.find(a); - Assert(itmea != d_m_exp.end()); - if (c == 1) { - // TODO : not just against containing variables? - // compare magnitude against variables - for (unsigned k = 0; k < ms_vars.size(); k++) { - Node v = ms_vars[k]; - std::vector<Node> exp; - NodeMultiset a_exp_proc; - NodeMultiset b_exp_proc; - if (itmea->second.find(v) != itmea->second.end()) { - a_exp_proc[v] = 1; - b_exp_proc[v] = 1; - setMonomialFactor(a, v, a_exp_proc); - setMonomialFactor(v, a, b_exp_proc); - compareMonomial(a, a, a_exp_proc, v, v, b_exp_proc, exp, - lemmas, cmp_infers); - } - } - } else { - // compare magnitude against other non-linear monomials - for (unsigned k = (j + 1); k < ms.size(); k++) { - Node b = ms[k]; - //(signs[a]==signs[b])==(r==0) - if (ms_proc.find(b) == ms_proc.end()) { - std::map<Node, NodeMultiset>::iterator itmeb = - d_m_exp.find(b); - Assert(itmeb != d_m_exp.end()); - - std::vector<Node> exp; - // take common factors of monomials, set minimum of - // common exponents as processed - NodeMultiset a_exp_proc; - NodeMultiset b_exp_proc; - for (NodeMultiset::iterator itmea2 = itmea->second.begin(); - itmea2 != itmea->second.end(); ++itmea2) { - NodeMultiset::iterator itmeb2 = - itmeb->second.find(itmea2->first); - if (itmeb2 != itmeb->second.end()) { - unsigned min_exp = itmea2->second > itmeb2->second - ? itmeb2->second - : itmea2->second; - a_exp_proc[itmea2->first] = min_exp; - b_exp_proc[itmea2->first] = min_exp; - Trace("nl-ext-comp") - << "Common exponent : " << itmea2->first << " : " - << min_exp << std::endl; - } - } - if (!a_exp_proc.empty()) { - setMonomialFactor(a, b, a_exp_proc); - setMonomialFactor(b, a, b_exp_proc); - } - /* - if( !a_exp_proc.empty() ){ - //reduction based on common exponents a > 0 => ( a * b - <> a * c <=> b <> c ), a < 0 => ( a * b <> a * c <=> b - !<> c ) ? }else{ compareMonomial( a, a, a_exp_proc, b, - b, b_exp_proc, exp, lemmas ); - } - */ - compareMonomial(a, a, a_exp_proc, b, b, b_exp_proc, exp, - lemmas, cmp_infers); - } - } - } - } - } - } - // remove redundant lemmas, e.g. if a > b, b > c, a > c were - // inferred, discard lemma with conclusion a > c - Trace("nl-ext-comp") << "Compute redundancies for " << lemmas.size() - << " lemmas." << std::endl; - // naive - std::vector<Node> r_lemmas; - for (std::map<int, std::map<Node, std::map<Node, Node> > >::iterator itb = - cmp_infers.begin(); - itb != cmp_infers.end(); ++itb) { - for (std::map<Node, std::map<Node, Node> >::iterator itc = - itb->second.begin(); - itc != itb->second.end(); ++itc) { - for (std::map<Node, Node>::iterator itc2 = itc->second.begin(); - itc2 != itc->second.end(); ++itc2) { - std::map<Node, bool> visited; - for (std::map<Node, Node>::iterator itc3 = itc->second.begin(); - itc3 != itc->second.end(); ++itc3) { - if (itc3->first != itc2->first) { - std::vector<Node> exp; - if (cmp_holds(itc3->first, itc2->first, itb->second, exp, - visited)) { - r_lemmas.push_back(itc2->second); - Trace("nl-ext-comp") - << "...inference of " << itc->first << " > " - << itc2->first << " was redundant." << std::endl; - break; - } - } - } - } - } - } - std::vector<Node> nr_lemmas; - for (unsigned i = 0; i < lemmas.size(); i++) { - if (std::find(r_lemmas.begin(), r_lemmas.end(), lemmas[i]) == - r_lemmas.end()) { - nr_lemmas.push_back(lemmas[i]); - } - } - // TODO: only take maximal lower/minimial lower bounds? + //-----------------------------------lemmas based on magnitude of non-zero monomials + Trace("nl-ext-proc") << "Assign order ids..." << std::endl; + unsigned r = 3; + assignOrderIds(d_ms_vars, d_order_vars, r); - Trace("nl-ext-comp") << nr_lemmas.size() << " / " << lemmas.size() - << " were non-redundant." << std::endl; - lemmas_proc = flushLemmas(nr_lemmas); - if (lemmas_proc > 0) { - Trace("nl-ext") << " ...finished with " << lemmas_proc - << " new lemmas (out of possible " << lemmas.size() - << ")." << std::endl; - return; - } + // sort individual variable lists + Trace("nl-ext-proc") << "Assign order var lists..." << std::endl; + SortNonlinearExtension smv; + smv.d_nla = this; + smv.d_order_type = r; + smv.d_reverse_order = true; + for (unsigned j = 0; j < d_ms.size(); j++) { + std::sort(d_m_vlist[d_ms[j]].begin(), d_m_vlist[d_ms[j]].end(), smv); + } + for (unsigned c = 0; c < 3; c++) { + // c is effort level + lemmas = checkMonomialMagnitude( c ); + lemmas_proc = flushLemmas(lemmas); + if (lemmas_proc > 0) { + Trace("nl-ext") << " ...finished with " << lemmas_proc + << " new lemmas (out of possible " << lemmas.size() + << ")." << std::endl; + return; } } // sort monomials by degree + Trace("nl-ext-proc") << "Sort monomials by degree..." << std::endl; SortNonlinearExtension snlad; snlad.d_nla = this; snlad.d_order_type = 4; snlad.d_reverse_order = false; - std::sort(ms.begin(), ms.end(), snlad); + std::sort(d_ms.begin(), d_ms.end(), snlad); // all monomials - std::vector<Node> terms; - terms.insert(terms.end(), ms_vars.begin(), ms_vars.end()); - terms.insert(terms.end(), ms.begin(), ms.end()); - - // term -> coeff -> rhs -> ( status, exp, b ), - // where we have that : exp => ( coeff * term <status> rhs ) - // b is true if degree( term ) >= degree( rhs ) - std::map<Node, std::map<Node, std::map<Node, Kind> > > ci; - std::map<Node, std::map<Node, std::map<Node, Node> > > ci_exp; - std::map<Node, std::map<Node, std::map<Node, bool> > > ci_max; - - // If ( m, p1, true ), then it would help satisfiability if m were ( > - // if p1=true, < if p1=false ) - std::map<Node, std::map<bool, bool> > tplane_refine_dir; - - // register constraints - Trace("nl-ext-debug") << "Register bound constraints..." << std::endl; - for (context::CDList<Assertion>::const_iterator it = - d_containing.facts_begin(); - it != d_containing.facts_end(); ++it) { - Node lit = (*it).assertion; - bool polarity = lit.getKind() != kind::NOT; - Node atom = lit.getKind() == kind::NOT ? lit[0] : lit; - registerConstraint(atom); - bool is_false_lit = false_asserts.find(lit) != false_asserts.end(); - // add information about bounds to variables - std::map<Node, std::map<Node, ConstraintInfo> >::iterator itc = - d_c_info.find(atom); - std::map<Node, std::map<Node, bool> >::iterator itcm = - d_c_info_maxm.find(atom); - if (itc != d_c_info.end()) { - Assert(itcm != d_c_info_maxm.end()); - for (std::map<Node, ConstraintInfo>::iterator itcc = itc->second.begin(); - itcc != itc->second.end(); ++itcc) { - Node x = itcc->first; - Node coeff = itcc->second.d_coeff; - Node rhs = itcc->second.d_rhs; - Kind type = itcc->second.d_type; - Node exp = lit; - if (!polarity) { - // reverse - if (type == kind::EQUAL) { - // we will take the strict inequality in the direction of the - // model - Node lhs = QuantArith::mkCoeffTerm(coeff, x); - Node query = NodeManager::currentNM()->mkNode(kind::GT, lhs, rhs); - Node query_mv = computeModelValue(query, 1); - if (query_mv == d_true) { - exp = query; - type = kind::GT; - } else { - Assert(query_mv == d_false); - exp = NodeManager::currentNM()->mkNode(kind::LT, lhs, rhs); - type = kind::LT; - } - } else { - type = negateKind(type); - } - } - // add to status if maximal degree - ci_max[x][coeff][rhs] = itcm->second.find(x) != itcm->second.end(); - if (Trace.isOn("nl-ext-bound-debug2")) { - Node t = QuantArith::mkCoeffTerm(coeff, x); - Trace("nl-ext-bound-debug2") - << "Add Bound: " << t << " " << type << " " << rhs << " by " - << exp << std::endl; - } - bool updated = true; - std::map<Node, Kind>::iterator its = ci[x][coeff].find(rhs); - if (its == ci[x][coeff].end()) { - ci[x][coeff][rhs] = type; - ci_exp[x][coeff][rhs] = exp; - } else if (type != its->second) { - Trace("nl-ext-bound-debug2") - << "Joining kinds : " << type << " " << its->second << std::endl; - Kind jk = joinKinds(type, its->second); - if (jk == kind::UNDEFINED_KIND) { - updated = false; - } else if (jk != its->second) { - if (jk == type) { - ci[x][coeff][rhs] = type; - ci_exp[x][coeff][rhs] = exp; - } else { - ci[x][coeff][rhs] = jk; - ci_exp[x][coeff][rhs] = NodeManager::currentNM()->mkNode( - kind::AND, ci_exp[x][coeff][rhs], exp); - } - } else { - updated = false; - } - } - if (Trace.isOn("nl-ext-bound")) { - if (updated) { - Trace("nl-ext-bound") << "Bound: "; - debugPrintBound("nl-ext-bound", coeff, x, ci[x][coeff][rhs], rhs); - Trace("nl-ext-bound") << " by " << ci_exp[x][coeff][rhs]; - if (ci_max[x][coeff][rhs]) { - Trace("nl-ext-bound") << ", is max degree"; - } - Trace("nl-ext-bound") << std::endl; - } - } - // compute if bound is not satisfied, and store what is required - // for a possible refinement - if (options::nlExtTangentPlanes()) { - if (is_false_lit) { - Node rhs_v = computeModelValue(rhs, 0); - Node x_v = computeModelValue(x, 0); - bool needsRefine = false; - bool refineDir; - if (rhs_v == x_v) { - if (type == kind::GT) { - needsRefine = true; - refineDir = true; - } else if (type == kind::LT) { - needsRefine = true; - refineDir = false; - } - } else if (x_v.getConst<Rational>() > rhs_v.getConst<Rational>()) { - if (type != kind::GT && type != kind::GEQ) { - needsRefine = true; - refineDir = false; - } - } else { - if (type != kind::LT && type != kind::LEQ) { - needsRefine = true; - refineDir = true; - } - } - Trace("nl-ext-tplanes-cons-debug") - << "...compute if bound corresponds to a required " - "refinement" - << std::endl; - Trace("nl-ext-tplanes-cons-debug") - << "...M[" << x << "] = " << x_v << ", M[" << rhs - << "] = " << rhs_v << std::endl; - Trace("nl-ext-tplanes-cons-debug") << "...refine = " << needsRefine - << "/" << refineDir << std::endl; - if (needsRefine) { - Trace("nl-ext-tplanes-cons") - << "---> By " << lit << " and since M[" << x << "] = " << x_v - << ", M[" << rhs << "] = " << rhs_v << ", "; - Trace("nl-ext-tplanes-cons") - << "monomial " << x << " should be " - << (refineDir ? "larger" : "smaller") << std::endl; - tplane_refine_dir[x][refineDir] = true; - } - } - } - } - } - } - // reflexive constraints - Node null_coeff; - for (unsigned j = 0; j < terms.size(); j++) { - Node n = terms[j]; - ci[n][null_coeff][n] = kind::EQUAL; - ci_exp[n][null_coeff][n] = d_true; - ci_max[n][null_coeff][n] = false; - } + d_mterms.insert(d_mterms.end(), d_ms_vars.begin(), d_ms_vars.end()); + d_mterms.insert(d_mterms.end(), d_ms.begin(), d_ms.end()); - //-----------------------------------------------------------------------------------------inferred - // bounds lemmas, e.g. x >= t => y*x >= y*t - Trace("nl-ext") << "Get inferred bound lemmas..." << std::endl; - - std::vector<Node> nt_lemmas; - for (unsigned k = 0; k < terms.size(); k++) { - Node x = terms[k]; - Trace("nl-ext-bound-debug") - << "Process bounds for " << x << " : " << std::endl; - std::map<Node, std::vector<Node> >::iterator itm = - d_m_contain_parent.find(x); - if (itm != d_m_contain_parent.end()) { - Trace("nl-ext-bound-debug") << "...has " << itm->second.size() - << " parent monomials." << std::endl; - // check derived bounds - std::map<Node, std::map<Node, std::map<Node, Kind> > >::iterator itc = - ci.find(x); - if (itc != ci.end()) { - for (std::map<Node, std::map<Node, Kind> >::iterator itcc = - itc->second.begin(); - itcc != itc->second.end(); ++itcc) { - Node coeff = itcc->first; - Node t = QuantArith::mkCoeffTerm(coeff, x); - for (std::map<Node, Kind>::iterator itcr = itcc->second.begin(); - itcr != itcc->second.end(); ++itcr) { - Node rhs = itcr->first; - // only consider this bound if maximal degree - if (ci_max[x][coeff][rhs]) { - Kind type = itcr->second; - for (unsigned j = 0; j < itm->second.size(); j++) { - Node y = itm->second[j]; - Assert(d_m_contain_mult[x].find(y) != - d_m_contain_mult[x].end()); - Node mult = d_m_contain_mult[x][y]; - // x <k> t => m*x <k'> t where y = m*x - // get the sign of mult - Node mmv = computeModelValue(mult); - Trace("nl-ext-bound-debug2") - << "Model value of " << mult << " is " << mmv << std::endl; - Assert(mmv.isConst()); - int mmv_sign = mmv.getConst<Rational>().sgn(); - Trace("nl-ext-bound-debug2") - << " sign of " << mmv << " is " << mmv_sign << std::endl; - if (mmv_sign != 0) { - Trace("nl-ext-bound-debug") - << " from " << x << " * " << mult << " = " << y - << " and " << t << " " << type << " " << rhs - << ", infer : " << std::endl; - Kind infer_type = - mmv_sign == -1 ? reverseRelationKind(type) : type; - Node infer_lhs = - NodeManager::currentNM()->mkNode(kind::MULT, mult, t); - Node infer_rhs = - NodeManager::currentNM()->mkNode(kind::MULT, mult, rhs); - Node infer = NodeManager::currentNM()->mkNode( - infer_type, infer_lhs, infer_rhs); - Trace("nl-ext-bound-debug") << " " << infer << std::endl; - infer = Rewriter::rewrite(infer); - Trace("nl-ext-bound-debug2") - << " ...rewritten : " << infer << std::endl; - // check whether it is false in model for abstraction - Node infer_mv = computeModelValue(infer, 1); - Trace("nl-ext-bound-debug") - << " ...infer model value is " << infer_mv - << std::endl; - if (infer_mv == d_false) { - Node exp = NodeManager::currentNM()->mkNode( - kind::AND, - NodeManager::currentNM()->mkNode( - mmv_sign == 1 ? kind::GT : kind::LT, mult, d_zero), - ci_exp[x][coeff][rhs]); - Node iblem = NodeManager::currentNM()->mkNode(kind::IMPLIES, - exp, infer); - Node pr_iblem = iblem; - iblem = Rewriter::rewrite(iblem); - bool introNewTerms = hasNewMonomials(iblem, ms); - Trace("nl-ext-bound-lemma") - << "*** Bound inference lemma : " << iblem - << " (pre-rewrite : " << pr_iblem << ")" << std::endl; - // Trace("nl-ext-bound-lemma") << " intro new - // monomials = " << introNewTerms << std::endl; - if (!introNewTerms) { - lemmas.push_back(iblem); - } else { - nt_lemmas.push_back(iblem); - } - } - } else { - Trace("nl-ext-bound-debug") << " ...coefficient " << mult - << " is zero." << std::endl; - } - } - } - } - } - } - } else { - Trace("nl-ext-bound-debug") << "...has no parent monomials." << std::endl; - } - } + //-----------------------------------inferred bounds lemmas + // e.g. x >= t => y*x >= y*t + std::vector< Node > nt_lemmas; + lemmas = checkMonomialInferBounds( nt_lemmas, false_asserts ); // Trace("nl-ext") << "Bound lemmas : " << lemmas.size() << ", " << // nt_lemmas.size() << std::endl; prioritize lemmas that do not // introduce new monomials @@ -1594,226 +1312,43 @@ void NonlinearExtension::checkLastCall(const std::vector<Node>& assertions, << std::endl; return; } - - //------------------------------------resolution bound inferences, e.g. - //( - // y>=0 ^ s <= x*z ^ x*y <= t ) => y*s <= z*t - if (options::nlExtResBound()) { - Trace("nl-ext") << "Get resolution inferred bound lemmas..." << std::endl; - for (unsigned j = 0; j < terms.size(); j++) { - Node a = terms[j]; - std::map<Node, std::map<Node, std::map<Node, Kind> > >::iterator itca = - ci.find(a); - if (itca != ci.end()) { - for (unsigned k = (j + 1); k < terms.size(); k++) { - Node b = terms[k]; - std::map<Node, std::map<Node, std::map<Node, Kind> > >::iterator - itcb = ci.find(b); - if (itcb != ci.end()) { - Trace("nl-ext-rbound-debug") << "resolution inferences : compare " - << a << " and " << b << std::endl; - // if they have common factors - std::map<Node, Node>::iterator ita = d_mono_diff[a].find(b); - if (ita != d_mono_diff[a].end()) { - std::map<Node, Node>::iterator itb = d_mono_diff[b].find(a); - Assert(itb != d_mono_diff[b].end()); - Node mv_a = computeModelValue(ita->second, 1); - Assert(mv_a.isConst()); - int mv_a_sgn = mv_a.getConst<Rational>().sgn(); - Assert(mv_a_sgn != 0); - Node mv_b = computeModelValue(itb->second, 1); - Assert(mv_b.isConst()); - int mv_b_sgn = mv_b.getConst<Rational>().sgn(); - Assert(mv_b_sgn != 0); - Trace("nl-ext-rbound") << "Get resolution inferences for [a] " - << a << " vs [b] " << b << std::endl; - Trace("nl-ext-rbound") - << " [a] factor is " << ita->second - << ", sign in model = " << mv_a_sgn << std::endl; - Trace("nl-ext-rbound") - << " [b] factor is " << itb->second - << ", sign in model = " << mv_b_sgn << std::endl; - - std::vector<Node> exp; - // bounds of a - for (std::map<Node, std::map<Node, Kind> >::iterator itcac = - itca->second.begin(); - itcac != itca->second.end(); ++itcac) { - Node coeff_a = itcac->first; - for (std::map<Node, Kind>::iterator itcar = - itcac->second.begin(); - itcar != itcac->second.end(); ++itcar) { - Node rhs_a = itcar->first; - Node rhs_a_res_base = NodeManager::currentNM()->mkNode( - kind::MULT, itb->second, rhs_a); - rhs_a_res_base = Rewriter::rewrite(rhs_a_res_base); - if (!hasNewMonomials(rhs_a_res_base, ms)) { - Kind type_a = itcar->second; - exp.push_back(ci_exp[a][coeff_a][rhs_a]); - - // bounds of b - for (std::map<Node, std::map<Node, Kind> >::iterator itcbc = - itcb->second.begin(); - itcbc != itcb->second.end(); ++itcbc) { - Node coeff_b = itcbc->first; - Node rhs_a_res = - QuantArith::mkCoeffTerm(coeff_b, rhs_a_res_base); - for (std::map<Node, Kind>::iterator itcbr = - itcbc->second.begin(); - itcbr != itcbc->second.end(); ++itcbr) { - Node rhs_b = itcbr->first; - Node rhs_b_res = NodeManager::currentNM()->mkNode( - kind::MULT, ita->second, rhs_b); - rhs_b_res = QuantArith::mkCoeffTerm(coeff_a, rhs_b_res); - rhs_b_res = Rewriter::rewrite(rhs_b_res); - if (!hasNewMonomials(rhs_b_res, ms)) { - Kind type_b = itcbr->second; - exp.push_back(ci_exp[b][coeff_b][rhs_b]); - if (Trace.isOn("nl-ext-rbound")) { - Trace("nl-ext-rbound") << "* try bounds : "; - debugPrintBound("nl-ext-rbound", coeff_a, a, type_a, - rhs_a); - Trace("nl-ext-rbound") << std::endl; - Trace("nl-ext-rbound") << " "; - debugPrintBound("nl-ext-rbound", coeff_b, b, type_b, - rhs_b); - Trace("nl-ext-rbound") << std::endl; - } - Kind types[2]; - for (unsigned r = 0; r < 2; r++) { - Node pivot_factor = - r == 0 ? itb->second : ita->second; - int pivot_factor_sign = - r == 0 ? mv_b_sgn : mv_a_sgn; - types[r] = r == 0 ? type_a : type_b; - if (pivot_factor_sign == (r == 0 ? 1 : -1)) { - types[r] = reverseRelationKind(types[r]); - } - if (pivot_factor_sign == 1) { - exp.push_back(NodeManager::currentNM()->mkNode( - kind::GT, pivot_factor, d_zero)); - } else { - exp.push_back(NodeManager::currentNM()->mkNode( - kind::LT, pivot_factor, d_zero)); - } - } - Kind jk = transKinds(types[0], types[1]); - Trace("nl-ext-rbound-debug") - << "trans kind : " << types[0] << " + " - << types[1] << " = " << jk << std::endl; - if (jk != kind::UNDEFINED_KIND) { - Node conc = NodeManager::currentNM()->mkNode( - jk, rhs_a_res, rhs_b_res); - Node conc_mv = computeModelValue(conc, 1); - if (conc_mv == d_false) { - Node rblem = NodeManager::currentNM()->mkNode( - kind::IMPLIES, - NodeManager::currentNM()->mkNode(kind::AND, - exp), - conc); - Trace("nl-ext-rbound-lemma-debug") - << "Resolution bound lemma " - "(pre-rewrite) " - ": " - << rblem << std::endl; - rblem = Rewriter::rewrite(rblem); - Trace("nl-ext-rbound-lemma") - << "Resolution bound lemma : " << rblem - << std::endl; - lemmas.push_back(rblem); - } - } - exp.pop_back(); - exp.pop_back(); - exp.pop_back(); - } - } - } - exp.pop_back(); - } - } - } - } - } - } - } - } - lemmas_proc = flushLemmas(lemmas); - if (lemmas_proc > 0) { - Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." - << std::endl; - return; - } - } - - // from inferred bound inferences + + // from inferred bound inferences : now do ones that introduce new terms lemmas_proc = flushLemmas(nt_lemmas); if (lemmas_proc > 0) { Trace("nl-ext") << " ...finished with " << lemmas_proc << " new (monomial-introducing) lemmas." << std::endl; return; } + + //------------------------------------factoring lemmas + // x*y + x*z >= t => exists k. k = y + z ^ x*k >= t + if( options::nlExtFactor() ){ + lemmas = checkFactoring( false_asserts ); + lemmas_proc = flushLemmas(lemmas); + if (lemmas_proc > 0) { + Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." << std::endl; + return; + } + } - if (options::nlExtTangentPlanes()) { - Trace("nl-ext") << "Get tangent plane lemmas..." << std::endl; - unsigned kstart = ms_vars.size(); - for (unsigned k = kstart; k < terms.size(); k++) { - Node t = terms[k]; - // if this term requires a refinement - if (tplane_refine_dir.find(t) != tplane_refine_dir.end()) { - Trace("nl-ext-tplanes") - << "Look at monomial requiring refinement : " << t << std::endl; - // get a decomposition - std::map<Node, std::vector<Node> >::iterator it = - d_m_contain_children.find(t); - if (it != d_m_contain_children.end()) { - std::map<Node, std::map<Node, bool> > dproc; - for (unsigned j = 0; j < it->second.size(); j++) { - Node tc = it->second[j]; - if (tc != d_one) { - Node tc_diff = d_m_contain_umult[tc][t]; - Assert(!tc_diff.isNull()); - Node a = tc < tc_diff ? tc : tc_diff; - Node b = tc < tc_diff ? tc_diff : tc; - if (dproc[a].find(b) == dproc[a].end()) { - dproc[a][b] = true; - Trace("nl-ext-tplanes") - << " decomposable into : " << a << " * " << b << std::endl; - Node a_v = computeModelValue(a, 1); - Node b_v = computeModelValue(b, 1); - // tangent plane - Node tplane = NodeManager::currentNM()->mkNode( - kind::MINUS, - NodeManager::currentNM()->mkNode( - kind::PLUS, - NodeManager::currentNM()->mkNode(kind::MULT, b_v, a), - NodeManager::currentNM()->mkNode(kind::MULT, a_v, b)), - NodeManager::currentNM()->mkNode(kind::MULT, a_v, b_v)); - for (unsigned d = 0; d < 4; d++) { - Node aa = NodeManager::currentNM()->mkNode( - d == 0 || d == 3 ? kind::GEQ : kind::LEQ, a, a_v); - Node ab = NodeManager::currentNM()->mkNode( - d == 1 || d == 3 ? kind::GEQ : kind::LEQ, b, b_v); - Node conc = NodeManager::currentNM()->mkNode( - d <= 1 ? kind::LEQ : kind::GEQ, t, tplane); - Node tlem = NodeManager::currentNM()->mkNode( - kind::OR, aa.negate(), ab.negate(), conc); - Trace("nl-ext-tplanes") - << "Tangent plane lemma : " << tlem << std::endl; - lemmas.push_back(tlem); - } - } - } - } - } - } + //------------------------------------resolution bound inferences + // e.g. ( y>=0 ^ s <= x*z ^ x*y <= t ) => y*s <= z*t + if (options::nlExtResBound()) { + lemmas = checkMonomialInferResBounds(); + lemmas_proc = flushLemmas(lemmas); + if (lemmas_proc > 0) { + Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." << std::endl; + return; } - Trace("nl-ext") << "...trying " << lemmas.size() - << " tangent plane lemmas..." << std::endl; + } + + //------------------------------------tangent planes + if (options::nlExtTangentPlanes()) { + lemmas = checkTangentPlanes(); lemmas_proc = flushLemmas(lemmas); if (lemmas_proc > 0) { - Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." - << std::endl; + Trace("nl-ext") << " ...finished with " << lemmas_proc << " new lemmas." << std::endl; return; } } @@ -1852,10 +1387,13 @@ void NonlinearExtension::check(Theory::Effort e) { const Assertion& assertion = *it; assertions.push_back(assertion.assertion); } - const std::set<Node> false_asserts = getFalseInModel(assertions); + + std::vector<Node> xts; + d_containing.getExtTheory()->getTerms(xts); + if (!false_asserts.empty()) { - checkLastCall(assertions, false_asserts); + checkLastCall(assertions, false_asserts, xts); }else{ //must ensure that shared terms are equal to their concrete value std::vector< Node > lemmas; @@ -1902,6 +1440,11 @@ void NonlinearExtension::assignOrderIds(std::vector<Node>& vars, for (unsigned j = 0; j < vars.size(); j++) { Node x = vars[j]; Node v = get_compare_value(x, orderType); + if( !v.isConst() ){ + Trace("nl-ext-mvo") << "..do not assign order to " << x << " : " << v << std::endl; + //don't assign for non-constant values (transcendental function apps) + break; + } Trace("nl-ext-mvo") << " order " << x << " : " << v << std::endl; if (v != prev) { // builtin points @@ -1944,8 +1487,21 @@ void NonlinearExtension::assignOrderIds(std::vector<Node>& vars, int NonlinearExtension::compare(Node i, Node j, unsigned orderType) const { Assert(orderType >= 0); if (orderType <= 3) { - return compare_value(get_compare_value(i, orderType), - get_compare_value(j, orderType), orderType); + Node ci = get_compare_value(i, orderType); + Node cj = get_compare_value(j, orderType); + if( ci.isConst() ){ + if( cj.isConst() ){ + return compare_value(ci, cj, orderType); + }else{ + return 1; + } + }else{ + if( cj.isConst() ){ + return -1; + }else{ + return 0; + } + } // minimal degree } else if (orderType == 4) { unsigned i_count = getCount(d_m_degree, i); @@ -1956,10 +1512,32 @@ int NonlinearExtension::compare(Node i, Node j, unsigned orderType) const { } } + + +void NonlinearExtension::mkPi(){ + if( d_pi.isNull() ){ + d_pi = NodeManager::currentNM()->mkNullaryOperator( NodeManager::currentNM()->realType(), kind::PI ); + d_pi_2 = Rewriter::rewrite( NodeManager::currentNM()->mkNode( kind::MULT, d_pi, NodeManager::currentNM()->mkConst( Rational(1)/Rational(2) ) ) ); + d_pi_neg_2 = Rewriter::rewrite( NodeManager::currentNM()->mkNode( kind::MULT, d_pi, NodeManager::currentNM()->mkConst( Rational(-1)/Rational(2) ) ) ); + d_pi_neg = Rewriter::rewrite( NodeManager::currentNM()->mkNode( kind::MULT, d_pi, NodeManager::currentNM()->mkConst( Rational(-1) ) ) ); + //initialize bounds + d_pi_bound[0] = NodeManager::currentNM()->mkConst( Rational(333)/Rational(106) ); + d_pi_bound[1] = NodeManager::currentNM()->mkConst( Rational(355)/Rational(113) ); + } +} + +void NonlinearExtension::getCurrentPiBounds( std::vector< Node >& lemmas ) { + Node pi_lem = NodeManager::currentNM()->mkNode( kind::AND, + NodeManager::currentNM()->mkNode( kind::GT, d_pi, d_pi_bound[0] ), + NodeManager::currentNM()->mkNode( kind::LT, d_pi, d_pi_bound[1] ) ); + lemmas.push_back( pi_lem ); +} + int NonlinearExtension::compare_value(Node i, Node j, unsigned orderType) const { Assert(orderType >= 0 && orderType <= 3); - Trace("nl-ext-debug") << "compare_value " << i << " " << j + Assert( i.isConst() && j.isConst() ); + Trace("nl-ext-debug") << "compare value " << i << " " << j << ", o = " << orderType << std::endl; int ret; if (i == j) { @@ -1991,8 +1569,7 @@ Node NonlinearExtension::get_compare_value(Node i, unsigned orderType) const { return iti->second; } -// trying to show a <> 0 by inequalities between variables in monomial a w.r.t -// 0 +// show a <> 0 by inequalities between variables in monomial a w.r.t 0 int NonlinearExtension::compareSign(Node oa, Node a, unsigned a_index, int status, std::vector<Node>& exp, std::vector<Node>& lem) { @@ -2011,8 +1588,9 @@ int NonlinearExtension::compareSign(Node oa, Node a, unsigned a_index, Node av = d_m_vlist[a][a_index]; unsigned aexp = d_m_exp[a][av]; // take current sign in model - Assert(d_mv[0].find(av) != d_mv[0].end()); - int sgn = d_mv[0][av].getConst<Rational>().sgn(); + Assert( d_mv[1].find(av) != d_mv[0].end() ); + Assert( d_mv[1][av].isConst() ); + int sgn = d_mv[1][av].getConst<Rational>().sgn(); Trace("nl-ext-debug") << "Process var " << av << "^" << aexp << ", model sign = " << sgn << std::endl; if (sgn == 0) { @@ -2126,8 +1704,8 @@ bool NonlinearExtension::compareMonomial( return compareMonomial(oa, a, a_index + 1, a_exp_proc, ob, b, b_index, b_exp_proc, status, exp, lem, cmp_infers); } - Assert(d_order_vars[1].find(av) != d_order_vars[1].end()); - avo = d_order_vars[1][av]; + Assert(d_order_vars.find(av) != d_order_vars.end()); + avo = d_order_vars[av]; } Node bv; unsigned bexp = 0; @@ -2140,12 +1718,12 @@ bool NonlinearExtension::compareMonomial( return compareMonomial(oa, a, a_index, a_exp_proc, ob, b, b_index + 1, b_exp_proc, status, exp, lem, cmp_infers); } - Assert(d_order_vars[1].find(bv) != d_order_vars[1].end()); - bvo = d_order_vars[1][bv]; + Assert(d_order_vars.find(bv) != d_order_vars.end()); + bvo = d_order_vars[bv]; } // get "one" information - Assert(d_order_vars[1].find(d_one) != d_order_vars[1].end()); - unsigned ovo = d_order_vars[1][d_one]; + Assert(d_order_vars.find(d_one) != d_order_vars.end()); + unsigned ovo = d_order_vars[d_one]; Trace("nl-ext-comp-debug") << "....vars : " << av << "^" << aexp << " " << bv << "^" << bexp << std::endl; @@ -2266,6 +1844,1024 @@ void NonlinearExtension::MonomialIndex::addTerm(Node n, } } +std::vector<Node> NonlinearExtension::checkMonomialSign() { + std::vector<Node> lemmas; + std::map<Node, int> signs; + Trace("nl-ext") << "Get monomial sign lemmas..." << std::endl; + for (unsigned j = 0; j < d_ms.size(); j++) { + Node a = d_ms[j]; + if (d_ms_proc.find(a) == d_ms_proc.end()) { + std::vector<Node> exp; + Trace("nl-ext-debug") << " process " << a << ", mv=" << d_mv[0][a] << "..." << std::endl; + if( d_m_nconst_factor.find( a )==d_m_nconst_factor.end() ){ + signs[a] = compareSign(a, a, 0, 1, exp, lemmas); + if (signs[a] == 0) { + d_ms_proc[a] = true; + Trace("nl-ext-debug") << "...mark " << a + << " reduced since its value is 0." << std::endl; + } + }else{ + Trace("nl-ext-debug") << "...can't conclude sign lemma for " << a << " since model value of a factor is non-constant." << std::endl; + //TODO + } + } + } + return lemmas; +} + +std::vector<Node> NonlinearExtension::checkMonomialMagnitude( unsigned c ) { + unsigned r = 1; + std::vector<Node> lemmas; +// if (x,y,L) in cmp_infers, then x > y inferred as conclusion of L + // in lemmas + std::map<int, std::map<Node, std::map<Node, Node> > > cmp_infers; + Trace("nl-ext") << "Get monomial comparison lemmas (order=" << r + << ", compare=" << c << ")..." << std::endl; + for (unsigned j = 0; j < d_ms.size(); j++) { + Node a = d_ms[j]; + if (d_ms_proc.find(a) == d_ms_proc.end() && + d_m_nconst_factor.find( a )==d_m_nconst_factor.end()) { + if (c == 0) { + // compare magnitude against 1 + std::vector<Node> exp; + NodeMultiset a_exp_proc; + NodeMultiset b_exp_proc; + compareMonomial(a, a, a_exp_proc, d_one, d_one, b_exp_proc, exp, + lemmas, cmp_infers); + } else { + std::map<Node, NodeMultiset>::iterator itmea = d_m_exp.find(a); + Assert(itmea != d_m_exp.end()); + if (c == 1) { + // TODO : not just against containing variables? + // compare magnitude against variables + for (unsigned k = 0; k < d_ms_vars.size(); k++) { + Node v = d_ms_vars[k]; + Assert( d_mv[0].find( v )!=d_mv[0].end() ); + if( d_mv[0][v].isConst() ){ + std::vector<Node> exp; + NodeMultiset a_exp_proc; + NodeMultiset b_exp_proc; + if (itmea->second.find(v) != itmea->second.end()) { + a_exp_proc[v] = 1; + b_exp_proc[v] = 1; + setMonomialFactor(a, v, a_exp_proc); + setMonomialFactor(v, a, b_exp_proc); + compareMonomial(a, a, a_exp_proc, v, v, b_exp_proc, exp, + lemmas, cmp_infers); + } + } + } + } else { + // compare magnitude against other non-linear monomials + for (unsigned k = (j + 1); k < d_ms.size(); k++) { + Node b = d_ms[k]; + //(signs[a]==signs[b])==(r==0) + if (d_ms_proc.find(b) == d_ms_proc.end() && + d_m_nconst_factor.find( b )==d_m_nconst_factor.end()) { + std::map<Node, NodeMultiset>::iterator itmeb = + d_m_exp.find(b); + Assert(itmeb != d_m_exp.end()); + + std::vector<Node> exp; + // take common factors of monomials, set minimum of + // common exponents as processed + NodeMultiset a_exp_proc; + NodeMultiset b_exp_proc; + for (NodeMultiset::iterator itmea2 = itmea->second.begin(); + itmea2 != itmea->second.end(); ++itmea2) { + NodeMultiset::iterator itmeb2 = + itmeb->second.find(itmea2->first); + if (itmeb2 != itmeb->second.end()) { + unsigned min_exp = itmea2->second > itmeb2->second + ? itmeb2->second + : itmea2->second; + a_exp_proc[itmea2->first] = min_exp; + b_exp_proc[itmea2->first] = min_exp; + Trace("nl-ext-comp") + << "Common exponent : " << itmea2->first << " : " + << min_exp << std::endl; + } + } + if (!a_exp_proc.empty()) { + setMonomialFactor(a, b, a_exp_proc); + setMonomialFactor(b, a, b_exp_proc); + } + /* + if( !a_exp_proc.empty() ){ + //reduction based on common exponents a > 0 => ( a * b + <> a * c <=> b <> c ), a < 0 => ( a * b <> a * c <=> b + !<> c ) ? }else{ compareMonomial( a, a, a_exp_proc, b, + b, b_exp_proc, exp, lemmas ); + } + */ + compareMonomial(a, a, a_exp_proc, b, b, b_exp_proc, exp, + lemmas, cmp_infers); + } + } + } + } + } + } + // remove redundant lemmas, e.g. if a > b, b > c, a > c were + // inferred, discard lemma with conclusion a > c + Trace("nl-ext-comp") << "Compute redundand_cies for " << lemmas.size() + << " lemmas." << std::endl; + // naive + std::vector<Node> r_lemmas; + for (std::map<int, std::map<Node, std::map<Node, Node> > >::iterator itb = + cmp_infers.begin(); + itb != cmp_infers.end(); ++itb) { + for (std::map<Node, std::map<Node, Node> >::iterator itc = + itb->second.begin(); + itc != itb->second.end(); ++itc) { + for (std::map<Node, Node>::iterator itc2 = itc->second.begin(); + itc2 != itc->second.end(); ++itc2) { + std::map<Node, bool> visited; + for (std::map<Node, Node>::iterator itc3 = itc->second.begin(); + itc3 != itc->second.end(); ++itc3) { + if (itc3->first != itc2->first) { + std::vector<Node> exp; + if (cmp_holds(itc3->first, itc2->first, itb->second, exp, + visited)) { + r_lemmas.push_back(itc2->second); + Trace("nl-ext-comp") + << "...inference of " << itc->first << " > " + << itc2->first << " was redundant." << std::endl; + break; + } + } + } + } + } + } + std::vector<Node> nr_lemmas; + for (unsigned i = 0; i < lemmas.size(); i++) { + if (std::find(r_lemmas.begin(), r_lemmas.end(), lemmas[i]) == + r_lemmas.end()) { + nr_lemmas.push_back(lemmas[i]); + } + } + // TODO: only take maximal lower/minimial lower bounds? + + Trace("nl-ext-comp") << nr_lemmas.size() << " / " << lemmas.size() + << " were non-redundant." << std::endl; + return nr_lemmas; +} + +std::vector<Node> NonlinearExtension::checkTangentPlanes() { + std::vector< Node > lemmas; + Trace("nl-ext") << "Get monomial tangent plane lemmas..." << std::endl; + unsigned kstart = d_ms_vars.size(); + for (unsigned k = kstart; k < d_mterms.size(); k++) { + Node t = d_mterms[k]; + // if this term requires a refinement + if (d_tplane_refine_dir.find(t) != d_tplane_refine_dir.end()) { + Trace("nl-ext-tplanes") + << "Look at monomial requiring refinement : " << t << std::endl; + // get a decomposition + std::map<Node, std::vector<Node> >::iterator it = + d_m_contain_children.find(t); + if (it != d_m_contain_children.end()) { + std::map<Node, std::map<Node, bool> > dproc; + for (unsigned j = 0; j < it->second.size(); j++) { + Node tc = it->second[j]; + if (tc != d_one) { + Node tc_diff = d_m_contain_umult[tc][t]; + Assert(!tc_diff.isNull()); + Node a = tc < tc_diff ? tc : tc_diff; + Node b = tc < tc_diff ? tc_diff : tc; + if (dproc[a].find(b) == dproc[a].end()) { + dproc[a][b] = true; + Trace("nl-ext-tplanes") + << " decomposable into : " << a << " * " << b << std::endl; + Node a_v = computeModelValue(a, 1); + Node b_v = computeModelValue(b, 1); + // tangent plane + Node tplane = NodeManager::currentNM()->mkNode( + kind::MINUS, + NodeManager::currentNM()->mkNode( + kind::PLUS, + NodeManager::currentNM()->mkNode(kind::MULT, b_v, a), + NodeManager::currentNM()->mkNode(kind::MULT, a_v, b)), + NodeManager::currentNM()->mkNode(kind::MULT, a_v, b_v)); + for (unsigned d = 0; d < 4; d++) { + Node aa = NodeManager::currentNM()->mkNode( + d == 0 || d == 3 ? kind::GEQ : kind::LEQ, a, a_v); + Node ab = NodeManager::currentNM()->mkNode( + d == 1 || d == 3 ? kind::GEQ : kind::LEQ, b, b_v); + Node conc = NodeManager::currentNM()->mkNode( + d <= 1 ? kind::LEQ : kind::GEQ, t, tplane); + Node tlem = NodeManager::currentNM()->mkNode( + kind::OR, aa.negate(), ab.negate(), conc); + Trace("nl-ext-tplanes") + << "Tangent plane lemma : " << tlem << std::endl; + lemmas.push_back(tlem); + } + } + } + } + } + } + } + Trace("nl-ext") << "...trying " << lemmas.size() + << " tangent plane lemmas..." << std::endl; + return lemmas; +} + + + +std::vector<Node> NonlinearExtension::checkMonomialInferBounds( std::vector<Node>& nt_lemmas, + const std::set<Node>& false_asserts ) { + std::vector< Node > lemmas; + // register constraints + Trace("nl-ext-debug") << "Register bound constraints..." << std::endl; + for (context::CDList<Assertion>::const_iterator it = + d_containing.facts_begin(); + it != d_containing.facts_end(); ++it) { + Node lit = (*it).assertion; + bool polarity = lit.getKind() != kind::NOT; + Node atom = lit.getKind() == kind::NOT ? lit[0] : lit; + registerConstraint(atom); + bool is_false_lit = false_asserts.find(lit) != false_asserts.end(); + // add information about bounds to variables + std::map<Node, std::map<Node, ConstraintInfo> >::iterator itc = + d_c_info.find(atom); + std::map<Node, std::map<Node, bool> >::iterator itcm = + d_c_info_maxm.find(atom); + if (itc != d_c_info.end()) { + Assert(itcm != d_c_info_maxm.end()); + for (std::map<Node, ConstraintInfo>::iterator itcc = itc->second.begin(); + itcc != itc->second.end(); ++itcc) { + Node x = itcc->first; + Node coeff = itcc->second.d_coeff; + Node rhs = itcc->second.d_rhs; + Kind type = itcc->second.d_type; + Node exp = lit; + if (!polarity) { + // reverse + if (type == kind::EQUAL) { + // we will take the strict inequality in the direction of the + // model + Node lhs = QuantArith::mkCoeffTerm(coeff, x); + Node query = NodeManager::currentNM()->mkNode(kind::GT, lhs, rhs); + Node query_mv = computeModelValue(query, 1); + if (query_mv == d_true) { + exp = query; + type = kind::GT; + } else { + Assert(query_mv == d_false); + exp = NodeManager::currentNM()->mkNode(kind::LT, lhs, rhs); + type = kind::LT; + } + } else { + type = negateKind(type); + } + } + // add to status if maximal degree + d_ci_max[x][coeff][rhs] = itcm->second.find(x) != itcm->second.end(); + if (Trace.isOn("nl-ext-bound-debug2")) { + Node t = QuantArith::mkCoeffTerm(coeff, x); + Trace("nl-ext-bound-debug2") + << "Add Bound: " << t << " " << type << " " << rhs << " by " + << exp << std::endl; + } + bool updated = true; + std::map<Node, Kind>::iterator its = d_ci[x][coeff].find(rhs); + if (its == d_ci[x][coeff].end()) { + d_ci[x][coeff][rhs] = type; + d_ci_exp[x][coeff][rhs] = exp; + } else if (type != its->second) { + Trace("nl-ext-bound-debug2") + << "Joining kinds : " << type << " " << its->second << std::endl; + Kind jk = joinKinds(type, its->second); + if (jk == kind::UNDEFINED_KIND) { + updated = false; + } else if (jk != its->second) { + if (jk == type) { + d_ci[x][coeff][rhs] = type; + d_ci_exp[x][coeff][rhs] = exp; + } else { + d_ci[x][coeff][rhs] = jk; + d_ci_exp[x][coeff][rhs] = NodeManager::currentNM()->mkNode( + kind::AND, d_ci_exp[x][coeff][rhs], exp); + } + } else { + updated = false; + } + } + if (Trace.isOn("nl-ext-bound")) { + if (updated) { + Trace("nl-ext-bound") << "Bound: "; + debugPrintBound("nl-ext-bound", coeff, x, d_ci[x][coeff][rhs], rhs); + Trace("nl-ext-bound") << " by " << d_ci_exp[x][coeff][rhs]; + if (d_ci_max[x][coeff][rhs]) { + Trace("nl-ext-bound") << ", is max degree"; + } + Trace("nl-ext-bound") << std::endl; + } + } + // compute if bound is not satisfied, and store what is required + // for a possible refinement + if (options::nlExtTangentPlanes()) { + if (is_false_lit) { + Node rhs_v = computeModelValue(rhs, 0); + Node x_v = computeModelValue(x, 0); + if( rhs_v.isConst() && x_v.isConst() ){ + bool needsRefine = false; + bool refineDir; + if (rhs_v == x_v) { + if (type == kind::GT) { + needsRefine = true; + refineDir = true; + } else if (type == kind::LT) { + needsRefine = true; + refineDir = false; + } + } else if (x_v.getConst<Rational>() > rhs_v.getConst<Rational>()) { + if (type != kind::GT && type != kind::GEQ) { + needsRefine = true; + refineDir = false; + } + } else { + if (type != kind::LT && type != kind::LEQ) { + needsRefine = true; + refineDir = true; + } + } + Trace("nl-ext-tplanes-cons-debug") + << "...compute if bound corresponds to a required " + "refinement" + << std::endl; + Trace("nl-ext-tplanes-cons-debug") + << "...M[" << x << "] = " << x_v << ", M[" << rhs + << "] = " << rhs_v << std::endl; + Trace("nl-ext-tplanes-cons-debug") << "...refine = " << needsRefine + << "/" << refineDir << std::endl; + if (needsRefine) { + Trace("nl-ext-tplanes-cons") + << "---> By " << lit << " and since M[" << x << "] = " << x_v + << ", M[" << rhs << "] = " << rhs_v << ", "; + Trace("nl-ext-tplanes-cons") + << "monomial " << x << " should be " + << (refineDir ? "larger" : "smaller") << std::endl; + d_tplane_refine_dir[x][refineDir] = true; + } + } + } + } + } + } + } + // reflexive constraints + Node null_coeff; + for (unsigned j = 0; j < d_mterms.size(); j++) { + Node n = d_mterms[j]; + d_ci[n][null_coeff][n] = kind::EQUAL; + d_ci_exp[n][null_coeff][n] = d_true; + d_ci_max[n][null_coeff][n] = false; + } + + Trace("nl-ext") << "Get inferred bound lemmas..." << std::endl; + + for (unsigned k = 0; k < d_mterms.size(); k++) { + Node x = d_mterms[k]; + Trace("nl-ext-bound-debug") + << "Process bounds for " << x << " : " << std::endl; + std::map<Node, std::vector<Node> >::iterator itm = + d_m_contain_parent.find(x); + if (itm != d_m_contain_parent.end()) { + Trace("nl-ext-bound-debug") << "...has " << itm->second.size() + << " parent monomials." << std::endl; + // check derived bounds + std::map<Node, std::map<Node, std::map<Node, Kind> > >::iterator itc = + d_ci.find(x); + if (itc != d_ci.end()) { + for (std::map<Node, std::map<Node, Kind> >::iterator itcc = + itc->second.begin(); + itcc != itc->second.end(); ++itcc) { + Node coeff = itcc->first; + Node t = QuantArith::mkCoeffTerm(coeff, x); + for (std::map<Node, Kind>::iterator itcr = itcc->second.begin(); + itcr != itcc->second.end(); ++itcr) { + Node rhs = itcr->first; + // only consider this bound if maximal degree + if (d_ci_max[x][coeff][rhs]) { + Kind type = itcr->second; + for (unsigned j = 0; j < itm->second.size(); j++) { + Node y = itm->second[j]; + Assert(d_m_contain_mult[x].find(y) != + d_m_contain_mult[x].end()); + Node mult = d_m_contain_mult[x][y]; + // x <k> t => m*x <k'> t where y = m*x + // get the sign of mult + Node mmv = computeModelValue(mult); + Trace("nl-ext-bound-debug2") + << "Model value of " << mult << " is " << mmv << std::endl; + if(mmv.isConst()){ + int mmv_sign = mmv.getConst<Rational>().sgn(); + Trace("nl-ext-bound-debug2") + << " sign of " << mmv << " is " << mmv_sign << std::endl; + if (mmv_sign != 0) { + Trace("nl-ext-bound-debug") + << " from " << x << " * " << mult << " = " << y + << " and " << t << " " << type << " " << rhs + << ", infer : " << std::endl; + Kind infer_type = + mmv_sign == -1 ? reverseRelationKind(type) : type; + Node infer_lhs = + NodeManager::currentNM()->mkNode(kind::MULT, mult, t); + Node infer_rhs = + NodeManager::currentNM()->mkNode(kind::MULT, mult, rhs); + Node infer = NodeManager::currentNM()->mkNode( + infer_type, infer_lhs, infer_rhs); + Trace("nl-ext-bound-debug") << " " << infer << std::endl; + infer = Rewriter::rewrite(infer); + Trace("nl-ext-bound-debug2") + << " ...rewritten : " << infer << std::endl; + // check whether it is false in model for abstraction + Node infer_mv = computeModelValue(infer, 1); + Trace("nl-ext-bound-debug") + << " ...infer model value is " << infer_mv + << std::endl; + if (infer_mv == d_false) { + Node exp = NodeManager::currentNM()->mkNode( + kind::AND, + NodeManager::currentNM()->mkNode( + mmv_sign == 1 ? kind::GT : kind::LT, mult, d_zero), + d_ci_exp[x][coeff][rhs]); + Node iblem = NodeManager::currentNM()->mkNode(kind::IMPLIES, + exp, infer); + Node pr_iblem = iblem; + iblem = Rewriter::rewrite(iblem); + bool introNewTerms = hasNewMonomials(iblem, d_ms); + Trace("nl-ext-bound-lemma") + << "*** Bound inference lemma : " << iblem + << " (pre-rewrite : " << pr_iblem << ")" << std::endl; + // Trace("nl-ext-bound-lemma") << " intro new + // monomials = " << introNewTerms << std::endl; + if (!introNewTerms) { + lemmas.push_back(iblem); + } else { + nt_lemmas.push_back(iblem); + } + } + } else { + Trace("nl-ext-bound-debug") << " ...coefficient " << mult + << " is zero." << std::endl; + } + }else{ + Trace("nl-ext-bound-debug") << " ...coefficient " << mult + << " is non-constant (probably transcendental)." << std::endl; + } + } + } + } + } + } + } else { + Trace("nl-ext-bound-debug") << "...has no parent monomials." << std::endl; + } + } + return lemmas; +} + +std::vector<Node> NonlinearExtension::checkFactoring( const std::set<Node>& false_asserts ) { + std::vector< Node > lemmas; + Trace("nl-ext") << "Get factoring lemmas..." << std::endl; + for (context::CDList<Assertion>::const_iterator it = + d_containing.facts_begin(); + it != d_containing.facts_end(); ++it) { + Node lit = (*it).assertion; + bool polarity = lit.getKind() != kind::NOT; + Node atom = lit.getKind() == kind::NOT ? lit[0] : lit; + if( false_asserts.find(lit) != false_asserts.end() || d_skolem_atoms.find(atom)!=d_skolem_atoms.end() ){ + std::map<Node, Node> msum; + if (QuantArith::getMonomialSumLit(atom, msum)) { + Trace("nl-ext-factor") << "Factoring for literal " << lit << ", monomial sum is : " << std::endl; + if (Trace.isOn("nl-ext-factor")) { + QuantArith::debugPrintMonomialSum(msum, "nl-ext-factor"); + } + std::map< Node, std::vector< Node > > factor_to_mono; + std::map< Node, std::vector< Node > > factor_to_mono_orig; + for( std::map<Node, Node>::iterator itm = msum.begin(); itm != msum.end(); ++itm ){ + if( !itm->first.isNull() ){ + if( itm->first.getKind()==NONLINEAR_MULT ){ + std::vector< Node > children; + for( unsigned i=0; i<itm->first.getNumChildren(); i++ ){ + children.push_back( itm->first[i] ); + } + std::map< Node, bool > processed; + for( unsigned i=0; i<itm->first.getNumChildren(); i++ ){ + if( processed.find( itm->first[i] )==processed.end() ){ + processed[itm->first[i]] = true; + children[i] = d_one; + if( !itm->second.isNull() ){ + children.push_back( itm->second ); + } + Node val = NodeManager::currentNM()->mkNode( kind::MULT, children ); + if( !itm->second.isNull() ){ + children.pop_back(); + } + children[i] = itm->first[i]; + val = Rewriter::rewrite( val ); + factor_to_mono[itm->first[i]].push_back( val ); + factor_to_mono_orig[itm->first[i]].push_back( itm->first ); + } + } + } /* else{ + factor_to_mono[itm->first].push_back( itm->second.isNull() ? d_one : itm->second ); + factor_to_mono_orig[itm->first].push_back( itm->first ); + }*/ + } + } + for( std::map< Node, std::vector< Node > >::iterator itf = factor_to_mono.begin(); itf != factor_to_mono.end(); ++itf ){ + if( itf->second.size()>1 ){ + Node sum = NodeManager::currentNM()->mkNode( kind::PLUS, itf->second ); + sum = Rewriter::rewrite( sum ); + Trace("nl-ext-factor") << "* Factored sum for " << itf->first << " : " << sum << std::endl; + Node kf = getFactorSkolem( sum, lemmas ); + std::vector< Node > poly; + poly.push_back( NodeManager::currentNM()->mkNode( kind::MULT, itf->first, kf ) ); + std::map< Node, std::vector< Node > >::iterator itfo = factor_to_mono_orig.find( itf->first ); + Assert( itfo!=factor_to_mono_orig.end() ); + for( std::map<Node, Node>::iterator itm = msum.begin(); itm != msum.end(); ++itm ){ + if( std::find( itfo->second.begin(), itfo->second.end(), itm->first )==itfo->second.end() ){ + poly.push_back( QuantArith::mkCoeffTerm(itm->second, itm->first.isNull() ? d_one : itm->first) ); + } + } + Node polyn = poly.size()==1 ? poly[0] : NodeManager::currentNM()->mkNode( kind::PLUS, poly ); + Trace("nl-ext-factor") << "...factored polynomial : " << polyn << std::endl; + Node conc_lit = NodeManager::currentNM()->mkNode( atom.getKind(), polyn, d_zero ); + conc_lit = Rewriter::rewrite( conc_lit ); + d_skolem_atoms.insert( conc_lit ); + if( !polarity ){ + conc_lit = conc_lit.negate(); + } + + std::vector< Node > lemma_disj; + lemma_disj.push_back( lit.negate() ); + lemma_disj.push_back( conc_lit ); + Node flem = NodeManager::currentNM()->mkNode( kind::OR, lemma_disj ); + Trace("nl-ext-factor") << "...lemma is " << flem << std::endl; + lemmas.push_back( flem ); + } + } + } + } + } + return lemmas; +} + +Node NonlinearExtension::getFactorSkolem( Node n, std::vector< Node >& lemmas ) { + std::map< Node, Node >::iterator itf = d_factor_skolem.find( n ); + if( itf==d_factor_skolem.end() ){ + Node k = NodeManager::currentNM()->mkSkolem( "kf", n.getType() ); + Node k_eq = Rewriter::rewrite( k.eqNode( n ) ); + d_skolem_atoms.insert( k_eq ); + lemmas.push_back( k_eq ); + d_factor_skolem[n] = k; + return k; + }else{ + return itf->second; + } +} + +std::vector<Node> NonlinearExtension::checkMonomialInferResBounds() { + std::vector< Node > lemmas; + Trace("nl-ext") << "Get monomial resolution inferred bound lemmas..." << std::endl; + for (unsigned j = 0; j < d_mterms.size(); j++) { + Node a = d_mterms[j]; + std::map<Node, std::map<Node, std::map<Node, Kind> > >::iterator itca = + d_ci.find(a); + if (itca != d_ci.end()) { + for (unsigned k = (j + 1); k < d_mterms.size(); k++) { + Node b = d_mterms[k]; + std::map<Node, std::map<Node, std::map<Node, Kind> > >::iterator + itcb = d_ci.find(b); + if (itcb != d_ci.end()) { + Trace("nl-ext-rbound-debug") << "resolution inferences : compare " + << a << " and " << b << std::endl; + // if they have common factors + std::map<Node, Node>::iterator ita = d_mono_diff[a].find(b); + if (ita != d_mono_diff[a].end()) { + std::map<Node, Node>::iterator itb = d_mono_diff[b].find(a); + Assert(itb != d_mono_diff[b].end()); + Node mv_a = computeModelValue(ita->second, 1); + Assert(mv_a.isConst()); + int mv_a_sgn = mv_a.getConst<Rational>().sgn(); + Assert(mv_a_sgn != 0); + Node mv_b = computeModelValue(itb->second, 1); + Assert(mv_b.isConst()); + int mv_b_sgn = mv_b.getConst<Rational>().sgn(); + Assert(mv_b_sgn != 0); + Trace("nl-ext-rbound") << "Get resolution inferences for [a] " + << a << " vs [b] " << b << std::endl; + Trace("nl-ext-rbound") + << " [a] factor is " << ita->second + << ", sign in model = " << mv_a_sgn << std::endl; + Trace("nl-ext-rbound") + << " [b] factor is " << itb->second + << ", sign in model = " << mv_b_sgn << std::endl; + + std::vector<Node> exp; + // bounds of a + for (std::map<Node, std::map<Node, Kind> >::iterator itcac = + itca->second.begin(); + itcac != itca->second.end(); ++itcac) { + Node coeff_a = itcac->first; + for (std::map<Node, Kind>::iterator itcar = + itcac->second.begin(); + itcar != itcac->second.end(); ++itcar) { + Node rhs_a = itcar->first; + Node rhs_a_res_base = NodeManager::currentNM()->mkNode( + kind::MULT, itb->second, rhs_a); + rhs_a_res_base = Rewriter::rewrite(rhs_a_res_base); + if (!hasNewMonomials(rhs_a_res_base, d_ms)) { + Kind type_a = itcar->second; + exp.push_back(d_ci_exp[a][coeff_a][rhs_a]); + + // bounds of b + for (std::map<Node, std::map<Node, Kind> >::iterator itcbc = + itcb->second.begin(); + itcbc != itcb->second.end(); ++itcbc) { + Node coeff_b = itcbc->first; + Node rhs_a_res = + QuantArith::mkCoeffTerm(coeff_b, rhs_a_res_base); + for (std::map<Node, Kind>::iterator itcbr = + itcbc->second.begin(); + itcbr != itcbc->second.end(); ++itcbr) { + Node rhs_b = itcbr->first; + Node rhs_b_res = NodeManager::currentNM()->mkNode( + kind::MULT, ita->second, rhs_b); + rhs_b_res = QuantArith::mkCoeffTerm(coeff_a, rhs_b_res); + rhs_b_res = Rewriter::rewrite(rhs_b_res); + if (!hasNewMonomials(rhs_b_res, d_ms)) { + Kind type_b = itcbr->second; + exp.push_back(d_ci_exp[b][coeff_b][rhs_b]); + if (Trace.isOn("nl-ext-rbound")) { + Trace("nl-ext-rbound") << "* try bounds : "; + debugPrintBound("nl-ext-rbound", coeff_a, a, type_a, + rhs_a); + Trace("nl-ext-rbound") << std::endl; + Trace("nl-ext-rbound") << " "; + debugPrintBound("nl-ext-rbound", coeff_b, b, type_b, + rhs_b); + Trace("nl-ext-rbound") << std::endl; + } + Kind types[2]; + for (unsigned r = 0; r < 2; r++) { + Node pivot_factor = + r == 0 ? itb->second : ita->second; + int pivot_factor_sign = + r == 0 ? mv_b_sgn : mv_a_sgn; + types[r] = r == 0 ? type_a : type_b; + if (pivot_factor_sign == (r == 0 ? 1 : -1)) { + types[r] = reverseRelationKind(types[r]); + } + if (pivot_factor_sign == 1) { + exp.push_back(NodeManager::currentNM()->mkNode( + kind::GT, pivot_factor, d_zero)); + } else { + exp.push_back(NodeManager::currentNM()->mkNode( + kind::LT, pivot_factor, d_zero)); + } + } + Kind jk = transKinds(types[0], types[1]); + Trace("nl-ext-rbound-debug") + << "trans kind : " << types[0] << " + " + << types[1] << " = " << jk << std::endl; + if (jk != kind::UNDEFINED_KIND) { + Node conc = NodeManager::currentNM()->mkNode( + jk, rhs_a_res, rhs_b_res); + Node conc_mv = computeModelValue(conc, 1); + if (conc_mv == d_false) { + Node rblem = NodeManager::currentNM()->mkNode( + kind::IMPLIES, + NodeManager::currentNM()->mkNode(kind::AND, + exp), + conc); + Trace("nl-ext-rbound-lemma-debug") + << "Resolution bound lemma " + "(pre-rewrite) " + ": " + << rblem << std::endl; + rblem = Rewriter::rewrite(rblem); + Trace("nl-ext-rbound-lemma") + << "Resolution bound lemma : " << rblem + << std::endl; + lemmas.push_back(rblem); + } + } + exp.pop_back(); + exp.pop_back(); + exp.pop_back(); + } + } + } + exp.pop_back(); + } + } + } + } + } + } + } + } + return lemmas; +} + +std::vector<Node> NonlinearExtension::checkTranscendentalInitialRefine() { + std::vector< Node > lemmas; + Trace("nl-ext") << "Get initial refinement lemmas for transcendental functions..." << std::endl; + for( std::map< Kind, std::map< Node, Node > >::iterator it = d_tf_rep_map.begin(); it != d_tf_rep_map.end(); ++it ){ + std::map< Node, Node > mv_to_term; + for( std::map< Node, Node >::iterator itt = it->second.begin(); itt != it->second.end(); ++itt ){ + Node t = itt->second; + Assert( d_mv[1].find( t )!=d_mv[1].end() ); + Node tv = d_mv[1][t]; + mv_to_term[tv] = t; + // easy model-based bounds (TODO: make these unconditional?) + if( it->first==kind::SINE ){ + Assert( tv.isConst() ); + /* + if( tv.getConst<Rational>() > d_one.getConst<Rational>() ){ + lemmas.push_back( NodeManager::currentNM()->mkNode( kind::LEQ, t, d_one ) ); + }else if( tv.getConst<Rational>() < d_neg_one.getConst<Rational>() ){ + lemmas.push_back( NodeManager::currentNM()->mkNode( kind::GEQ, t, d_neg_one ) ); + } + */ + /* + if( tv.getConst<Rational>().sgn()!=0 ){ + //symmetry (model-based) + Node neg_tv = NodeManager::currentNM()->mkConst( -tv.getConst<Rational>() ); + if( mv_to_term.find( neg_tv )!=mv_to_term.end() ){ + Node sum = NodeManager::currentNM()->mkNode( kind::PLUS, mv_to_term[neg_tv][0], t[0] ); + Node res = computeModelValue( sum, 0 ); + if( !res.isConst() || res.getConst<Rational>().sgn()!=0 ){ + Node tsum = NodeManager::currentNM()->mkNode( kind::PLUS, mv_to_term[neg_tv], t ); + Node sym_lem = NodeManager::currentNM()->mkNode( kind::IMPLIES, tsum.eqNode( d_zero ), sum.eqNode( d_zero ) ); + lemmas.push_back( sym_lem ); + } + } + } + */ + }else if( it->first==kind::EXPONENTIAL ){ + if( tv.getConst<Rational>().sgn()==-1 ){ + lemmas.push_back( NodeManager::currentNM()->mkNode( kind::GT, t, d_zero ) ); + } + } + //initial refinements + if( d_tf_initial_refine.find( t )==d_tf_initial_refine.end() ){ + d_tf_initial_refine[t] = true; + Node lem; + if( it->first==kind::SINE ){ + Node symn = NodeManager::currentNM()->mkNode( kind::SINE, + NodeManager::currentNM()->mkNode( kind::MULT, d_neg_one, t[0] ) ); + symn = Rewriter::rewrite( symn ); + //can assume its basis since phase is split over 0 + d_trig_is_base[symn] = true; + Assert( d_trig_is_base.find( t ) != d_trig_is_base.end() ); + std::vector< Node > children; + + lem = NodeManager::currentNM()->mkNode( kind::AND, + //bounds + NodeManager::currentNM()->mkNode( kind::AND, + NodeManager::currentNM()->mkNode( kind::LEQ, t, d_one ), + NodeManager::currentNM()->mkNode( kind::GEQ, t, d_neg_one ) ), + //symmetry + NodeManager::currentNM()->mkNode( kind::PLUS, t, symn ).eqNode( d_zero ), + //sign + NodeManager::currentNM()->mkNode( kind::EQUAL, + NodeManager::currentNM()->mkNode( kind::LT, t[0], d_zero ), + NodeManager::currentNM()->mkNode( kind::LT, t, d_zero ) ), + //zero val + NodeManager::currentNM()->mkNode( kind::EQUAL, + NodeManager::currentNM()->mkNode( kind::GT, t[0], d_zero ), + NodeManager::currentNM()->mkNode( kind::GT, t, d_zero ) ) ); + lem = NodeManager::currentNM()->mkNode( kind::AND, lem, + //zero tangent + NodeManager::currentNM()->mkNode( kind::AND, + NodeManager::currentNM()->mkNode( kind::IMPLIES, + NodeManager::currentNM()->mkNode( kind::GT, t[0], d_zero ), + NodeManager::currentNM()->mkNode( kind::LT, t, t[0] ) ), + NodeManager::currentNM()->mkNode( kind::IMPLIES, + NodeManager::currentNM()->mkNode( kind::LT, t[0], d_zero ), + NodeManager::currentNM()->mkNode( kind::GT, t, t[0] ) ) ), + //pi tangent + NodeManager::currentNM()->mkNode( kind::AND, + NodeManager::currentNM()->mkNode( kind::IMPLIES, + NodeManager::currentNM()->mkNode( kind::LT, t[0], d_pi ), + NodeManager::currentNM()->mkNode( kind::LT, t, NodeManager::currentNM()->mkNode( kind::MINUS, d_pi, t[0] ) ) ), + NodeManager::currentNM()->mkNode( kind::IMPLIES, + NodeManager::currentNM()->mkNode( kind::GT, t[0], d_pi_neg ), + NodeManager::currentNM()->mkNode( kind::GT, t, NodeManager::currentNM()->mkNode( kind::MINUS, d_pi_neg, t[0] ) ) ) ) ); + }else if( it->first==kind::EXPONENTIAL ){ + // exp(x)>0 ^ x < 0 <=> exp( x ) < 1 ^ ( x = 0 V exp( x ) > x + 1 ) + lem = NodeManager::currentNM()->mkNode( kind::AND, NodeManager::currentNM()->mkNode( kind::EQUAL, t[0].eqNode(d_zero), t.eqNode(d_one)), + NodeManager::currentNM()->mkNode( kind::EQUAL, + NodeManager::currentNM()->mkNode( kind::LT, t[0], d_zero ), + NodeManager::currentNM()->mkNode( kind::LT, t, d_one ) ), + NodeManager::currentNM()->mkNode( kind::OR, + NodeManager::currentNM()->mkNode( kind::LEQ, t[0], d_zero ), + NodeManager::currentNM()->mkNode( kind::GT, t, NodeManager::currentNM()->mkNode( kind::PLUS, t[0], d_one ) ) ) ); + + } + if( !lem.isNull() ){ + lemmas.push_back( lem ); + } + } + } + } + + return lemmas; +} + +std::vector<Node> NonlinearExtension::checkTranscendentalMonotonic() { + std::vector< Node > lemmas; + Trace("nl-ext") << "Get monotonicity lemmas for transcendental functions..." << std::endl; + + //sort arguments of all transcendentals + std::map< Kind, std::vector< Node > > sorted_tf_args; + std::map< Kind, std::map< Node, Node > > tf_arg_to_term; + + for( std::map< Kind, std::map< Node, Node > >::iterator it = d_tf_rep_map.begin(); it != d_tf_rep_map.end(); ++it ){ + for( std::map< Node, Node >::iterator itt = it->second.begin(); itt != it->second.end(); ++itt ){ + computeModelValue( itt->second[0], 1 ); + Assert( d_mv[1].find( itt->second[0] )!=d_mv[1].end() ); + if( d_mv[1][itt->second[0]].isConst() ){ + Trace("nl-ext-tf-mono-debug") << "...tf term : " << itt->second[0] << std::endl; + sorted_tf_args[ it->first ].push_back( itt->second[0] ); + tf_arg_to_term[ it->first ][ itt->second[0] ] = itt->second; + } + } + } + + SortNonlinearExtension smv; + smv.d_nla = this; + //sort by concrete values + smv.d_order_type = 0; + smv.d_reverse_order = true; + for( std::map< Kind, std::map< Node, Node > >::iterator it = d_tf_rep_map.begin(); it != d_tf_rep_map.end(); ++it ){ + Kind k = it->first; + if( !sorted_tf_args[k].empty() ){ + std::sort( sorted_tf_args[k].begin(), sorted_tf_args[k].end(), smv ); + Trace("nl-ext-tf-mono") << "Sorted transcendental function list for " << k << " : " << std::endl; + for( unsigned i=0; i<sorted_tf_args[it->first].size(); i++ ){ + Node targ = sorted_tf_args[k][i]; + Assert( d_mv[1].find( targ )!=d_mv[1].end() ); + Trace("nl-ext-tf-mono") << " " << targ << " -> " << d_mv[1][targ] << std::endl; + Node t = tf_arg_to_term[k][targ]; + Assert( d_mv[1].find( t )!=d_mv[1].end() ); + Trace("nl-ext-tf-mono") << " f-val : " << d_mv[1][t] << std::endl; + } + std::vector< int > mdirs; + std::vector< Node > mpoints; + std::vector< Node > mpoints_vals; + if( it->first==kind::SINE ){ + mdirs.push_back( -1 ); + mpoints.push_back( d_pi ); + mdirs.push_back( 1 ); + mpoints.push_back( d_pi_2 ); + mdirs.push_back( -1 ); + mpoints.push_back( d_pi_neg_2 ); + mdirs.push_back( 0 ); + mpoints.push_back( d_pi_neg ); + }else if( it->first==kind::EXPONENTIAL ){ + mdirs.push_back( 1 ); + mpoints.push_back( Node::null() ); + } + if( !mpoints.empty() ){ + //get model values for points + for( unsigned i=0; i<mpoints.size(); i++ ){ + Node mpv; + if( !mpoints[i].isNull() ){ + mpv = computeModelValue( mpoints[i], 1 ); + Assert( mpv.isConst() ); + } + mpoints_vals.push_back( mpv ); + } + + unsigned mdir_index = 0; + int monotonic_dir = -1; + Node mono_bounds[2]; + Node targ, targval, t, tval; + for( unsigned i=0; i<sorted_tf_args[it->first].size(); i++ ){ + Node sarg = sorted_tf_args[k][i]; + Assert( d_mv[1].find( sarg )!=d_mv[1].end() ); + Node sargval = d_mv[1][sarg]; + Assert( sargval.isConst() ); + Node s = tf_arg_to_term[k][ sarg ]; + Assert( d_mv[1].find( s )!=d_mv[1].end() ); + Node sval = d_mv[1][s]; + Assert( sval.isConst() ); + + //increment to the proper monotonicity region + bool increment = true; + while( increment && mdir_index<mdirs.size() ){ + increment = false; + if( mpoints[mdir_index].isNull() ){ + increment = true; + }else{ + Node pval = mpoints_vals[mdir_index]; + Assert( pval.isConst() ); + if( sargval.getConst<Rational>() < pval.getConst<Rational>() ){ + increment = true; + Trace("nl-ext-tf-mono") << "...increment at " << sarg << " since model value is less than " << mpoints[mdir_index] << std::endl; + } + } + if( increment ){ + tval = Node::null(); + monotonic_dir = mdirs[mdir_index]; + mono_bounds[1] = mpoints[mdir_index]; + mdir_index++; + if( mdir_index<mdirs.size() ){ + mono_bounds[0] = mpoints[mdir_index]; + }else{ + mono_bounds[0] = Node::null(); + } + } + } + + + if( !tval.isNull() ){ + Node mono_lem; + if( monotonic_dir==1 && sval.getConst<Rational>() > tval.getConst<Rational>() ){ + mono_lem = NodeManager::currentNM()->mkNode( kind::IMPLIES, + NodeManager::currentNM()->mkNode( kind::GEQ, targ, sarg ), + NodeManager::currentNM()->mkNode( kind::GEQ, t, s ) ); + }else if( monotonic_dir==-1 && sval.getConst<Rational>() < tval.getConst<Rational>() ){ + mono_lem = NodeManager::currentNM()->mkNode( kind::IMPLIES, + NodeManager::currentNM()->mkNode( kind::LEQ, targ, sarg ), + NodeManager::currentNM()->mkNode( kind::LEQ, t, s ) ); + } + if( !mono_lem.isNull() ){ + if( !mono_bounds[0].isNull() ){ + Assert( !mono_bounds[1].isNull() ); + mono_lem = NodeManager::currentNM()->mkNode( kind::IMPLIES, + NodeManager::currentNM()->mkNode( kind::AND, + mkBounded( mono_bounds[0], targ, mono_bounds[1] ), + mkBounded( mono_bounds[0], sarg, mono_bounds[1] ) ), + mono_lem ); + } + Trace("nl-ext-tf-mono") << "Monotonicity lemma : " << mono_lem << std::endl; + lemmas.push_back( mono_lem ); + } + } + targ = sarg; + targval = sargval; + t = s; + tval = sval; + } + } + } + } + + + + + return lemmas; +} + + +Node NonlinearExtension::getTaylor( Node tf, Node x, unsigned n, std::vector< Node >& lemmas ) { + Node i_exp_base_term = Rewriter::rewrite( NodeManager::currentNM()->mkNode( kind::MINUS, x, tf[0] ) ); + Node i_exp_base = getFactorSkolem( i_exp_base_term, lemmas ); + Node i_derv = tf; + Node i_fact = d_one; + Node i_exp = d_one; + int i_derv_status = 0; + unsigned counter = 0; + std::vector< Node > sum; + do { + counter++; + if( tf.getKind()==kind::EXPONENTIAL ){ + //unchanged + }else if( tf.getKind()==kind::SINE ){ + if( i_derv_status%2==1 ){ + Node arg = NodeManager::currentNM()->mkNode( kind::MINUS, + NodeManager::currentNM()->mkNode( kind::MULT, + NodeManager::currentNM()->mkConst( Rational(1)/Rational(2) ), + NodeManager::currentNM()->mkNullaryOperator( NodeManager::currentNM()->realType(), kind::PI ) ), + tf[0] ); + i_derv = NodeManager::currentNM()->mkNode( kind::SINE, arg ); + }else{ + i_derv = tf; + } + if( i_derv_status>=2 ){ + i_derv = NodeManager::currentNM()->mkNode( kind::MINUS, d_zero, i_derv ); + } + i_derv = Rewriter::rewrite( i_derv ); + i_derv_status = i_derv_status==3 ? 0 : i_derv_status+1; + } + Node curr = NodeManager::currentNM()->mkNode( kind::MULT, + NodeManager::currentNM()->mkNode( kind::DIVISION, i_derv, i_fact ), i_exp ); + sum.push_back( curr ); + i_fact = Rewriter::rewrite( NodeManager::currentNM()->mkNode( kind::MULT, NodeManager::currentNM()->mkConst( Rational( counter ) ) ) ); + i_exp = Rewriter::rewrite( NodeManager::currentNM()->mkNode( kind::MULT, i_exp_base, i_exp ) ); + }while( counter<n ); + return sum.size()==1 ? sum[0] : NodeManager::currentNM()->mkNode( kind::PLUS, sum ); +} + } // namespace arith } // namespace theory } // namespace CVC4 diff --git a/src/theory/arith/nonlinear_extension.h b/src/theory/arith/nonlinear_extension.h index 7c7bfbce9..1a19eb67a 100644 --- a/src/theory/arith/nonlinear_extension.h +++ b/src/theory/arith/nonlinear_extension.h @@ -2,7 +2,7 @@ /*! \file nonlinear_extension.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds + ** Tim King ** 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. @@ -86,17 +86,17 @@ class NonlinearExtension { // Check assertions for consistency in the effort LAST_CALL with a subset of // the assertions, false_asserts, evaluate to false in the current model. void checkLastCall(const std::vector<Node>& assertions, - const std::set<Node>& false_asserts); - - // Returns a vector containing a split on whether each term is 0 or not for - // those terms that have not been split on in the current context. - std::vector<Node> splitOnZeros(const std::vector<Node>& terms); + const std::set<Node>& false_asserts, + const std::vector<Node>& xts); static bool isArithKind(Kind k); static Node mkLit(Node a, Node b, int status, int orderType = 0); static Node mkAbs(Node a); + static Node mkValidPhase(Node a, Node pi); + static Node mkBounded( Node l, Node a, Node u ); static Kind joinKinds(Kind k1, Kind k2); static Kind transKinds(Kind k1, Kind k2); + static bool isTranscendentalKind(Kind k); Node mkMonomialRemFactor(Node n, const NodeMultiset& n_exp_rem) const; // register monomial @@ -171,6 +171,9 @@ class NonlinearExtension { // cache of all lemmas sent NodeSet d_lemmas; NodeSet d_zero_split; + + // literals with Skolems (need not be satisfied by model) + NodeSet d_skolem_atoms; // utilities Node d_zero; @@ -197,8 +200,71 @@ class NonlinearExtension { std::map<Node, Node> d_mv[2]; // ordering, stores variables and 0,1,-1 - std::map<unsigned, NodeMultiset> d_order_vars; + std::map<Node, unsigned> d_order_vars; std::vector<Node> d_order_points; + + //transcendent functions + std::map<Node, Node> d_trig_base; + std::map<Node, bool> d_trig_is_base; + std::map< Node, bool > d_tf_initial_refine; + Node d_pi; + Node d_pi_2; + Node d_pi_neg_2; + Node d_pi_neg; + Node d_pi_bound[2]; + + void mkPi(); + void getCurrentPiBounds( std::vector< Node >& lemmas ); +private: + //per last-call effort check + + //information about monomials + std::vector< Node > d_ms; + std::vector< Node > d_ms_vars; + std::map<Node, bool> d_ms_proc; + std::vector<Node> d_mterms; + //list of monomials with factors whose model value is non-constant in model + // e.g. y*cos( x ) + std::map<Node, bool> d_m_nconst_factor; + // If ( m, p1, true ), then it would help satisfiability if m were ( > + // if p1=true, < if p1=false ) + std::map<Node, std::map<bool, bool> > d_tplane_refine_dir; + // term -> coeff -> rhs -> ( status, exp, b ), + // where we have that : exp => ( coeff * term <status> rhs ) + // b is true if degree( term ) >= degree( rhs ) + std::map<Node, std::map<Node, std::map<Node, Kind> > > d_ci; + std::map<Node, std::map<Node, std::map<Node, Node> > > d_ci_exp; + std::map<Node, std::map<Node, std::map<Node, bool> > > d_ci_max; + + //information about transcendental functions + std::map< Kind, std::map< Node, Node > > d_tf_rep_map; + + // factor skolems + std::map< Node, Node > d_factor_skolem; + Node getFactorSkolem( Node n, std::vector< Node >& lemmas ); + + Node getTaylor( Node tf, Node x, unsigned n, std::vector< Node >& lemmas ); +private: + // Returns a vector containing a split on whether each term is 0 or not for + // those terms that have not been split on in the current context. + std::vector<Node> checkSplitZero(); + + std::vector<Node> checkMonomialSign(); + + std::vector<Node> checkMonomialMagnitude( unsigned c ); + + std::vector<Node> checkMonomialInferBounds( std::vector<Node>& nt_lemmas, + const std::set<Node>& false_asserts ); + + std::vector<Node> checkFactoring( const std::set<Node>& false_asserts ); + + std::vector<Node> checkMonomialInferResBounds(); + + std::vector<Node> checkTangentPlanes(); + + std::vector<Node> checkTranscendentalInitialRefine(); + + std::vector<Node> checkTranscendentalMonotonic(); }; /* class NonlinearExtension */ } // namespace arith diff --git a/src/theory/arith/normal_form.cpp b/src/theory/arith/normal_form.cpp index 14607f4e4..30b9ca0b5 100644 --- a/src/theory/arith/normal_form.cpp +++ b/src/theory/arith/normal_form.cpp @@ -2,9 +2,9 @@ /*! \file normal_form.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Dejan Jovanovic + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -89,14 +89,23 @@ bool Variable::isDivMember(Node n){ } } +bool Variable::isTranscendentalMember(Node n) { + switch(n.getKind()){ + case kind::EXPONENTIAL: + case kind::SINE: + case kind::COSINE: + case kind::TANGENT: + return Polynomial::isMember(n[0]); + case kind::PI: + return true; + default: + return false; + } +} bool VarList::isSorted(iterator start, iterator end) { -#if IS_SORTED_IN_GNUCXX_NAMESPACE - return __gnu_cxx::is_sorted(start, end); -#else /* IS_SORTED_IN_GNUCXX_NAMESPACE */ return std::is_sorted(start, end); -#endif /* IS_SORTED_IN_GNUCXX_NAMESPACE */ } bool VarList::isMember(Node n) { @@ -185,8 +194,7 @@ VarList VarList::operator*(const VarList& other) const { otherEnd = other.internalEnd(); Variable::VariableNodeCmp cmp; - - merge_ranges(thisBegin, thisEnd, otherBegin, otherEnd, result, cmp); + std::merge(thisBegin, thisEnd, otherBegin, otherEnd, std::back_inserter(result), cmp); Assert(result.size() >= 2); Node mult = NodeManager::currentNM()->mkNode(kind::NONLINEAR_MULT, result); @@ -343,7 +351,7 @@ void Monomial::printList(const std::vector<Monomial>& list) { Polynomial Polynomial::operator+(const Polynomial& vl) const { std::vector<Monomial> sortedMonos; - merge_ranges(begin(), end(), vl.begin(), vl.end(), sortedMonos); + std::merge(begin(), end(), vl.begin(), vl.end(), std::back_inserter(sortedMonos)); Monomial::combineAdjacentMonomials(sortedMonos); //std::vector<Monomial> combined = Monomial::sumLikeTerms(sortedMonos); diff --git a/src/theory/arith/normal_form.h b/src/theory/arith/normal_form.h index d0c9df1a6..21301da91 100644 --- a/src/theory/arith/normal_form.h +++ b/src/theory/arith/normal_form.h @@ -2,9 +2,9 @@ /*! \file normal_form.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Dejan Jovanovic + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -23,10 +23,6 @@ #include <algorithm> #include <list> -#if IS_SORTED_IN_GNUCXX_NAMESPACE -# include <ext/algorithm> -#endif /* IS_SORTED_IN_GNUCXX_NAMESPACE */ - #include "base/output.h" #include "expr/node.h" #include "expr/node_self_iterator.h" @@ -245,6 +241,12 @@ public: case kind::INTS_MODULUS_TOTAL: case kind::DIVISION_TOTAL: return isDivMember(n); + case kind::EXPONENTIAL: + case kind::SINE: + case kind::COSINE: + case kind::TANGENT: + case kind::PI: + return isTranscendentalMember(n); case kind::ABS: case kind::TO_INTEGER: // Treat to_int as a variable; it is replaced in early preprocessing @@ -260,6 +262,7 @@ public: bool isDivLike() const{ return isDivMember(getNode()); } + static bool isTranscendentalMember(Node n); bool isNormalForm() { return isMember(getNode()); } @@ -277,7 +280,7 @@ public: } struct VariableNodeCmp { - static inline int cmp(Node n, Node m) { + static inline int cmp(const Node& n, const Node& m) { if ( n == m ) { return 0; } // this is now slightly off of the old variable order. @@ -313,7 +316,7 @@ public: } } - bool operator()(Node n, Node m) const { + bool operator()(const Node& n, const Node& m) const { return VariableNodeCmp::cmp(n,m) < 0; } }; @@ -424,56 +427,6 @@ inline Node makeNode(Kind k, GetNodeIterator start, GetNodeIterator end) { return Node(nb); }/* makeNode<GetNodeIterator>(Kind, iterator, iterator) */ - -template <class GetNodeIterator, class T> -static void copy_range(GetNodeIterator begin, GetNodeIterator end, std::vector<T>& result){ - while(begin != end){ - result.push_back(*begin); - ++begin; - } -} - -template <class GetNodeIterator, class T> -static void merge_ranges(GetNodeIterator first1, - GetNodeIterator last1, - GetNodeIterator first2, - GetNodeIterator last2, - std::vector<T>& result) { - - while(first1 != last1 && first2 != last2){ - if( (*first1) < (*first2) ){ - result.push_back(*first1); - ++ first1; - }else{ - result.push_back(*first2); - ++ first2; - } - } - copy_range(first1, last1, result); - copy_range(first2, last2, result); -} - -template <class GetNodeIterator, class T, class Cmp> -static void merge_ranges(GetNodeIterator first1, - GetNodeIterator last1, - GetNodeIterator first2, - GetNodeIterator last2, - std::vector<T>& result, - const Cmp& cmp) { - - while(first1 != last1 && first2 != last2){ - if( cmp(*first1, *first2) ){ - result.push_back(*first1); - ++ first1; - }else{ - result.push_back(*first2); - ++ first2; - } - } - copy_range(first1, last1, result); - copy_range(first2, last2, result); -} - /** * A VarList is a sorted list of variables representing a product. * If the VarList is empty, it represents an empty product or 1. @@ -742,11 +695,7 @@ public: } static bool isSorted(const std::vector<Monomial>& m) { -#if IS_SORTED_IN_GNUCXX_NAMESPACE - return __gnu_cxx::is_sorted(m.begin(), m.end()); -#else /* IS_SORTED_IN_GNUCXX_NAMESPACE */ return std::is_sorted(m.begin(), m.end()); -#endif /* IS_SORTED_IN_GNUCXX_NAMESPACE */ } static bool isStrictlySorted(const std::vector<Monomial>& m) { @@ -845,7 +794,7 @@ private: public: static bool isMember(TNode n); - class iterator { + class iterator : public std::iterator<std::input_iterator_tag, Monomial> { private: internal_iterator d_iter; @@ -947,7 +896,7 @@ public: iterator tailStart = begin(); ++tailStart; std::vector<Monomial> subrange; - copy_range(tailStart, end(), subrange); + std::copy(tailStart, end(), std::back_inserter(subrange)); return mkPolynomial(subrange); } diff --git a/src/theory/arith/partial_model.cpp b/src/theory/arith/partial_model.cpp index 632be2a81..2c50a1b1d 100644 --- a/src/theory/arith/partial_model.cpp +++ b/src/theory/arith/partial_model.cpp @@ -2,9 +2,9 @@ /*! \file partial_model.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/partial_model.h b/src/theory/arith/partial_model.h index b5eafb2c4..50fb2cb48 100644 --- a/src/theory/arith/partial_model.h +++ b/src/theory/arith/partial_model.h @@ -2,9 +2,9 @@ /*! \file partial_model.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/pseudoboolean_proc.cpp b/src/theory/arith/pseudoboolean_proc.cpp index 0c1496a89..230cfb7ca 100644 --- a/src/theory/arith/pseudoboolean_proc.cpp +++ b/src/theory/arith/pseudoboolean_proc.cpp @@ -2,9 +2,9 @@ /*! \file pseudoboolean_proc.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/pseudoboolean_proc.h b/src/theory/arith/pseudoboolean_proc.h index 23065ca48..0b91ed074 100644 --- a/src/theory/arith/pseudoboolean_proc.h +++ b/src/theory/arith/pseudoboolean_proc.h @@ -2,9 +2,9 @@ /*! \file pseudoboolean_proc.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,7 +19,7 @@ #pragma once -#include <ext/hash_set> +#include <unordered_set> #include <vector> #include "context/cdhashmap.h" @@ -43,7 +43,7 @@ private: CDNode2PairMap d_pbBounds; SubstitutionMap d_subCache; - typedef __gnu_cxx::hash_set<Node, NodeHashFunction> NodeSet; + typedef std::unordered_set<Node, NodeHashFunction> NodeSet; NodeSet d_learningCache; context::CDO<unsigned> d_pbs; diff --git a/src/theory/arith/simplex.cpp b/src/theory/arith/simplex.cpp index 9dd13711c..a7c5a1ac1 100644 --- a/src/theory/arith/simplex.cpp +++ b/src/theory/arith/simplex.cpp @@ -2,9 +2,9 @@ /*! \file simplex.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/simplex.h b/src/theory/arith/simplex.h index b4cd54a78..bd983e0bf 100644 --- a/src/theory/arith/simplex.h +++ b/src/theory/arith/simplex.h @@ -2,9 +2,9 @@ /*! \file simplex.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Clark Barrett + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -53,6 +53,8 @@ #pragma once +#include <unordered_map> + #include "theory/arith/arithvar.h" #include "theory/arith/delta_rational.h" #include "theory/arith/error_set.h" @@ -199,7 +201,7 @@ protected: } }; - typedef std::hash_map< std::pair<ArithVar, int>, ArithVarVec, ArithVarIntPairHashFunc> sgn_table; + typedef std::unordered_map< std::pair<ArithVar, int>, ArithVarVec, ArithVarIntPairHashFunc> sgn_table; static inline int determinizeSgn(int sgn){ return sgn < 0 ? -1 : (sgn == 0 ? 0 : 1); diff --git a/src/theory/arith/simplex_update.cpp b/src/theory/arith/simplex_update.cpp index adf0dc039..e5bcfa612 100644 --- a/src/theory/arith/simplex_update.cpp +++ b/src/theory/arith/simplex_update.cpp @@ -2,9 +2,9 @@ /*! \file simplex_update.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/simplex_update.h b/src/theory/arith/simplex_update.h index 2c02e3f77..7b487c8a3 100644 --- a/src/theory/arith/simplex_update.h +++ b/src/theory/arith/simplex_update.h @@ -2,9 +2,9 @@ /*! \file simplex_update.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/soi_simplex.cpp b/src/theory/arith/soi_simplex.cpp index 0a437cde0..b2f7b08b5 100644 --- a/src/theory/arith/soi_simplex.cpp +++ b/src/theory/arith/soi_simplex.cpp @@ -2,9 +2,9 @@ /*! \file soi_simplex.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/soi_simplex.h b/src/theory/arith/soi_simplex.h index c2afe062a..5f2233b3f 100644 --- a/src/theory/arith/soi_simplex.h +++ b/src/theory/arith/soi_simplex.h @@ -2,9 +2,9 @@ /*! \file soi_simplex.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/tableau.cpp b/src/theory/arith/tableau.cpp index 0bd130985..080104118 100644 --- a/src/theory/arith/tableau.cpp +++ b/src/theory/arith/tableau.cpp @@ -2,9 +2,9 @@ /*! \file tableau.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/tableau.h b/src/theory/arith/tableau.h index c4c8cfba3..caf360153 100644 --- a/src/theory/arith/tableau.h +++ b/src/theory/arith/tableau.h @@ -2,9 +2,9 @@ /*! \file tableau.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/tableau_sizes.cpp b/src/theory/arith/tableau_sizes.cpp index 08f7a69d8..6d7b2e7da 100644 --- a/src/theory/arith/tableau_sizes.cpp +++ b/src/theory/arith/tableau_sizes.cpp @@ -2,9 +2,9 @@ /*! \file tableau_sizes.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/tableau_sizes.h b/src/theory/arith/tableau_sizes.h index 635330798..da6f0f828 100644 --- a/src/theory/arith/tableau_sizes.h +++ b/src/theory/arith/tableau_sizes.h @@ -2,9 +2,9 @@ /*! \file tableau_sizes.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/theory_arith.cpp b/src/theory/arith/theory_arith.cpp index f390503a3..985799e88 100644 --- a/src/theory/arith/theory_arith.cpp +++ b/src/theory/arith/theory_arith.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -40,6 +40,11 @@ TheoryArith::TheoryArith(context::Context* c, context::UserContext* u, if (options::nlExt()) { setupExtTheory(); getExtTheory()->addFunctionKind(kind::NONLINEAR_MULT); + getExtTheory()->addFunctionKind(kind::EXPONENTIAL); + getExtTheory()->addFunctionKind(kind::SINE); + getExtTheory()->addFunctionKind(kind::COSINE); + getExtTheory()->addFunctionKind(kind::TANGENT); + getExtTheory()->addFunctionKind(kind::PI); } } diff --git a/src/theory/arith/theory_arith.h b/src/theory/arith/theory_arith.h index 5dcea4be0..e1226279a 100644 --- a/src/theory/arith/theory_arith.h +++ b/src/theory/arith/theory_arith.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/theory_arith_private.cpp b/src/theory/arith/theory_arith_private.cpp index 250317b78..ab5a19858 100644 --- a/src/theory/arith/theory_arith_private.cpp +++ b/src/theory/arith/theory_arith_private.cpp @@ -2,9 +2,9 @@ /*! \file theory_arith_private.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Martin Brain + ** Tim King, Andrew Reynolds, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -1454,7 +1454,6 @@ void TheoryArithPrivate::setupVariableList(const VarList& vl){ } if( !options::nlExt() ){ - setIncomplete(); d_nlIncomplete = true; } @@ -1464,6 +1463,13 @@ void TheoryArithPrivate::setupVariableList(const VarList& vl){ //setupInitialValue(av); markSetup(vlNode); + }else{ + if( !options::nlExt() ){ + if( vlNode.getKind()==kind::EXPONENTIAL || vlNode.getKind()==kind::SINE || + vlNode.getKind()==kind::COSINE || vlNode.getKind()==kind::TANGENT ){ + d_nlIncomplete = true; + } + } } /* Note: @@ -3823,7 +3829,6 @@ void TheoryArithPrivate::check(Theory::Effort effortLevel){ } if(Theory::fullEffort(effortLevel) && d_nlIncomplete){ - // TODO this is total paranoia setIncomplete(); } @@ -4263,7 +4268,7 @@ void TheoryArithPrivate::collectModelInfo( TheoryModel* m ){ // Delta lasts at least the duration of the function call const Rational& delta = d_partialModel.getDelta(); - std::hash_set<TNode, TNodeHashFunction> shared = d_containing.currentlySharedTerms(); + std::unordered_set<TNode, TNodeHashFunction> shared = d_containing.currentlySharedTerms(); // TODO: // This is not very good for user push/pop.... @@ -4865,6 +4870,12 @@ const BoundsInfo& TheoryArithPrivate::boundsInfo(ArithVar basic) const{ Node TheoryArithPrivate::expandDefinition(LogicRequest &logicRequest, Node node) { NodeManager* nm = NodeManager::currentNM(); + // eliminate here since involves division + if( node.getKind()==kind::TANGENT ){ + node = nm->mkNode(kind::DIVISION, nm->mkNode( kind::SINE, node[0] ), + nm->mkNode( kind::COSINE, node[0] ) ); + } + switch(node.getKind()) { case kind::DIVISION: { // partial function: division diff --git a/src/theory/arith/theory_arith_private.h b/src/theory/arith/theory_arith_private.h index a56028f32..b2471c5e8 100644 --- a/src/theory/arith/theory_arith_private.h +++ b/src/theory/arith/theory_arith_private.h @@ -2,9 +2,9 @@ /*! \file theory_arith_private.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Martin Brain, Morgan Deters + ** Tim King, Martin Brain, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/theory_arith_private_forward.h b/src/theory/arith/theory_arith_private_forward.h index ffab816f1..f52a80e68 100644 --- a/src/theory/arith/theory_arith_private_forward.h +++ b/src/theory/arith/theory_arith_private_forward.h @@ -2,9 +2,9 @@ /*! \file theory_arith_private_forward.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arith/theory_arith_type_rules.h b/src/theory/arith/theory_arith_type_rules.h index 071ec9391..db3ae65f2 100644 --- a/src/theory/arith/theory_arith_type_rules.h +++ b/src/theory/arith/theory_arith_type_rules.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -93,6 +93,24 @@ public: } };/* class IntOperatorTypeRule */ +class RealOperatorTypeRule { +public: + inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) + throw (TypeCheckingExceptionPrivate, AssertionException) { + TNode::iterator child_it = n.begin(); + TNode::iterator child_it_end = n.end(); + if(check) { + for(; child_it != child_it_end; ++child_it) { + TypeNode childType = (*child_it).getType(check); + if (!childType.isReal()) { + throw TypeCheckingExceptionPrivate(n, "expecting a real subterm"); + } + } + } + return nodeManager->realType(); + } +};/* class RealOperatorTypeRule */ + class ArithPredicateTypeRule { public: inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) @@ -139,31 +157,19 @@ public: } };/* class IntUnaryPredicateTypeRule */ -class SubrangeProperties { +class RealNullaryOperatorTypeRule { public: - inline static Cardinality computeCardinality(TypeNode type) { - Assert(type.getKind() == kind::SUBRANGE_TYPE); - - const SubrangeBounds& bounds = type.getConst<SubrangeBounds>(); - if(!bounds.lower.hasBound() || !bounds.upper.hasBound()) { - return Cardinality::INTEGERS; - } - return Cardinality(bounds.upper.getBound() - bounds.lower.getBound()); - } - - inline static Node mkGroundTerm(TypeNode type) { - Assert(type.getKind() == kind::SUBRANGE_TYPE); - - const SubrangeBounds& bounds = type.getConst<SubrangeBounds>(); - if(bounds.lower.hasBound()) { - return NodeManager::currentNM()->mkConst(Rational(bounds.lower.getBound())); - } - if(bounds.upper.hasBound()) { - return NodeManager::currentNM()->mkConst(Rational(bounds.upper.getBound())); + inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) + throw (TypeCheckingExceptionPrivate, AssertionException) { + // for nullary operators, we only computeType for check=true, since they are given TypeAttr() on creation + Assert(check); + TypeNode realType = n.getType(); + if(realType!=NodeManager::currentNM()->realType()) { + throw TypeCheckingExceptionPrivate(n, "expecting real type"); } - return NodeManager::currentNM()->mkConst(Rational(0)); + return realType; } -};/* class SubrangeProperties */ +};/* class RealNullaryOperatorTypeRule */ }/* CVC4::theory::arith namespace */ }/* CVC4::theory namespace */ diff --git a/src/theory/arith/type_enumerator.h b/src/theory/arith/type_enumerator.h index 36b7b543a..4cb34ed4a 100644 --- a/src/theory/arith/type_enumerator.h +++ b/src/theory/arith/type_enumerator.h @@ -2,9 +2,9 @@ /*! \file type_enumerator.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -108,55 +108,6 @@ public: };/* class IntegerEnumerator */ -class SubrangeEnumerator : public TypeEnumeratorBase<SubrangeEnumerator> { - Integer d_int; - SubrangeBounds d_bounds; - bool d_direction;// true == +, false == - - -public: - - SubrangeEnumerator(TypeNode type, TypeEnumeratorProperties * tep = NULL) throw(AssertionException) : - TypeEnumeratorBase<SubrangeEnumerator>(type), - d_int(0), - d_bounds(type.getConst<SubrangeBounds>()), - d_direction(d_bounds.lower.hasBound()) { - - d_int = d_direction ? d_bounds.lower.getBound() : d_bounds.upper.getBound(); - - Assert(type.getKind() == kind::SUBRANGE_TYPE); - - // if we're counting down, there's no lower bound - Assert(d_direction || !d_bounds.lower.hasBound()); - } - - Node operator*() throw(NoMoreValuesException) { - if(isFinished()) { - throw NoMoreValuesException(getType()); - } - return NodeManager::currentNM()->mkConst(Rational(d_int)); - } - - SubrangeEnumerator& operator++() throw() { - if(d_direction) { - if(!d_bounds.upper.hasBound() || d_int <= d_bounds.upper.getBound()) { - d_int += 1; - } - } else { - // if we're counting down, there's no lower bound - d_int -= 1; - } - return *this; - } - - bool isFinished() throw() { - // if we're counting down, there's no lower bound - return d_direction && - d_bounds.upper.hasBound() && - d_int > d_bounds.upper.getBound(); - } - -};/* class SubrangeEnumerator */ - }/* CVC4::theory::arith namespace */ }/* CVC4::theory namespace */ }/* CVC4 namespace */ diff --git a/src/theory/arrays/array_info.cpp b/src/theory/arrays/array_info.cpp index c63d528a7..fc86e00de 100644 --- a/src/theory/arrays/array_info.cpp +++ b/src/theory/arrays/array_info.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Clark Barrett, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arrays/array_info.h b/src/theory/arrays/array_info.h index 11455a97d..5955fb4e4 100644 --- a/src/theory/arrays/array_info.h +++ b/src/theory/arrays/array_info.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Clark Barrett, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -18,10 +18,9 @@ #ifndef __CVC4__THEORY__ARRAYS__ARRAY_INFO_H #define __CVC4__THEORY__ARRAYS__ARRAY_INFO_H -#include <ext/hash_set> -#include <ext/hash_map> #include <iostream> #include <map> +#include <unordered_map> #include "context/backtrackable.h" #include "context/cdlist.h" @@ -92,7 +91,7 @@ public: };/* class Info */ -typedef __gnu_cxx::hash_map<Node, Info*, NodeHashFunction> CNodeInfoMap; +typedef std::unordered_map<Node, Info*, NodeHashFunction> CNodeInfoMap; /** * Class keeping track of the following information for canonical diff --git a/src/theory/arrays/array_proof_reconstruction.cpp b/src/theory/arrays/array_proof_reconstruction.cpp index 5ecccdd53..471084d6f 100644 --- a/src/theory/arrays/array_proof_reconstruction.cpp +++ b/src/theory/arrays/array_proof_reconstruction.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Guy Katz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arrays/array_proof_reconstruction.h b/src/theory/arrays/array_proof_reconstruction.h index ef3e09aed..c5ba21569 100644 --- a/src/theory/arrays/array_proof_reconstruction.h +++ b/src/theory/arrays/array_proof_reconstruction.h @@ -2,9 +2,9 @@ /*! \file array_proof_reconstruction.h ** \verbatim ** Top contributors (to current version): - ** Guy Katz + ** Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arrays/static_fact_manager.cpp b/src/theory/arrays/static_fact_manager.cpp index da1d7bba9..a3f1ae929 100644 --- a/src/theory/arrays/static_fact_manager.cpp +++ b/src/theory/arrays/static_fact_manager.cpp @@ -2,9 +2,9 @@ /*! \file static_fact_manager.cpp ** \verbatim ** Top contributors (to current version): - ** Clark Barrett, Tim King + ** Clark Barrett, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arrays/static_fact_manager.h b/src/theory/arrays/static_fact_manager.h index d40f56e61..4a08838fe 100644 --- a/src/theory/arrays/static_fact_manager.h +++ b/src/theory/arrays/static_fact_manager.h @@ -2,9 +2,9 @@ /*! \file static_fact_manager.h ** \verbatim ** Top contributors (to current version): - ** Clark Barrett, Tim King, Morgan Deters + ** Clark Barrett, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -23,7 +23,7 @@ #include <utility> #include <vector> -#include <ext/hash_map> +#include <unordered_map> #include "expr/node.h" @@ -33,7 +33,7 @@ namespace arrays { class StaticFactManager { /** Our underlying map type. */ - typedef __gnu_cxx::hash_map<Node, Node, NodeHashFunction> MapType; + typedef std::unordered_map<Node, Node, NodeHashFunction> MapType; /** * Our map of Nodes to their canonical representatives. diff --git a/src/theory/arrays/theory_arrays.cpp b/src/theory/arrays/theory_arrays.cpp index e712a51b6..2f5a9a14f 100644 --- a/src/theory/arrays/theory_arrays.cpp +++ b/src/theory/arrays/theory_arrays.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Clark Barrett, Morgan Deters, Guy Katz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -551,7 +551,7 @@ void TheoryArrays::weakEquivMakeRepIndex(TNode node) { } void TheoryArrays::weakEquivAddSecondary(TNode index, TNode arrayFrom, TNode arrayTo, TNode reason) { - std::hash_set<TNode, TNodeHashFunction> marked; + std::unordered_set<TNode, TNodeHashFunction> marked; vector<TNode> index_trail; vector<TNode>::iterator it, iend; Node equivalence_trail = reason; @@ -1198,7 +1198,7 @@ void TheoryArrays::collectModelInfo( TheoryModel* m ) /* } else { - std::hash_map<Node, Node, NodeHashFunction>::iterator it = d_skolemCache.find(n); + std::unordered_map<Node, Node, NodeHashFunction>::iterator it = d_skolemCache.find(n); if (it == d_skolemCache.end()) { rep = nm->mkSkolem("array_collect_model_var", n.getType(), "base model variable for array collectModelInfo"); d_skolemCache[n] = rep; @@ -1240,7 +1240,7 @@ void TheoryArrays::presolve() Node TheoryArrays::getSkolem(TNode ref, const string& name, const TypeNode& type, const string& comment, bool makeEqual) { Node skolem; - std::hash_map<Node, Node, NodeHashFunction>::iterator it = d_skolemCache.find(ref); + std::unordered_map<Node, Node, NodeHashFunction>::iterator it = d_skolemCache.find(ref); if (it == d_skolemCache.end()) { NodeManager* nm = NodeManager::currentNM(); skolem = nm->mkSkolem(name, type, comment); diff --git a/src/theory/arrays/theory_arrays.h b/src/theory/arrays/theory_arrays.h index 48da4c681..3ef9578ef 100644 --- a/src/theory/arrays/theory_arrays.h +++ b/src/theory/arrays/theory_arrays.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Clark Barrett, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,6 +19,8 @@ #ifndef __CVC4__THEORY__ARRAYS__THEORY_ARRAYS_H #define __CVC4__THEORY__ARRAYS__THEORY_ARRAYS_H +#include <unordered_map> + #include "context/cdhashmap.h" #include "context/cdhashset.h" #include "context/cdqueue.h" @@ -384,7 +386,7 @@ class TheoryArrays : public Theory { // When a new read term is created, we check the index to see if we know the model value. If so, we add it to d_constReads (and d_constReadsList) // If not, we push it onto d_reads and figure out where it goes at computeCareGraph time. // d_constReadsList is used as a backup in case we can't compute the model at computeCareGraph time. - typedef std::hash_map<Node, CTNodeList*, NodeHashFunction> CNodeNListMap; + typedef std::unordered_map<Node, CTNodeList*, NodeHashFunction> CNodeNListMap; CNodeNListMap d_constReads; context::CDList<TNode> d_reads; context::CDList<TNode> d_constReadsList; @@ -408,7 +410,7 @@ class TheoryArrays : public Theory { };/* class ContextPopper */ ContextPopper d_contextPopper; - std::hash_map<Node, Node, NodeHashFunction> d_skolemCache; + std::unordered_map<Node, Node, NodeHashFunction> d_skolemCache; context::CDO<unsigned> d_skolemIndex; std::vector<Node> d_skolemAssertions; @@ -425,7 +427,7 @@ class TheoryArrays : public Theory { typedef context::CDHashMap<Node,Node,NodeHashFunction> DefValMap; DefValMap d_defValues; - typedef std::hash_map<std::pair<TNode, TNode>, CTNodeList*, TNodePairHashFunction> ReadBucketMap; + typedef std::unordered_map<std::pair<TNode, TNode>, CTNodeList*, TNodePairHashFunction> ReadBucketMap; ReadBucketMap d_readBucketTable; context::Context* d_readTableContext; context::CDList<Node> d_arrayMerges; diff --git a/src/theory/arrays/theory_arrays_rewriter.cpp b/src/theory/arrays/theory_arrays_rewriter.cpp index f1cf1d320..c9ceae857 100644 --- a/src/theory/arrays/theory_arrays_rewriter.cpp +++ b/src/theory/arrays/theory_arrays_rewriter.cpp @@ -2,9 +2,9 @@ /*! \file theory_arrays_rewriter.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arrays/theory_arrays_rewriter.h b/src/theory/arrays/theory_arrays_rewriter.h index e63c224a0..04d199971 100644 --- a/src/theory/arrays/theory_arrays_rewriter.h +++ b/src/theory/arrays/theory_arrays_rewriter.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Clark Barrett, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,6 +20,9 @@ #ifndef __CVC4__THEORY__ARRAYS__THEORY_ARRAYS_REWRITER_H #define __CVC4__THEORY__ARRAYS__THEORY_ARRAYS_REWRITER_H +#include <unordered_map> +#include <unordered_set> + #include "theory/rewriter.h" #include "theory/type_enumerator.h" @@ -150,9 +153,9 @@ public: // Bad case: have to recompute value counts and/or possibly switch out // default value store = n; - std::hash_set<TNode, TNodeHashFunction> indexSet; - std::hash_map<TNode, unsigned, TNodeHashFunction> elementsMap; - std::hash_map<TNode, unsigned, TNodeHashFunction>::iterator it; + std::unordered_set<TNode, TNodeHashFunction> indexSet; + std::unordered_map<TNode, unsigned, TNodeHashFunction> elementsMap; + std::unordered_map<TNode, unsigned, TNodeHashFunction>::iterator it; unsigned count; unsigned max = 0; TNode maxValue; diff --git a/src/theory/arrays/theory_arrays_type_rules.h b/src/theory/arrays/theory_arrays_type_rules.h index d817fb179..2dbc5affd 100644 --- a/src/theory/arrays/theory_arrays_type_rules.h +++ b/src/theory/arrays/theory_arrays_type_rules.h @@ -2,9 +2,9 @@ /*! \file theory_arrays_type_rules.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Clark Barrett, Guy Katz + ** Morgan Deters, Clark Barrett, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -36,7 +36,7 @@ struct ArraySelectTypeRule { throw TypeCheckingExceptionPrivate(n, "array select operating on non-array"); } TypeNode indexType = n[1].getType(check); - if(!indexType.isComparableTo(arrayType.getArrayIndexType())){ + if(!indexType.isSubtypeOf(arrayType.getArrayIndexType())){ throw TypeCheckingExceptionPrivate(n, "array select not indexed with correct type for array"); } } @@ -55,10 +55,10 @@ struct ArrayStoreTypeRule { } TypeNode indexType = n[1].getType(check); TypeNode valueType = n[2].getType(check); - if(!indexType.isComparableTo(arrayType.getArrayIndexType())){ + if(!indexType.isSubtypeOf(arrayType.getArrayIndexType())){ throw TypeCheckingExceptionPrivate(n, "array store not indexed with correct type for array"); } - if(!valueType.isComparableTo(arrayType.getArrayConstituentType())){ + if(!valueType.isSubtypeOf(arrayType.getArrayConstituentType())){ Debug("array-types") << "array type: "<< arrayType.getArrayConstituentType() << std::endl; Debug("array-types") << "value types: " << valueType << std::endl; throw TypeCheckingExceptionPrivate(n, "array store not assigned with correct type for array"); diff --git a/src/theory/arrays/type_enumerator.h b/src/theory/arrays/type_enumerator.h index 25a8ca3f2..4314fad83 100644 --- a/src/theory/arrays/type_enumerator.h +++ b/src/theory/arrays/type_enumerator.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Clark Barrett, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arrays/union_find.cpp b/src/theory/arrays/union_find.cpp index 7899e85d5..73bedf6fc 100644 --- a/src/theory/arrays/union_find.cpp +++ b/src/theory/arrays/union_find.cpp @@ -2,9 +2,9 @@ /*! \file union_find.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/arrays/union_find.h b/src/theory/arrays/union_find.h index 5d59e8dcd..eb60f339b 100644 --- a/src/theory/arrays/union_find.h +++ b/src/theory/arrays/union_find.h @@ -2,9 +2,9 @@ /*! \file union_find.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -23,7 +23,7 @@ #include <utility> #include <vector> -#include <ext/hash_map> +#include <unordered_map> #include "expr/node.h" #include "context/cdo.h" @@ -41,7 +41,7 @@ namespace arrays { template <class NodeType, class NodeHash> class UnionFind : context::ContextNotifyObj { /** Our underlying map type. */ - typedef __gnu_cxx::hash_map<NodeType, NodeType, NodeHash> MapType; + typedef std::unordered_map<NodeType, NodeType, NodeHash> MapType; /** * Our map of Nodes to their canonical representatives. diff --git a/src/theory/assertion.cpp b/src/theory/assertion.cpp index 99ddbc6e9..8c9de809c 100644 --- a/src/theory/assertion.cpp +++ b/src/theory/assertion.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/atom_requests.cpp b/src/theory/atom_requests.cpp index e3f30cc6e..5605a6754 100644 --- a/src/theory/atom_requests.cpp +++ b/src/theory/atom_requests.cpp @@ -2,9 +2,9 @@ /*! \file atom_requests.cpp ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/atom_requests.h b/src/theory/atom_requests.h index 7f6194192..f36d23dc9 100644 --- a/src/theory/atom_requests.h +++ b/src/theory/atom_requests.h @@ -2,9 +2,9 @@ /*! \file atom_requests.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/booleans/circuit_propagator.cpp b/src/theory/booleans/circuit_propagator.cpp index 8e9116543..11b6185ab 100644 --- a/src/theory/booleans/circuit_propagator.cpp +++ b/src/theory/booleans/circuit_propagator.cpp @@ -2,9 +2,9 @@ /*! \file circuit_propagator.cpp ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/booleans/circuit_propagator.h b/src/theory/booleans/circuit_propagator.h index 5a6e46269..78e01f690 100644 --- a/src/theory/booleans/circuit_propagator.h +++ b/src/theory/booleans/circuit_propagator.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,8 +19,9 @@ #ifndef __CVC4__THEORY__BOOLEANS__CIRCUIT_PROPAGATOR_H #define __CVC4__THEORY__BOOLEANS__CIRCUIT_PROPAGATOR_H -#include <vector> #include <functional> +#include <unordered_map> +#include <vector> #include "theory/theory.h" #include "context/context.h" @@ -64,7 +65,7 @@ public: else return ASSIGNED_TO_TRUE; } - typedef std::hash_map<Node, std::vector<Node>, NodeHashFunction> BackEdgesMap; + typedef std::unordered_map<Node, std::vector<Node>, NodeHashFunction> BackEdgesMap; private: diff --git a/src/theory/booleans/theory_bool.cpp b/src/theory/booleans/theory_bool.cpp index de27fc834..afe673449 100644 --- a/src/theory/booleans/theory_bool.cpp +++ b/src/theory/booleans/theory_bool.cpp @@ -2,9 +2,9 @@ /*! \file theory_bool.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/booleans/theory_bool.h b/src/theory/booleans/theory_bool.h index 353143c43..9d5966628 100644 --- a/src/theory/booleans/theory_bool.h +++ b/src/theory/booleans/theory_bool.h @@ -2,9 +2,9 @@ /*! \file theory_bool.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Dejan Jovanovic + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/booleans/theory_bool_rewriter.cpp b/src/theory/booleans/theory_bool_rewriter.cpp index 32f69e037..8373f636b 100644 --- a/src/theory/booleans/theory_bool_rewriter.cpp +++ b/src/theory/booleans/theory_bool_rewriter.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Dejan Jovanovic, Kshitij Bansal ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -16,6 +16,8 @@ **/ #include <algorithm> +#include <unordered_set> + #include "theory/booleans/theory_bool_rewriter.h" namespace CVC4 { @@ -41,7 +43,7 @@ RewriteResponse TheoryBoolRewriter::postRewrite(TNode node) { */ RewriteResponse flattenNode(TNode n, TNode trivialNode, TNode skipNode) { - typedef std::hash_set<TNode, TNodeHashFunction> node_set; + typedef std::unordered_set<TNode, TNodeHashFunction> node_set; node_set visited; visited.insert(skipNode); diff --git a/src/theory/booleans/theory_bool_rewriter.h b/src/theory/booleans/theory_bool_rewriter.h index b7512ad09..d5b2aba21 100644 --- a/src/theory/booleans/theory_bool_rewriter.h +++ b/src/theory/booleans/theory_bool_rewriter.h @@ -2,9 +2,9 @@ /*! \file theory_bool_rewriter.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Morgan Deters, Dejan Jovanovic, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/booleans/theory_bool_type_rules.h b/src/theory/booleans/theory_bool_type_rules.h index 050796e50..7de38b6af 100644 --- a/src/theory/booleans/theory_bool_type_rules.h +++ b/src/theory/booleans/theory_bool_type_rules.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/booleans/type_enumerator.h b/src/theory/booleans/type_enumerator.h index e91f47317..b0759cbb2 100644 --- a/src/theory/booleans/type_enumerator.h +++ b/src/theory/booleans/type_enumerator.h @@ -2,9 +2,9 @@ /*! \file type_enumerator.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Paul Meng, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/builtin/kinds b/src/theory/builtin/kinds index 0ebebf1dd..12e897189 100644 --- a/src/theory/builtin/kinds +++ b/src/theory/builtin/kinds @@ -336,17 +336,4 @@ typerule LAMBDA ::CVC4::theory::builtin::LambdaTypeRule typerule CHAIN ::CVC4::theory::builtin::ChainTypeRule typerule CHAIN_OP ::CVC4::theory::builtin::ChainedOperatorTypeRule -constant SUBTYPE_TYPE \ - ::CVC4::Predicate \ - ::CVC4::PredicateHashFunction \ - "expr/predicate.h" \ - "predicate subtype; payload is an instance of the CVC4::Predicate class" -cardinality SUBTYPE_TYPE \ - "::CVC4::theory::builtin::SubtypeProperties::computeCardinality(%TYPE%)" \ - "theory/builtin/theory_builtin_type_rules.h" -well-founded SUBTYPE_TYPE \ - "::CVC4::theory::builtin::SubtypeProperties::isWellFounded(%TYPE%)" \ - "::CVC4::theory::builtin::SubtypeProperties::mkGroundTerm(%TYPE%)" \ - "theory/builtin/theory_builtin_type_rules.h" - endtheory diff --git a/src/theory/builtin/theory_builtin.cpp b/src/theory/builtin/theory_builtin.cpp index cea66dafe..5f3f1c843 100644 --- a/src/theory/builtin/theory_builtin.cpp +++ b/src/theory/builtin/theory_builtin.cpp @@ -2,9 +2,9 @@ /*! \file theory_builtin.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/builtin/theory_builtin.h b/src/theory/builtin/theory_builtin.h index 205db5b4d..cfc59272c 100644 --- a/src/theory/builtin/theory_builtin.h +++ b/src/theory/builtin/theory_builtin.h @@ -2,9 +2,9 @@ /*! \file theory_builtin.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/builtin/theory_builtin_rewriter.cpp b/src/theory/builtin/theory_builtin_rewriter.cpp index a2fb3f3f6..32b35dfe8 100644 --- a/src/theory/builtin/theory_builtin_rewriter.cpp +++ b/src/theory/builtin/theory_builtin_rewriter.cpp @@ -2,9 +2,9 @@ /*! \file theory_builtin_rewriter.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Morgan Deters, Dejan Jovanovic, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/builtin/theory_builtin_rewriter.h b/src/theory/builtin/theory_builtin_rewriter.h index 9ac259027..8ca2c538e 100644 --- a/src/theory/builtin/theory_builtin_rewriter.h +++ b/src/theory/builtin/theory_builtin_rewriter.h @@ -2,9 +2,9 @@ /*! \file theory_builtin_rewriter.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Morgan Deters, Dejan Jovanovic, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/builtin/theory_builtin_type_rules.h b/src/theory/builtin/theory_builtin_type_rules.h index 85adfb41c..d8893d441 100644 --- a/src/theory/builtin/theory_builtin_type_rules.h +++ b/src/theory/builtin/theory_builtin_type_rules.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -77,6 +77,9 @@ class EqualityTypeRule { TypeNode lhsType = n[0].getType(check); TypeNode rhsType = n[1].getType(check); + // TODO : we may want to limit cases where we have equalities between terms of different types + // equalities between (Set Int) and (Set Real) already cause strange issues in theory solver for sets + // one possibility is to only allow this for Int/Real if ( TypeNode::leastCommonTypeNode(lhsType, rhsType).isNull() ) { std::stringstream ss; ss << "Subexpressions must have a common base type:" << std::endl; @@ -299,26 +302,6 @@ public: } };/* class SExprProperties */ -class SubtypeProperties { -public: - - inline static Cardinality computeCardinality(TypeNode type) { - Assert(type.getKind() == kind::SUBTYPE_TYPE); - Unimplemented("Computing the cardinality for predicate subtype not yet supported."); - } - - inline static bool isWellFounded(TypeNode type) { - Assert(type.getKind() == kind::SUBTYPE_TYPE); - Unimplemented("Computing the well-foundedness for predicate subtype not yet supported."); - } - - inline static Node mkGroundTerm(TypeNode type) { - Assert(type.getKind() == kind::SUBTYPE_TYPE); - Unimplemented("Constructing a ground term for predicate subtype not yet supported."); - } - -};/* class SubtypeProperties */ - }/* CVC4::theory::builtin namespace */ }/* CVC4::theory namespace */ }/* CVC4 namespace */ diff --git a/src/theory/builtin/type_enumerator.h b/src/theory/builtin/type_enumerator.h index 6ee540004..1ab732710 100644 --- a/src/theory/builtin/type_enumerator.h +++ b/src/theory/builtin/type_enumerator.h @@ -2,9 +2,9 @@ /*! \file type_enumerator.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Morgan Deters, Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/abstraction.cpp b/src/theory/bv/abstraction.cpp index dc5520411..4ef484594 100644 --- a/src/theory/bv/abstraction.cpp +++ b/src/theory/bv/abstraction.cpp @@ -2,9 +2,9 @@ /*! \file abstraction.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King, Morgan Deters + ** Liana Hadarean, Guy Katz, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/abstraction.h b/src/theory/bv/abstraction.h index 5d48b926e..0d7e0ff2a 100644 --- a/src/theory/bv/abstraction.h +++ b/src/theory/bv/abstraction.h @@ -2,9 +2,9 @@ /*! \file abstraction.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King + ** Liana Hadarean, Guy Katz, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,8 +19,8 @@ #ifndef __CVC4__THEORY__BV__ABSTRACTION_H #define __CVC4__THEORY__BV__ABSTRACTION_H -#include <ext/hash_map> -#include <ext/hash_set> +#include <unordered_map> +#include <unordered_set> #include "expr/node.h" #include "theory/substitutions.h" @@ -64,10 +64,10 @@ class AbstractionModule { }; class ArgsTable { - __gnu_cxx::hash_map<TNode, ArgsTableEntry, TNodeHashFunction > d_data; + std::unordered_map<TNode, ArgsTableEntry, TNodeHashFunction > d_data; bool hasEntry(TNode signature) const; public: - typedef __gnu_cxx::hash_map<TNode, ArgsTableEntry, TNodeHashFunction >::iterator iterator; + typedef std::unordered_map<TNode, ArgsTableEntry, TNodeHashFunction >::iterator iterator; ArgsTable() {} void addEntry(TNode signature, const ArgsVec& args); ArgsTableEntry& getEntry(TNode signature); @@ -122,16 +122,16 @@ class AbstractionModule { }; - typedef __gnu_cxx::hash_map<Node, std::vector<Node>, NodeHashFunction> NodeVecMap; - typedef __gnu_cxx::hash_map<Node, TNode, NodeHashFunction> NodeTNodeMap; - typedef __gnu_cxx::hash_map<TNode, TNode, TNodeHashFunction> TNodeTNodeMap; - typedef __gnu_cxx::hash_map<Node, Node, NodeHashFunction> NodeNodeMap; - typedef __gnu_cxx::hash_map<Node, TNode, NodeHashFunction> TNodeNodeMap; - typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet; - typedef __gnu_cxx::hash_map<unsigned, Node> IntNodeMap; - typedef __gnu_cxx::hash_map<unsigned, unsigned> IndexMap; - typedef __gnu_cxx::hash_map<unsigned, std::vector<Node> > SkolemMap; - typedef __gnu_cxx::hash_map<TNode, unsigned, TNodeHashFunction > SignatureMap; + typedef std::unordered_map<Node, std::vector<Node>, NodeHashFunction> NodeVecMap; + typedef std::unordered_map<Node, TNode, NodeHashFunction> NodeTNodeMap; + typedef std::unordered_map<TNode, TNode, TNodeHashFunction> TNodeTNodeMap; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeNodeMap; + typedef std::unordered_map<Node, TNode, NodeHashFunction> TNodeNodeMap; + typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; + typedef std::unordered_map<unsigned, Node> IntNodeMap; + typedef std::unordered_map<unsigned, unsigned> IndexMap; + typedef std::unordered_map<unsigned, std::vector<Node> > SkolemMap; + typedef std::unordered_map<TNode, unsigned, TNodeHashFunction > SignatureMap; ArgsTable d_argsTable; diff --git a/src/theory/bv/aig_bitblaster.cpp b/src/theory/bv/aig_bitblaster.cpp index 35cd48058..fad1ea89b 100644 --- a/src/theory/bv/aig_bitblaster.cpp +++ b/src/theory/bv/aig_bitblaster.cpp @@ -2,9 +2,9 @@ /*! \file aig_bitblaster.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King, Morgan Deters + ** Liana Hadarean, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bitblast_strategies_template.h b/src/theory/bv/bitblast_strategies_template.h index 3a9106984..a93e3416c 100644 --- a/src/theory/bv/bitblast_strategies_template.h +++ b/src/theory/bv/bitblast_strategies_template.h @@ -2,9 +2,9 @@ /*! \file bitblast_strategies_template.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King, Morgan Deters + ** Liana Hadarean, Tim King, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bitblast_utils.h b/src/theory/bv/bitblast_utils.h index baa85f64b..1d6920007 100644 --- a/src/theory/bv/bitblast_utils.h +++ b/src/theory/bv/bitblast_utils.h @@ -2,9 +2,9 @@ /*! \file bitblast_utils.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King + ** Liana Hadarean, Paul Meng, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bitblaster_template.h b/src/theory/bv/bitblaster_template.h index 8a7ccf8c6..565c454e3 100644 --- a/src/theory/bv/bitblaster_template.h +++ b/src/theory/bv/bitblaster_template.h @@ -2,9 +2,9 @@ /*! \file bitblaster_template.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King, Morgan Deters + ** Liana Hadarean, Tim King, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,7 +19,8 @@ #ifndef __CVC4__BITBLASTER_TEMPLATE_H #define __CVC4__BITBLASTER_TEMPLATE_H -#include <ext/hash_map> +#include <unordered_map> +#include <unordered_set> #include <vector> #include "bitblast_strategies_template.h" @@ -58,8 +59,8 @@ namespace bv { class BitblastingRegistrar; -typedef __gnu_cxx::hash_set<Node, NodeHashFunction> NodeSet; -typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet; +typedef std::unordered_set<Node, NodeHashFunction> NodeSet; +typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; class AbstractionModule; @@ -73,9 +74,9 @@ template <class T> class TBitblaster { protected: typedef std::vector<T> Bits; - typedef __gnu_cxx::hash_map <Node, Bits, NodeHashFunction> TermDefMap; - typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet; - typedef __gnu_cxx::hash_map<Node, Node, NodeHashFunction> ModelCache; + typedef std::unordered_map <Node, Bits, NodeHashFunction> TermDefMap; + typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; + typedef std::unordered_map<Node, Node, NodeHashFunction> ModelCache; typedef void (*TermBBStrategy) (TNode, Bits&, TBitblaster<T>*); typedef T (*AtomBBStrategy) (TNode, TBitblaster<T>*); @@ -258,7 +259,7 @@ public: class EagerBitblaster : public TBitblaster<Node> { - typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet; + typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; // sat solver used for bitblasting and associated CnfStream prop::SatSolver* d_satSolver; BitblastingRegistrar* d_bitblastingRegistrar; @@ -305,8 +306,8 @@ public: }; /* class Registrar */ class AigBitblaster : public TBitblaster<Abc_Obj_t*> { - typedef std::hash_map<TNode, Abc_Obj_t*, TNodeHashFunction > TNodeAigMap; - typedef std::hash_map<Node, Abc_Obj_t*, NodeHashFunction > NodeAigMap; + typedef std::unordered_map<TNode, Abc_Obj_t*, TNodeHashFunction > TNodeAigMap; + typedef std::unordered_map<Node, Abc_Obj_t*, NodeHashFunction > NodeAigMap; static Abc_Ntk_t* abcAigNetwork; context::Context* d_nullContext; diff --git a/src/theory/bv/bv_eager_solver.cpp b/src/theory/bv/bv_eager_solver.cpp index cad59f5ca..05b314fad 100644 --- a/src/theory/bv/bv_eager_solver.cpp +++ b/src/theory/bv/bv_eager_solver.cpp @@ -2,9 +2,9 @@ /*! \file bv_eager_solver.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King + ** Liana Hadarean, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bv_eager_solver.h b/src/theory/bv/bv_eager_solver.h index 7ac05379b..ec6cbad09 100644 --- a/src/theory/bv/bv_eager_solver.h +++ b/src/theory/bv/bv_eager_solver.h @@ -2,25 +2,28 @@ /*! \file bv_eager_solver.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King + ** Liana Hadarean, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 Eager bit-blasting solver. + ** \brief Eager bit-blasting solver. ** ** Eager bit-blasting solver. **/ #include "cvc4_private.h" + +#pragma once + +#include <unordered_set> +#include <vector> + #include "expr/node.h" #include "theory/theory_model.h" #include "theory/bv/theory_bv.h" -#include <vector> -#pragma once - namespace CVC4 { namespace theory { @@ -33,7 +36,7 @@ class AigBitblaster; * BitblastSolver */ class EagerBitblastSolver { - typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> AssertionSet; + typedef std::unordered_set<TNode, TNodeHashFunction> AssertionSet; AssertionSet d_assertionSet; /** Bitblasters */ EagerBitblaster* d_bitblaster; diff --git a/src/theory/bv/bv_inequality_graph.cpp b/src/theory/bv/bv_inequality_graph.cpp index f03d3a683..d0b299d3b 100644 --- a/src/theory/bv/bv_inequality_graph.cpp +++ b/src/theory/bv/bv_inequality_graph.cpp @@ -2,9 +2,9 @@ /*! \file bv_inequality_graph.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King, Morgan Deters + ** Liana Hadarean, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bv_inequality_graph.h b/src/theory/bv/bv_inequality_graph.h index 72f6dbfd1..30270b3c3 100644 --- a/src/theory/bv/bv_inequality_graph.h +++ b/src/theory/bv/bv_inequality_graph.h @@ -2,14 +2,14 @@ /*! \file bv_inequality_graph.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King + ** Liana Hadarean, Tim King, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 Algebraic solver. + ** \brief Algebraic solver. ** ** Algebraic solver. **/ @@ -19,23 +19,25 @@ #ifndef __CVC4__THEORY__BV__BV_INEQUALITY__GRAPH_H #define __CVC4__THEORY__BV__BV_INEQUALITY__GRAPH_H -#include "context/context.h" +#include <list> +#include <queue> +#include <unordered_map> +#include <unordered_set> + #include "context/cdqueue.h" -#include "theory/uf/equality_engine.h" +#include "context/context.h" #include "theory/theory.h" -#include <queue> -#include <list> +#include "theory/uf/equality_engine.h" + namespace CVC4 { namespace theory { - - namespace bv { -typedef unsigned TermId; +typedef unsigned TermId; typedef unsigned ReasonId; extern const TermId UndefinedTermId; extern const ReasonId UndefinedReasonId; -extern const ReasonId AxiomReasonId; +extern const ReasonId AxiomReasonId; class InequalityGraph : public context::ContextNotifyObj{ @@ -100,15 +102,15 @@ class InequalityGraph : public context::ContextNotifyObj{ } }; - typedef __gnu_cxx::hash_map<TNode, ReasonId, TNodeHashFunction> ReasonToIdMap; - typedef __gnu_cxx::hash_map<TNode, TermId, TNodeHashFunction> TermNodeToIdMap; + typedef std::unordered_map<TNode, ReasonId, TNodeHashFunction> ReasonToIdMap; + typedef std::unordered_map<TNode, TermId, TNodeHashFunction> TermNodeToIdMap; typedef std::vector<InequalityEdge> Edges; - typedef __gnu_cxx::hash_set<TermId> TermIdSet; + typedef std::unordered_set<TermId> TermIdSet; typedef std::priority_queue<TermId, std::vector<TermId>, QueueComparator> BFSQueue; - typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet; - typedef __gnu_cxx::hash_set<Node, NodeHashFunction> NodeSet; + typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; + typedef std::unordered_set<Node, NodeHashFunction> NodeSet; std::vector<InequalityNode> d_ineqNodes; std::vector< Edges > d_ineqEdges; diff --git a/src/theory/bv/bv_quick_check.cpp b/src/theory/bv/bv_quick_check.cpp index 0a9ae819d..b347ddccf 100644 --- a/src/theory/bv/bv_quick_check.cpp +++ b/src/theory/bv/bv_quick_check.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bv_quick_check.h b/src/theory/bv/bv_quick_check.h index 96f9c246e..c5fe63ad6 100644 --- a/src/theory/bv/bv_quick_check.h +++ b/src/theory/bv/bv_quick_check.h @@ -2,9 +2,9 @@ /*! \file bv_quick_check.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King, Morgan Deters + ** Liana Hadarean, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,7 @@ #define __CVC4__BV_QUICK_CHECK_H #include <vector> -#include <ext/hash_map> +#include <unordered_set> #include "context/cdo.h" #include "expr/node.h" @@ -99,7 +99,7 @@ public: uint64_t computeAtomWeight(TNode atom, NodeSet& seen); void collectModelInfo(theory::TheoryModel* model, bool fullModel); - typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction>::const_iterator vars_iterator; + typedef std::unordered_set<TNode, TNodeHashFunction>::const_iterator vars_iterator; vars_iterator beginVars(); vars_iterator endVars(); diff --git a/src/theory/bv/bv_subtheory.h b/src/theory/bv/bv_subtheory.h index 3c5777af9..4f074a202 100644 --- a/src/theory/bv/bv_subtheory.h +++ b/src/theory/bv/bv_subtheory.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Dejan Jovanovic, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bv_subtheory_algebraic.cpp b/src/theory/bv/bv_subtheory_algebraic.cpp index 60515b2d1..c5313b9e7 100644 --- a/src/theory/bv/bv_subtheory_algebraic.cpp +++ b/src/theory/bv/bv_subtheory_algebraic.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bv_subtheory_algebraic.h b/src/theory/bv/bv_subtheory_algebraic.h index 0e0e02151..4b4103e44 100644 --- a/src/theory/bv/bv_subtheory_algebraic.h +++ b/src/theory/bv/bv_subtheory_algebraic.h @@ -2,9 +2,9 @@ /*! \file bv_subtheory_algebraic.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Morgan Deters, Tim King + ** Liana Hadarean, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -14,12 +14,16 @@ ** Algebraic solver. **/ +#include "cvc4_private.h" + #pragma once -#include "cvc4_private.h" +#include <unordered_map> +#include <unordered_set> + #include "theory/bv/bv_subtheory.h" -#include "theory/substitutions.h" #include "theory/bv/slicer.h" +#include "theory/substitutions.h" namespace CVC4 { namespace theory { @@ -60,8 +64,8 @@ class SubstitutionEx { {} }; - typedef __gnu_cxx::hash_map<Node, SubstitutionElement, NodeHashFunction> Substitutions; - typedef __gnu_cxx::hash_map<Node, SubstitutionElement, NodeHashFunction> SubstitutionsCache; + typedef std::unordered_map<Node, SubstitutionElement, NodeHashFunction> Substitutions; + typedef std::unordered_map<Node, SubstitutionElement, NodeHashFunction> SubstitutionsCache; Substitutions d_substitutions; SubstitutionsCache d_cache; @@ -104,9 +108,9 @@ struct WorklistElement { }; -typedef __gnu_cxx::hash_map<Node, Node, NodeHashFunction> NodeNodeMap; -typedef __gnu_cxx::hash_map<Node, unsigned, NodeHashFunction> NodeIdMap; -typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet; +typedef std::unordered_map<Node, Node, NodeHashFunction> NodeNodeMap; +typedef std::unordered_map<Node, unsigned, NodeHashFunction> NodeIdMap; +typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; class ExtractSkolemizer { @@ -123,7 +127,7 @@ class ExtractSkolemizer { ExtractList() : base(1), extracts() {} void addExtract(Extract& e); }; - typedef __gnu_cxx::hash_map<Node, ExtractList, NodeHashFunction> VarExtractMap; + typedef std::unordered_map<Node, ExtractList, NodeHashFunction> VarExtractMap; context::Context d_emptyContext; VarExtractMap d_varToExtract; theory::SubstitutionMap* d_modelMap; diff --git a/src/theory/bv/bv_subtheory_bitblast.cpp b/src/theory/bv/bv_subtheory_bitblast.cpp index 7b7d38307..77e596d1f 100644 --- a/src/theory/bv/bv_subtheory_bitblast.cpp +++ b/src/theory/bv/bv_subtheory_bitblast.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Dejan Jovanovic, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bv_subtheory_bitblast.h b/src/theory/bv/bv_subtheory_bitblast.h index fe16d2702..4bbe4327e 100644 --- a/src/theory/bv/bv_subtheory_bitblast.h +++ b/src/theory/bv/bv_subtheory_bitblast.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Liana Hadarean, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -18,6 +18,8 @@ #pragma once +#include <unordered_map> + #include "theory/bv/bitblaster_template.h" #include "theory/bv/bv_subtheory.h" @@ -47,7 +49,7 @@ class BitblastSolver : public SubtheorySolver { context::CDQueue<TNode> d_bitblastQueue; Statistics d_statistics; - typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeMap; NodeMap d_modelCache; context::CDO<bool> d_validModelCache; diff --git a/src/theory/bv/bv_subtheory_core.cpp b/src/theory/bv/bv_subtheory_core.cpp index ccce819e6..54f454dca 100644 --- a/src/theory/bv/bv_subtheory_core.cpp +++ b/src/theory/bv/bv_subtheory_core.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bv_subtheory_core.h b/src/theory/bv/bv_subtheory_core.h index 22219b5d0..b416e019d 100644 --- a/src/theory/bv/bv_subtheory_core.h +++ b/src/theory/bv/bv_subtheory_core.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -14,12 +14,16 @@ ** Algebraic solver. **/ +#include "cvc4_private.h" + #pragma once -#include "cvc4_private.h" -#include "theory/bv/bv_subtheory.h" +#include <unordered_map> +#include <unordered_set> + #include "context/cdhashmap.h" #include "context/cdhashset.h" +#include "theory/bv/bv_subtheory.h" namespace CVC4 { namespace theory { @@ -31,9 +35,9 @@ class Base; * Bitvector equality solver */ class CoreSolver : public SubtheorySolver { - typedef __gnu_cxx::hash_map<TNode, Node, TNodeHashFunction> ModelValue; - typedef __gnu_cxx::hash_map<TNode, bool, TNodeHashFunction> TNodeBoolMap; - typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet; + typedef std::unordered_map<TNode, Node, TNodeHashFunction> ModelValue; + typedef std::unordered_map<TNode, bool, TNodeHashFunction> TNodeBoolMap; + typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; struct Statistics { diff --git a/src/theory/bv/bv_subtheory_inequality.cpp b/src/theory/bv/bv_subtheory_inequality.cpp index 1fe096214..d662f056b 100644 --- a/src/theory/bv/bv_subtheory_inequality.cpp +++ b/src/theory/bv/bv_subtheory_inequality.cpp @@ -2,9 +2,9 @@ /*! \file bv_subtheory_inequality.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Andrew Reynolds, Tim King + ** Liana Hadarean, Andrew Reynolds, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bv_subtheory_inequality.h b/src/theory/bv/bv_subtheory_inequality.h index 617e3b761..1123d15ae 100644 --- a/src/theory/bv/bv_subtheory_inequality.h +++ b/src/theory/bv/bv_subtheory_inequality.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Andrew Reynolds, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,10 +19,12 @@ #ifndef __CVC4__THEORY__BV__BV_SUBTHEORY__INEQUALITY_H #define __CVC4__THEORY__BV__BV_SUBTHEORY__INEQUALITY_H -#include "theory/bv/bv_subtheory.h" -#include "theory/bv/bv_inequality_graph.h" +#include <unordered_set> + #include "context/cdhashset.h" #include "expr/attribute.h" +#include "theory/bv/bv_inequality_graph.h" +#include "theory/bv/bv_subtheory.h" namespace CVC4 { namespace theory { @@ -47,7 +49,7 @@ class InequalitySolver: public SubtheorySolver { InequalityGraph d_inequalityGraph; context::CDHashMap<Node, TNode, NodeHashFunction> d_explanations; context::CDO<bool> d_isComplete; - typedef __gnu_cxx::hash_set<Node, NodeHashFunction> NodeSet; + typedef std::unordered_set<Node, NodeHashFunction> NodeSet; NodeSet d_ineqTerms; bool isInequalityOnly(TNode node); bool addInequality(TNode a, TNode b, bool strict, TNode fact); diff --git a/src/theory/bv/bv_to_bool.cpp b/src/theory/bv/bv_to_bool.cpp index 5b7fe160c..9718e9a2f 100644 --- a/src/theory/bv/bv_to_bool.cpp +++ b/src/theory/bv/bv_to_bool.cpp @@ -2,9 +2,9 @@ /*! \file bv_to_bool.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King + ** Liana Hadarean, Clark Barrett, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bv_to_bool.h b/src/theory/bv/bv_to_bool.h index 7e351c9c6..93a83626e 100644 --- a/src/theory/bv/bv_to_bool.h +++ b/src/theory/bv/bv_to_bool.h @@ -2,9 +2,9 @@ /*! \file bv_to_bool.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King + ** Liana Hadarean, Clark Barrett, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,6 +19,8 @@ #ifndef __CVC4__THEORY__BV__BV_TO_BOOL_H #define __CVC4__THEORY__BV__BV_TO_BOOL_H +#include <unordered_map> + #include "theory/bv/theory_bv_utils.h" #include "util/statistics_registry.h" @@ -26,7 +28,7 @@ namespace CVC4 { namespace theory { namespace bv { -typedef __gnu_cxx::hash_map<Node, Node, NodeHashFunction> NodeNodeMap; +typedef std::unordered_map<Node, Node, NodeHashFunction> NodeNodeMap; class BvToBoolPreprocessor { diff --git a/src/theory/bv/bvintropow2.cpp b/src/theory/bv/bvintropow2.cpp index 022aaf2fd..e7b6caaef 100644 --- a/src/theory/bv/bvintropow2.cpp +++ b/src/theory/bv/bvintropow2.cpp @@ -2,9 +2,9 @@ /*! \file bvintropow2.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Morgan Deters, Tim King + ** Liana Hadarean, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/bvintropow2.h b/src/theory/bv/bvintropow2.h index 09d3d9259..e335c1339 100644 --- a/src/theory/bv/bvintropow2.h +++ b/src/theory/bv/bvintropow2.h @@ -2,9 +2,9 @@ /*! \file bvintropow2.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Morgan Deters, Tim King + ** Liana Hadarean, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -21,7 +21,7 @@ #include "expr/node.h" #include <vector> -#include <ext/hash_map> +#include <unordered_map> #ifndef __CVC4__THEORY__BV__BV_INTRO_POW_H #define __CVC4__THEORY__BV__BV_INTRO_POW_H @@ -36,7 +36,7 @@ public: static void pow2Rewrite(std::vector<Node>& assertionsToPreprocess); private: - typedef __gnu_cxx::hash_map<Node, Node, NodeHashFunction> NodeMap; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeMap; static Node pow2Rewrite(Node assertionsToPreprocess, NodeMap& cache); }; diff --git a/src/theory/bv/cd_set_collection.h b/src/theory/bv/cd_set_collection.h index 456552ebd..397c872b2 100644 --- a/src/theory/bv/cd_set_collection.h +++ b/src/theory/bv/cd_set_collection.h @@ -2,9 +2,9 @@ /*! \file cd_set_collection.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/eager_bitblaster.cpp b/src/theory/bv/eager_bitblaster.cpp index 053986b8c..29f6e7800 100644 --- a/src/theory/bv/eager_bitblaster.cpp +++ b/src/theory/bv/eager_bitblaster.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Tim King, Guy Katz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/lazy_bitblaster.cpp b/src/theory/bv/lazy_bitblaster.cpp index e89cacb40..32aff1fb0 100644 --- a/src/theory/bv/lazy_bitblaster.cpp +++ b/src/theory/bv/lazy_bitblaster.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/slicer.cpp b/src/theory/bv/slicer.cpp index 150f73ac9..bf5152893 100644 --- a/src/theory/bv/slicer.cpp +++ b/src/theory/bv/slicer.cpp @@ -2,9 +2,9 @@ /*! \file slicer.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King, Morgan Deters + ** Liana Hadarean, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/slicer.h b/src/theory/bv/slicer.h index 4eae27963..dc8d333c4 100644 --- a/src/theory/bv/slicer.h +++ b/src/theory/bv/slicer.h @@ -2,9 +2,9 @@ /*! \file slicer.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King + ** Liana Hadarean, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,7 @@ #include <vector> #include <list> -#include <ext/hash_map> +#include <unordered_map> #include "expr/node.h" #include "theory/bv/theory_bv_utils.h" @@ -79,7 +79,7 @@ public: * UnionFind * */ -typedef __gnu_cxx::hash_set<TermId> TermSet; +typedef std::unordered_set<TermId> TermSet; typedef std::vector<TermId> Decomposition; struct ExtractTerm { @@ -226,9 +226,9 @@ public: }; class Slicer { - __gnu_cxx::hash_map<TermId, TNode> d_idToNode; - __gnu_cxx::hash_map<TNode, TermId, TNodeHashFunction> d_nodeToId; - __gnu_cxx::hash_map<TNode, bool, TNodeHashFunction> d_coreTermCache; + std::unordered_map<TermId, TNode> d_idToNode; + std::unordered_map<TNode, TermId, TNodeHashFunction> d_nodeToId; + std::unordered_map<TNode, bool, TNodeHashFunction> d_coreTermCache; UnionFind d_unionFind; ExtractTerm registerTerm(TNode node); public: diff --git a/src/theory/bv/theory_bv.cpp b/src/theory/bv/theory_bv.cpp index 9db909c22..1a59687db 100644 --- a/src/theory/bv/theory_bv.cpp +++ b/src/theory/bv/theory_bv.cpp @@ -2,9 +2,9 @@ /*! \file theory_bv.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King, Dejan Jovanovic + ** Liana Hadarean, Andrew Reynolds, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/theory_bv.h b/src/theory/bv/theory_bv.h index 62eb6f6b5..c20df35d5 100644 --- a/src/theory/bv/theory_bv.h +++ b/src/theory/bv/theory_bv.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,6 +19,9 @@ #ifndef __CVC4__THEORY__BV__THEORY_BV_H #define __CVC4__THEORY__BV__THEORY_BV_H +#include <unordered_map> +#include <unordered_set> + #include "context/cdhashset.h" #include "context/cdlist.h" #include "context/context.h" @@ -51,7 +54,7 @@ class TheoryBV : public Theory { context::CDHashSet<Node, NodeHashFunction> d_sharedTermsSet; std::vector<SubtheorySolver*> d_subtheories; - __gnu_cxx::hash_map<SubTheory, SubtheorySolver*, std::hash<int> > d_subtheoryMap; + std::unordered_map<SubTheory, SubtheorySolver*, std::hash<int> > d_subtheoryMap; public: @@ -129,22 +132,22 @@ private: */ Node getBVDivByZero(Kind k, unsigned width); - typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet; + typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; void collectFunctionSymbols(TNode term, TNodeSet& seen); void storeFunction(TNode func, TNode term); - typedef __gnu_cxx::hash_set<Node, NodeHashFunction> NodeSet; + typedef std::unordered_set<Node, NodeHashFunction> NodeSet; NodeSet d_staticLearnCache; /** * Maps from bit-vector width to division-by-zero uninterpreted * function symbols. */ - __gnu_cxx::hash_map<unsigned, Node> d_BVDivByZero; - __gnu_cxx::hash_map<unsigned, Node> d_BVRemByZero; + std::unordered_map<unsigned, Node> d_BVDivByZero; + std::unordered_map<unsigned, Node> d_BVRemByZero; - typedef __gnu_cxx::hash_map<Node, NodeSet, NodeHashFunction> FunctionToArgs; - typedef __gnu_cxx::hash_map<Node, Node, NodeHashFunction> NodeToNode; + typedef std::unordered_map<Node, NodeSet, NodeHashFunction> FunctionToArgs; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeToNode; // for ackermanization FunctionToArgs d_funcToArgs; CVC4::theory::SubstitutionMap d_funcToSkolem; diff --git a/src/theory/bv/theory_bv_rewrite_rules.h b/src/theory/bv/theory_bv_rewrite_rules.h index 39e8e38cd..9f148d823 100644 --- a/src/theory/bv/theory_bv_rewrite_rules.h +++ b/src/theory/bv/theory_bv_rewrite_rules.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Dejan Jovanovic, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h b/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h index 3605a6970..b53f7bb08 100644 --- a/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h +++ b/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Clark Barrett, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/theory_bv_rewrite_rules_core.h b/src/theory/bv/theory_bv_rewrite_rules_core.h index 395949f03..5b8eaea60 100644 --- a/src/theory/bv/theory_bv_rewrite_rules_core.h +++ b/src/theory/bv/theory_bv_rewrite_rules_core.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Liana Hadarean, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/theory_bv_rewrite_rules_normalization.h b/src/theory/bv/theory_bv_rewrite_rules_normalization.h index 89bb3d7ac..61f072643 100644 --- a/src/theory/bv/theory_bv_rewrite_rules_normalization.h +++ b/src/theory/bv/theory_bv_rewrite_rules_normalization.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Clark Barrett, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,6 +19,9 @@ #pragma once +#include <unordered_map> +#include <unordered_set> + #include "theory/rewriter.h" #include "theory/bv/theory_bv_rewrite_rules.h" #include "theory/bv/theory_bv_utils.h" @@ -922,7 +925,7 @@ struct Count { {} }; -inline static void insert(std::hash_map<TNode, Count, TNodeHashFunction>& map, TNode node, bool neg) { +inline static void insert(std::unordered_map<TNode, Count, TNodeHashFunction>& map, TNode node, bool neg) { if(map.find(node) == map.end()) { Count c = neg? Count(0,1) : Count(1, 0); map[node] = c; @@ -945,7 +948,7 @@ Node RewriteRule<AndSimplify>::apply(TNode node) { Debug("bv-rewrite") << "RewriteRule<AndSimplify>(" << node << ")" << std::endl; // this will remove duplicates - std::hash_map<TNode, Count, TNodeHashFunction> subterms; + std::unordered_map<TNode, Count, TNodeHashFunction> subterms; unsigned size = utils::getSize(node); BitVector constant = utils::mkBitVectorOnes(size); @@ -974,7 +977,7 @@ Node RewriteRule<AndSimplify>::apply(TNode node) { children.push_back(utils::mkConst(constant)); } - std::hash_map<TNode, Count, TNodeHashFunction>::const_iterator it = subterms.begin(); + std::unordered_map<TNode, Count, TNodeHashFunction>::const_iterator it = subterms.begin(); for (; it != subterms.end(); ++it) { if (it->second.pos > 0 && it->second.neg > 0) { @@ -1018,7 +1021,7 @@ Node RewriteRule<FlattenAssocCommutNoDuplicates>::apply(TNode node) { Debug("bv-rewrite") << "RewriteRule<FlattenAssocCommut>(" << node << ")" << std::endl; std::vector<Node> processingStack; processingStack.push_back(node); - __gnu_cxx::hash_set<TNode, TNodeHashFunction> processed; + std::unordered_set<TNode, TNodeHashFunction> processed; std::vector<Node> children; Kind kind = node.getKind(); @@ -1053,7 +1056,7 @@ Node RewriteRule<OrSimplify>::apply(TNode node) { Debug("bv-rewrite") << "RewriteRule<OrSimplify>(" << node << ")" << std::endl; // this will remove duplicates - std::hash_map<TNode, Count, TNodeHashFunction> subterms; + std::unordered_map<TNode, Count, TNodeHashFunction> subterms; unsigned size = utils::getSize(node); BitVector constant(size, (unsigned)0); @@ -1082,7 +1085,7 @@ Node RewriteRule<OrSimplify>::apply(TNode node) { children.push_back(utils::mkConst(constant)); } - std::hash_map<TNode, Count, TNodeHashFunction>::const_iterator it = subterms.begin(); + std::unordered_map<TNode, Count, TNodeHashFunction>::const_iterator it = subterms.begin(); for (; it != subterms.end(); ++it) { if (it->second.pos > 0 && it->second.neg > 0) { @@ -1116,7 +1119,7 @@ Node RewriteRule<XorSimplify>::apply(TNode node) { Debug("bv-rewrite") << "RewriteRule<XorSimplify>(" << node << ")" << std::endl; - std::hash_map<TNode, Count, TNodeHashFunction> subterms; + std::unordered_map<TNode, Count, TNodeHashFunction> subterms; unsigned size = utils::getSize(node); BitVector constant; bool const_set = false; @@ -1144,7 +1147,7 @@ Node RewriteRule<XorSimplify>::apply(TNode node) { std::vector<Node> children; - std::hash_map<TNode, Count, TNodeHashFunction>::const_iterator it = subterms.begin(); + std::unordered_map<TNode, Count, TNodeHashFunction>::const_iterator it = subterms.begin(); unsigned true_count = 0; bool seen_false = false; for (; it != subterms.end(); ++it) { diff --git a/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h b/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h index 052bc8c1a..f73c4fb0f 100644 --- a/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h +++ b/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Clark Barrett, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/theory_bv_rewrite_rules_simplification.h b/src/theory/bv/theory_bv_rewrite_rules_simplification.h index c49319387..c7247f260 100644 --- a/src/theory/bv/theory_bv_rewrite_rules_simplification.h +++ b/src/theory/bv/theory_bv_rewrite_rules_simplification.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Clark Barrett, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/theory_bv_rewriter.cpp b/src/theory/bv/theory_bv_rewriter.cpp index df21093c1..a96777954 100644 --- a/src/theory/bv/theory_bv_rewriter.cpp +++ b/src/theory/bv/theory_bv_rewriter.cpp @@ -2,9 +2,9 @@ /*! \file theory_bv_rewriter.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Morgan Deters, Clark Barrett + ** Liana Hadarean, Clark Barrett, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/theory_bv_rewriter.h b/src/theory/bv/theory_bv_rewriter.h index 8c3a20661..4fe4f4708 100644 --- a/src/theory/bv/theory_bv_rewriter.h +++ b/src/theory/bv/theory_bv_rewriter.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Morgan Deters, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/theory_bv_type_rules.h b/src/theory/bv/theory_bv_type_rules.h index 1c59ff8b1..957d15ec4 100644 --- a/src/theory/bv/theory_bv_type_rules.h +++ b/src/theory/bv/theory_bv_type_rules.h @@ -2,9 +2,9 @@ /*! \file theory_bv_type_rules.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Liana Hadarean + ** Tim King, Dejan Jovanovic, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/theory_bv_utils.cpp b/src/theory/bv/theory_bv_utils.cpp index f743e2d64..6697f9060 100644 --- a/src/theory/bv/theory_bv_utils.cpp +++ b/src/theory/bv/theory_bv_utils.cpp @@ -2,9 +2,9 @@ /*! \file theory_bv_utils.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King + ** Liana Hadarean, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/bv/theory_bv_utils.h b/src/theory/bv/theory_bv_utils.h index 1210e8495..8b8d5e003 100644 --- a/src/theory/bv/theory_bv_utils.h +++ b/src/theory/bv/theory_bv_utils.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Dejan Jovanovic, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,19 +17,22 @@ #include "cvc4_private.h" -#pragma once +#pragma once #include <set> -#include <vector> #include <sstream> +#include <unordered_map> +#include <unordered_set> +#include <vector> + #include "expr/node_manager.h" namespace CVC4 { namespace theory { namespace bv { -typedef __gnu_cxx::hash_set<Node, NodeHashFunction> NodeSet; -typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet; +typedef std::unordered_set<Node, NodeHashFunction> NodeSet; +typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; namespace utils { @@ -505,11 +508,11 @@ inline T gcd(T a, T b) { return a; } -typedef __gnu_cxx::hash_map<TNode, bool, TNodeHashFunction> TNodeBoolMap; +typedef std::unordered_map<TNode, bool, TNodeHashFunction> TNodeBoolMap; bool isCoreTerm(TNode term, TNodeBoolMap& cache); bool isEqualityTerm(TNode term, TNodeBoolMap& cache); -typedef __gnu_cxx::hash_set<Node, NodeHashFunction> NodeSet; +typedef std::unordered_set<Node, NodeHashFunction> NodeSet; uint64_t numNodes(TNode node, NodeSet& seen); diff --git a/src/theory/bv/type_enumerator.h b/src/theory/bv/type_enumerator.h index 3c984def8..ad18f901c 100644 --- a/src/theory/bv/type_enumerator.h +++ b/src/theory/bv/type_enumerator.h @@ -2,9 +2,9 @@ /*! \file type_enumerator.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/datatypes/datatypes_rewriter.h b/src/theory/datatypes/datatypes_rewriter.h index 30cdf8893..025fe0349 100644 --- a/src/theory/datatypes/datatypes_rewriter.h +++ b/src/theory/datatypes/datatypes_rewriter.h @@ -2,9 +2,9 @@ /*! \file datatypes_rewriter.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tim King + ** Andrew Reynolds, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -112,18 +112,22 @@ public: // Have to be careful not to rewrite well-typed expressions // where the selector doesn't match the constructor, // e.g. "pred(zero)". + TypeNode tn = in.getType(); + TypeNode argType = in[0].getType(); TNode selector = in.getOperator(); TNode constructor = in[0].getOperator(); - Expr selectorExpr = selector.toExpr(); - Expr constructorExpr = constructor.toExpr(); - size_t selectorIndex = Datatype::indexOf(selectorExpr); - size_t constructorIndex = Datatype::indexOf(constructorExpr); - const Datatype& dt = Datatype::datatypeOf(selectorExpr); + size_t constructorIndex = Datatype::indexOf(constructor.toExpr()); + const Datatype& dt = Datatype::datatypeOf(selector.toExpr()); const DatatypeConstructor& c = dt[constructorIndex]; - if(c.getNumArgs() > selectorIndex && c[selectorIndex].getSelector() == selectorExpr) { + Trace("datatypes-rewrite-debug") << "Rewriting collapsable selector : " << in; + Trace("datatypes-rewrite-debug") << ", cindex = " << constructorIndex << ", selector is " << selector << std::endl; + int selectorIndex = c.getSelectorIndexInternal( selector.toExpr() ); + Trace("datatypes-rewrite-debug") << "Internal selector index is " << selectorIndex << std::endl; + if( selectorIndex>=0 ){ + Assert( selectorIndex<(int)c.getNumArgs() ); if( dt.isCodatatype() && in[0][selectorIndex].isConst() ){ //must replace all debruijn indices with self - Node sub = replaceDebruijn( in[0][selectorIndex], in[0], in[0].getType(), 0 ); + Node sub = replaceDebruijn( in[0][selectorIndex], in[0], argType, 0 ); Trace("datatypes-rewrite") << "DatatypesRewriter::postRewrite: " << "Rewrite trivial codatatype selector " << in << " to " << sub << std::endl; if( sub!=in ){ @@ -135,8 +139,6 @@ public: return RewriteResponse(REWRITE_DONE, in[0][selectorIndex]); } }else{ - //typically should not be called - TypeNode tn = in.getType(); Node gt; bool useTe = true; //if( !tn.isSort() ){ @@ -206,6 +208,11 @@ public: Trace("datatypes-rewrite") << "DatatypesRewriter::postRewrite: rewrite height " << in << " to " << res << std::endl; return RewriteResponse(REWRITE_AGAIN_FULL, res ); } + }else if( in.getKind()==kind::DT_SIZE_BOUND ){ + if( in[0].isConst() ){ + Node res = NodeManager::currentNM()->mkNode( kind::LEQ, NodeManager::currentNM()->mkNode( kind::DT_SIZE, in[0] ), in[1] ); + return RewriteResponse(REWRITE_AGAIN_FULL, res ); + } } if(in.getKind() == kind::EQUAL ) { @@ -271,22 +278,25 @@ public: Assert( index>=0 && index<(int)dt.getNumConstructors() ); std::vector< Node > children; children.push_back( Node::fromExpr( dt[index].getConstructor() ) ); - for( int i=0; i<(int)dt[index].getNumArgs(); i++ ){ - Node nc = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[index][i].getSelector() ), n ); + Type t = n.getType().toType(); + for( unsigned i=0; i<dt[index].getNumArgs(); i++ ){ + Node nc = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[index].getSelectorInternal( t, i ) ), n ); children.push_back( nc ); } Node n_ic = NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, children ); - //add type ascription for ambiguous constructor types - if(!n_ic.getType().isComparableTo(n.getType())) { - Assert( dt.isParametric() ); - Debug("datatypes-parametric") << "DtInstantiate: ambiguous type for " << n_ic << ", ascribe to " << n.getType() << std::endl; - Debug("datatypes-parametric") << "Constructor is " << dt[index] << std::endl; - Type tspec = dt[index].getSpecializedConstructorType(n.getType().toType()); - Debug("datatypes-parametric") << "Type specification is " << tspec << std::endl; - children[0] = NodeManager::currentNM()->mkNode(kind::APPLY_TYPE_ASCRIPTION, - NodeManager::currentNM()->mkConst(AscriptionType(tspec)), children[0] ); - n_ic = NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, children ); - Assert( n_ic.getType()==n.getType() ); + if( dt.isParametric() ){ + TypeNode tn = TypeNode::fromType( t ); + //add type ascription for ambiguous constructor types + if(!n_ic.getType().isComparableTo(tn)) { + Debug("datatypes-parametric") << "DtInstantiate: ambiguous type for " << n_ic << ", ascribe to " << n.getType() << std::endl; + Debug("datatypes-parametric") << "Constructor is " << dt[index] << std::endl; + Type tspec = dt[index].getSpecializedConstructorType(n.getType().toType()); + Debug("datatypes-parametric") << "Type specification is " << tspec << std::endl; + children[0] = NodeManager::currentNM()->mkNode(kind::APPLY_TYPE_ASCRIPTION, + NodeManager::currentNM()->mkConst(AscriptionType(tspec)), children[0] ); + n_ic = NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, children ); + Assert( n_ic.getType()==tn ); + } } Assert( isInstCons( n, n_ic, dt )==index ); //n_ic = Rewriter::rewrite( n_ic ); @@ -297,9 +307,10 @@ public: if( n.getKind()==kind::APPLY_CONSTRUCTOR ){ int index = Datatype::indexOf( n.getOperator().toExpr() ); const DatatypeConstructor& c = dt[index]; + Type nt = n.getType().toType(); for( unsigned i=0; i<n.getNumChildren(); i++ ){ if( n[i].getKind()!=kind::APPLY_SELECTOR_TOTAL || - n[i].getOperator()!=Node::fromExpr( c[i].getSelector() ) || + n[i].getOperator()!=Node::fromExpr( c.getSelectorInternal( nt, i ) ) || n[i][0]!=t ){ return -1; } @@ -610,7 +621,6 @@ public: return Node::null(); } } - static Node normalizeTupleConstructorApp( Node n ){ Assert( n.getType().isTuple() ); Assert( n.getKind()==kind::APPLY_CONSTRUCTOR ); @@ -634,7 +644,7 @@ public: return NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, ch ); } return n; - } + } //normalize constant : apply to top-level codatatype constants static Node normalizeConstant( Node n ){ TypeNode tn = n.getType(); diff --git a/src/theory/datatypes/datatypes_sygus.cpp b/src/theory/datatypes/datatypes_sygus.cpp index f5ae05bc3..0652ebe10 100644 --- a/src/theory/datatypes/datatypes_sygus.cpp +++ b/src/theory/datatypes/datatypes_sygus.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,7 +19,9 @@ #include "options/quantifiers_options.h" #include "theory/datatypes/datatypes_rewriter.h" #include "theory/datatypes/datatypes_sygus.h" -#include "theory/quantifiers/term_database.h" +#include "theory/quantifiers/term_database_sygus.h" +#include "theory/datatypes/theory_datatypes.h" +#include "theory/theory_model.h" using namespace CVC4; using namespace CVC4::kind; @@ -27,370 +29,606 @@ using namespace CVC4::context; using namespace CVC4::theory; using namespace CVC4::theory::datatypes; -void SygusSplit::getSygusSplits( Node n, const Datatype& dt, std::vector< Node >& splits, std::vector< Node >& lemmas ) { +Node SygusSplitNew::getSygusSplit( quantifiers::TermDbSygus * tds, Node n, const Datatype& dt ) { + TypeNode tnn = n.getType(); + tds->registerSygusType( tnn ); + std::vector< Node > curr_splits; + for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ + Trace("sygus-split-debug2") << "Add split " << n << " : constructor " << dt[i].getName() << " : "; + if( !tds->isGenericRedundant( tnn, i ) ){ + std::vector< Node > test_c; + test_c.push_back( DatatypesRewriter::mkTester( n, i, dt ) ); + Node test = test_c.size()==1 ? test_c[0] : NodeManager::currentNM()->mkNode( AND, test_c ); + curr_splits.push_back( test ); + Trace("sygus-split-debug2") << "SUCCESS" << std::endl; + Trace("sygus-split-debug") << "Disjunct #" << curr_splits.size() << " : " << test << std::endl; + }else{ + Trace("sygus-split-debug2") << "redundant operator" << std::endl; + } + } + Assert( !curr_splits.empty() ); + return curr_splits.size()==1 ? curr_splits[0] : NodeManager::currentNM()->mkNode( OR, curr_splits ); + +} + +void SygusSplitNew::getSygusSplits( Node n, const Datatype& dt, std::vector< Node >& splits, std::vector< Node >& lemmas ) { Assert( dt.isSygus() ); if( d_splits.find( n )==d_splits.end() ){ Trace("sygus-split") << "Get sygus splits " << n << std::endl; - //get the kinds for child datatype - TypeNode tnn = n.getType(); - registerSygusType( tnn ); + Node split = getSygusSplit( d_tds, n, dt ); + Assert( !split.isNull() ); + d_splits[n].push_back( split ); + } + //copy to splits + splits.insert( splits.end(), d_splits[n].begin(), d_splits[n].end() ); +} + - //get parent information, if possible - int csIndex = -1; - int sIndex = -1; - Node arg1; - TypeNode tn1; - TypeNode tnnp; - Node ptest; - if( n.getKind()==APPLY_SELECTOR_TOTAL ){ - Node op = n.getOperator(); - Expr selectorExpr = op.toExpr(); - const Datatype& pdt = Datatype::datatypeOf(selectorExpr); - Assert( pdt.isSygus() ); - csIndex = Datatype::cindexOf(selectorExpr); - sIndex = Datatype::indexOf(selectorExpr); - tnnp = n[0].getType(); - //register the constructors that are redundant children of argument sIndex of constructor index csIndex of dt - registerSygusTypeConstructorArg( tnn, dt, tnnp, pdt, csIndex, sIndex ); +SygusSymBreakNew::SygusSymBreakNew( TheoryDatatypes * td, quantifiers::TermDbSygus * tds, context::Context* c ) : +d_td( td ), d_tds( tds ), d_context( c ), +d_testers( c ), d_is_const( c ), d_testers_exp( c ), d_active_terms( c ), d_currTermSize( c ) { + d_zero = NodeManager::currentNM()->mkConst( Rational(0) ); +} - if( options::sygusNormalFormArg() ){ - if( sIndex==1 && pdt[csIndex].getNumArgs()==2 ){ - arg1 = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( pdt[csIndex][0].getSelector() ), n[0] ); - tn1 = arg1.getType(); - if( !tn1.isDatatype() ){ - arg1 = Node::null(); +SygusSymBreakNew::~SygusSymBreakNew() { + for( std::map< Node, SearchSizeInfo * >::iterator it = d_szinfo.begin(); it != d_szinfo.end(); ++it ){ + delete it->second; + } +} + +/** add tester */ +void SygusSymBreakNew::assertTester( int tindex, TNode n, Node exp, std::vector< Node >& lemmas ) { + registerTerm( n, lemmas ); + // check if this is a relevant (sygus) term + if( d_term_to_anchor.find( n )!=d_term_to_anchor.end() ){ + Trace("sygus-sb-debug2") << "Sygus : process tester : " << exp << std::endl; + // if not already active (may have duplicate calls for the same tester) + if( d_active_terms.find( n )==d_active_terms.end() ) { + d_testers[n] = tindex; + d_testers_exp[n] = exp; + + // check if parent is active + bool do_add = true; + if( options::sygusSymBreakLazy() ){ + if( n.getKind()==kind::APPLY_SELECTOR_TOTAL ){ + NodeSet::const_iterator it = d_active_terms.find( n[0] ); + if( it==d_active_terms.end() ){ + do_add = false; + }else{ + //this must be a proper selector + IntMap::const_iterator itt = d_testers.find( n[0] ); + Assert( itt!=d_testers.end() ); + int ptindex = (*itt).second; + TypeNode ptn = n[0].getType(); + const Datatype& pdt = ((DatatypeType)ptn.toType()).getDatatype(); + int sindex_in_parent = pdt[ptindex].getSelectorIndexInternal( n.getOperator().toExpr() ); + // the tester is irrelevant in this branch + if( sindex_in_parent==-1 ){ + do_add = false; + } } } } - // we are splitting on a term that may later have no semantics : guard this case - ptest = DatatypesRewriter::mkTester( n[0], csIndex, pdt ); - Trace("sygus-split-debug") << "Parent guard : " << ptest << std::endl; + if( do_add ){ + assertTesterInternal( tindex, n, exp, lemmas ); + }else{ + Trace("sygus-sb-debug2") << "...ignore inactive tester : " << exp << std::endl; + } + }else{ + Trace("sygus-sb-debug2") << "...ignore repeated tester : " << exp << std::endl; } + }else{ + Trace("sygus-sb-debug2") << "...ignore non-sygus tester : " << exp << std::endl; + } +} - std::vector< Node > ptest_c; - bool narrow = false; - for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ - Trace("sygus-split-debug2") << "Add split " << n << " : constructor " << dt[i].getName() << " : "; - Assert( d_sygus_nred.find( tnn )!=d_sygus_nred.end() ); - bool addSplit = d_sygus_nred[tnn][i]; - if( addSplit ){ - if( csIndex!=-1 ){ - Assert( d_sygus_pc_nred[tnn][csIndex].find( sIndex )!=d_sygus_pc_nred[tnn][csIndex].end() ); - addSplit = d_sygus_pc_nred[tnn][csIndex][sIndex][i]; +void SygusSymBreakNew::assertFact( Node n, bool polarity, std::vector< Node >& lemmas ) { + if( n.getKind()==kind::DT_SYGUS_TERM_ORDER ){ + if( polarity ){ + Trace("sygus-sb-torder") << "Sygus term order : " << n[0] << " < " << n[1] << std::endl; + Node comm_sb = getTermOrderPredicate( n[0], n[1] ); + Node comm_lem = NodeManager::currentNM()->mkNode( kind::OR, n.negate(), comm_sb ); + lemmas.push_back( comm_lem ); + } + }else if( n.getKind()==kind::DT_SYGUS_BOUND ){ + Node m = n[0]; + Trace("sygus-fair") << "Have sygus bound : " << n << ", polarity=" << polarity << " on measure " << m << std::endl; + registerMeasureTerm( m ); + if( options::sygusFair()==SYGUS_FAIR_DT_SIZE ){ + std::map< Node, SearchSizeInfo * >::iterator its = d_szinfo.find( m ); + Assert( its!=d_szinfo.end() ); + Node mt = its->second->getOrMkSygusMeasureTerm( lemmas ); + //it relates the measure term to arithmetic + Node blem = n.eqNode( NodeManager::currentNM()->mkNode( kind::LEQ, mt, n[1] ) ); + lemmas.push_back( blem ); + } + if( polarity ){ + unsigned s = n[1].getConst<Rational>().getNumerator().toUnsignedInt(); + notifySearchSize( m, s, n, lemmas ); + } + }else if( n.getKind() == kind::DT_SYGUS_IS_CONST ){ + assertIsConst( n[0], polarity, lemmas ); + }else if( n.getKind() == kind::DT_HEIGHT_BOUND || n.getKind()==DT_SIZE_BOUND ){ + //reduce to arithmetic TODO ? + + } +} + +void SygusSymBreakNew::assertIsConst( Node n, bool polarity, std::vector< Node >& lemmas ) { + if( d_active_terms.find( n )!=d_active_terms.end() ) { + // what kind of constructor is n? + IntMap::const_iterator itt = d_testers.find( n ); + Assert( itt!=d_testers.end() ); + int tindex = (*itt).second; + TypeNode tn = n.getType(); + const Datatype& dt = ((DatatypeType)tn.toType()).getDatatype(); + Node lem; + if( dt[tindex].getNumArgs()==0 ){ + // is this a constant? + Node sygus_op = Node::fromExpr( dt[tindex].getSygusOp() ); + if( sygus_op.isConst()!=polarity ){ + lem = NodeManager::currentNM()->mkNode( kind::DT_SYGUS_IS_CONST, n ); + if( polarity ){ + lem.negate(); } - if( addSplit ){ - std::vector< Node > test_c; - Node test = DatatypesRewriter::mkTester( n, i, dt ); - test_c.push_back( test ); - //check if we can strengthen the first argument - if( !arg1.isNull() ){ - const Datatype& dt1 = ((DatatypeType)(tn1).toType()).getDatatype(); - Kind k = d_tds->getArgKind( tnnp, csIndex ); - //size comparison for arguments (if necessary) - Node sz_leq; - if( tn1==tnn && quantifiers::TermDb::isComm( k ) ){ - sz_leq = NodeManager::currentNM()->mkNode( LEQ, NodeManager::currentNM()->mkNode( DT_SIZE, n ), NodeManager::currentNM()->mkNode( DT_SIZE, arg1 ) ); - } - std::map< int, std::vector< int > >::iterator it = d_sygus_pc_arg_pos[tnn][csIndex].find( i ); - if( it!=d_sygus_pc_arg_pos[tnn][csIndex].end() ){ - Assert( !it->second.empty() ); - std::vector< Node > lem_c; - for( unsigned j=0; j<it->second.size(); j++ ){ - Node tt = DatatypesRewriter::mkTester( arg1, it->second[j], dt1 ); - //if commutative operator, and children have same constructor type, then first arg is larger than second arg - if( it->second[j]==(int)i && !sz_leq.isNull() ){ - tt = NodeManager::currentNM()->mkNode( AND, tt, sz_leq ); - } - lem_c.push_back( tt ); - } - Node argStr = lem_c.size()==1 ? lem_c[0] : NodeManager::currentNM()->mkNode( OR, lem_c ); - Trace("sygus-str") << "...strengthen corresponding first argument of " << test << " : " << argStr << std::endl; - test_c.push_back( argStr ); - narrow = true; - }else{ - if( !sz_leq.isNull() ){ - test_c.push_back( NodeManager::currentNM()->mkNode( OR, DatatypesRewriter::mkTester( arg1, i, dt1 ).negate(), sz_leq ) ); - narrow = true; - } - } - } - //other constraints on arguments - Kind curr = d_tds->getArgKind( tnn, i ); - if( curr!=UNDEFINED_KIND ){ - //ITE children must be distinct when properly typed - if( curr==ITE ){ - if( d_tds->getArgType( dt[i], 1 )==tnn && d_tds->getArgType( dt[i], 2 )==tnn ){ - Node arg_ite1 = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[i][1].getSelector() ), n ); - Node arg_ite2 = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[i][2].getSelector() ), n ); - Node deq = arg_ite1.eqNode( arg_ite2 ).negate(); - Trace("sygus-str") << "...ite strengthen arguments " << deq << std::endl; - test_c.push_back( deq ); - narrow = true; - } - //condition must be distinct from all parent ITE's - Node curr = n; - Node arg_itec = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[i][0].getSelector() ), n ); - while( curr.getKind()==APPLY_SELECTOR_TOTAL ){ - if( curr[0].getType()==tnn ){ - int sIndexCurr = Datatype::indexOf( curr.getOperator().toExpr() ); - int csIndexCurr = Datatype::cindexOf( curr.getOperator().toExpr() ); - if( sIndexCurr!=0 && csIndexCurr==(int)i ){ - Trace("sygus-ite") << "Parent ITE " << curr << " of " << n << std::endl; - Node arg_itecp = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[i][0].getSelector() ), curr[0] ); - Node deq = arg_itec.eqNode( arg_itecp ).negate(); - Trace("sygus-str") << "...ite strengthen condition " << deq << std::endl; - test_c.push_back( deq ); - narrow = true; - } - } - curr = curr[0]; - } - } - } - //add fairness constraint - if( options::ceGuidedInstFair()==quantifiers::CEGQI_FAIR_DT_SIZE ){ - Node szl = NodeManager::currentNM()->mkNode( DT_SIZE, n ); - Node szr = NodeManager::currentNM()->mkNode( DT_SIZE, DatatypesRewriter::getInstCons( n, dt, i ) ); - szr = Rewriter::rewrite( szr ); - test_c.push_back( szl.eqNode( szr ) ); + } + }else{ + // reduce + std::vector< Node > child_conj; + for( unsigned j=0; j<dt[tindex].getNumArgs(); j++ ){ + Node sel = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[tindex].getSelectorInternal( tn.toType(), j ) ), n ); + child_conj.push_back( NodeManager::currentNM()->mkNode( kind::DT_SYGUS_IS_CONST, sel ) ); + } + lem = child_conj.size()==1 ? child_conj[0] : NodeManager::currentNM()->mkNode( kind::AND, child_conj ); + // only an implication (TODO : strengthen?) + lem = NodeManager::currentNM()->mkNode( kind::OR, lem.negate(), NodeManager::currentNM()->mkNode( kind::DT_SYGUS_IS_CONST, n ) ); + } + if( !lem.isNull() ){ + Trace("sygus-isc") << "Sygus is-const lemma : " << lem << std::endl; + Node rlv = getRelevancyCondition( n ); + if( !rlv.isNull() ){ + lem = NodeManager::currentNM()->mkNode( kind::OR, rlv.negate(), lem ); + } + lemmas.push_back( lem ); + } + }else{ + // lazy + d_is_const[n] = polarity ? 1 : -1; + } +} + +Node SygusSymBreakNew::getTermOrderPredicate( Node n1, Node n2 ) { + std::vector< Node > comm_disj; + // (1) size of left is greater than size of right + Node sz_less = NodeManager::currentNM()->mkNode( GT, NodeManager::currentNM()->mkNode( DT_SIZE, n1 ), + NodeManager::currentNM()->mkNode( DT_SIZE, n2 ) ); + comm_disj.push_back( sz_less ); + // (2) ...or sizes are equal and first child is less by term order + std::vector< Node > sz_eq_cases; + Node sz_eq = NodeManager::currentNM()->mkNode( EQUAL, NodeManager::currentNM()->mkNode( DT_SIZE, n1 ), + NodeManager::currentNM()->mkNode( DT_SIZE, n2 ) ); + sz_eq_cases.push_back( sz_eq ); + if( options::sygusOpt1() ){ + TypeNode tnc = n1.getType(); + const Datatype& cdt = ((DatatypeType)(tnc).toType()).getDatatype(); + for( unsigned j=0; j<cdt.getNumConstructors(); j++ ){ + if( !d_tds->isGenericRedundant( tnc, j ) ){ + std::vector< Node > case_conj; + for( unsigned k=0; k<j; k++ ){ + if( !d_tds->isGenericRedundant( tnc, k ) ){ + case_conj.push_back( DatatypesRewriter::mkTester( n2, k, cdt ).negate() ); } - test = test_c.size()==1 ? test_c[0] : NodeManager::currentNM()->mkNode( AND, test_c ); - d_splits[n].push_back( test ); - Trace("sygus-split-debug2") << "SUCCESS" << std::endl; - Trace("sygus-split-debug") << "Disjunct #" << d_splits[n].size() << " : " << test << std::endl; - }else{ - Trace("sygus-split-debug2") << "redundant argument" << std::endl; - narrow = true; } - }else{ - Trace("sygus-split-debug2") << "redundant operator" << std::endl; - narrow = true; - } - if( !ptest.isNull() ){ - ptest_c.push_back( DatatypesRewriter::mkTester( n, i, dt ) ); + if( !case_conj.empty() ){ + Node corder = NodeManager::currentNM()->mkNode( kind::OR, DatatypesRewriter::mkTester( n1, j, cdt ).negate(), + case_conj.size()==1 ? case_conj[0] : NodeManager::currentNM()->mkNode( kind::AND, case_conj ) ); + sz_eq_cases.push_back( corder ); + } } } - if( narrow && !ptest.isNull() ){ - Node split = d_splits[n].empty() ? NodeManager::currentNM()->mkConst( false ) : - ( d_splits[n].size()==1 ? d_splits[n][0] : NodeManager::currentNM()->mkNode( OR, d_splits[n] ) ); - if( !d_splits[n].empty() ){ - d_splits[n].clear(); - split = NodeManager::currentNM()->mkNode( AND, ptest, split ); + } + Node sz_eqc = sz_eq_cases.size()==1 ? sz_eq_cases[0] : NodeManager::currentNM()->mkNode( kind::AND, sz_eq_cases ); + comm_disj.push_back( sz_eqc ); + + return NodeManager::currentNM()->mkNode( kind::OR, comm_disj ); +} + +void SygusSymBreakNew::registerTerm( Node n, std::vector< Node >& lemmas ) { + if( d_is_top_level.find( n )==d_is_top_level.end() ){ + d_is_top_level[n] = false; + TypeNode tn = n.getType(); + unsigned d = 0; + bool is_top_level = false; + bool success = false; + if( n.getKind()==kind::APPLY_SELECTOR_TOTAL ){ + registerTerm( n[0], lemmas ); + std::map< Node, Node >::iterator it = d_term_to_anchor.find( n[0] ); + if( it!=d_term_to_anchor.end() ) { + d_term_to_anchor[n] = it->second; + d_term_to_anchor_root[n] = d_term_to_anchor_root[n[0]]; + d = d_term_to_depth[n[0]] + 1; + is_top_level = computeTopLevel( tn, n[0] ); + success = true; } - d_splits[n].push_back( split ); - if( !ptest_c.empty() ){ - ptest = NodeManager::currentNM()->mkNode( AND, ptest.negate(), NodeManager::currentNM()->mkNode( OR, ptest_c ) ); + }else if( n.isVar() ){ + registerSizeTerm( n, lemmas ); + if( d_register_st[n] ){ + d_term_to_anchor[n] = n; + d_term_to_anchor_root[n] = d_tds->isMeasuredTerm( n ); + // this assertion fails if we have a sygus term in the search that is unmeasured + Assert( !d_term_to_anchor_root[n].isNull() ); + d = 0; + is_top_level = true; + success = true; } - d_splits[n].push_back( ptest ); + } + if( success ){ + Trace("sygus-sb-debug") << "Register : " << n << ", depth : " << d << ", top level = " << is_top_level << ", type = " << ((DatatypeType)tn.toType()).getDatatype().getName() << std::endl; + d_term_to_depth[n] = d; + d_is_top_level[n] = is_top_level; + registerSearchTerm( tn, d, n, is_top_level, lemmas ); }else{ - Assert( !d_splits[n].empty() ); + Trace("sygus-sb-debug2") << "Term " << n << " is not part of sygus search." << std::endl; } + } +} +bool SygusSymBreakNew::computeTopLevel( TypeNode tn, Node n ){ + if( n.getType()==tn ){ + return false; + }else if( n.getKind()==kind::APPLY_SELECTOR_TOTAL ){ + return computeTopLevel( tn, n[0] ); + }else{ + return true; } - //copy to splits - splits.insert( splits.end(), d_splits[n].begin(), d_splits[n].end() ); } -void SygusSplit::registerSygusType( TypeNode tn ) { - if( d_register.find( tn )==d_register.end() ){ - if( !tn.isDatatype() ){ - d_register[tn] = TypeNode::null(); - }else{ - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - Trace("sygus-split") << "Register type " << dt.getName() << "..." << std::endl; - d_register[tn] = TypeNode::fromType( dt.getSygusType() ); - if( d_register[tn].isNull() ){ - Trace("sygus-split") << "...not sygus." << std::endl; - }else{ - d_tds->registerSygusType( tn ); +void SygusSymBreakNew::assertTesterInternal( int tindex, TNode n, Node exp, std::vector< Node >& lemmas ) { + d_active_terms.insert( n ); + Trace("sygus-sb-debug2") << "Sygus : activate term : " << n << " : " << exp << std::endl; + + /* TODO + IntMap::const_iterator itisc = d_is_const.find( n ); + if( itisc != d_is_const.end() ){ + assertIsConst( n, (*itisc).second==1, lemmas ); + } + */ + + TypeNode ntn = n.getType(); + const Datatype& dt = ((DatatypeType)ntn.toType()).getDatatype(); + + // get the search size for this + Assert( d_term_to_anchor.find( n )!=d_term_to_anchor.end() ); + Node a = d_term_to_anchor[n]; + Assert( d_anchor_to_measure_term.find( a )!=d_anchor_to_measure_term.end() ); + Node m = d_anchor_to_measure_term[a]; + std::map< Node, SearchSizeInfo * >::iterator itsz = d_szinfo.find( m ); + Assert( itsz!=d_szinfo.end() ); + unsigned ssz = itsz->second->d_curr_search_size; + + if( options::sygusFair()==SYGUS_FAIR_DIRECT ){ + if( dt[tindex].getNumArgs()>0 ){ + // consider lower bounds for size of types + unsigned lb_add = d_tds->getMinConsTermSize( ntn, tindex ); + unsigned lb_rem = n==a ? 0 : d_tds->getMinTermSize( ntn ); + Assert( lb_add>=lb_rem ); + d_currTermSize[a].set( d_currTermSize[a].get() + ( lb_add - lb_rem ) ); + } + if( (unsigned)d_currTermSize[a].get()>ssz ){ + if( Trace.isOn("sygus-sb-fair") ){ + std::map< TypeNode, int > var_count; + Node templ = getCurrentTemplate( a, var_count ); + Trace("sygus-sb-fair") << "FAIRNESS : we have " << d_currTermSize[a].get() << " at search size " << ssz << ", template is " << templ << std::endl; + } + // conflict + std::vector< Node > conflict; + for( NodeSet::const_iterator its = d_active_terms.begin(); its != d_active_terms.end(); ++its ){ + Node x = *its; + Node xa = d_term_to_anchor[x]; + if( xa==a ){ + IntMap::const_iterator ittv = d_testers.find( x ); + Assert( ittv != d_testers.end() ); + int tindex = (*ittv).second; + const Datatype& dti = ((DatatypeType)x.getType().toType()).getDatatype(); + if( dti[tindex].getNumArgs()>0 ){ + NodeMap::const_iterator itt = d_testers_exp.find( x ); + Assert( itt != d_testers_exp.end() ); + conflict.push_back( (*itt).second ); + } + } + } + Assert( conflict.size()==(unsigned)d_currTermSize[a].get() ); + Assert( itsz->second->d_search_size_exp.find( ssz )!=itsz->second->d_search_size_exp.end() ); + conflict.push_back( itsz->second->d_search_size_exp[ssz] ); + Node conf = NodeManager::currentNM()->mkNode( kind::AND, conflict ); + Trace("sygus-sb-fair") << "Conflict is : " << conf << std::endl; + lemmas.push_back( conf.negate() ); + return; + } + } + + // now, add all applicable symmetry breaking lemmas for this term + Assert( d_term_to_depth.find( n )!=d_term_to_depth.end() ); + unsigned d = d_term_to_depth[n]; + Trace("sygus-sb-fair-debug") << "Tester " << exp << " is for depth " << d << " term in search size " << ssz << std::endl; + //Assert( d<=ssz ); + if( options::sygusSymBreakLazy() ){ + addSymBreakLemmasFor( ntn, n, d, lemmas ); + } + + // process simple symmetry breaking + unsigned max_depth = ssz>=d ? ssz-d : 0; + unsigned min_depth = d_simple_proc[exp]; + if( min_depth<=max_depth ){ + TNode x = getFreeVar( ntn ); + Node rlv = getRelevancyCondition( n ); + for( unsigned d=0; d<=max_depth; d++ ){ + Node simple_sb_pred = getSimpleSymBreakPred( ntn, tindex, d ); + if( !simple_sb_pred.isNull() ){ + simple_sb_pred = simple_sb_pred.substitute( x, n ); + if( !rlv.isNull() ){ + simple_sb_pred = NodeManager::currentNM()->mkNode( kind::OR, rlv.negate(), simple_sb_pred ); + } + lemmas.push_back( simple_sb_pred ); + } + } + } + d_simple_proc[exp] = max_depth + 1; + + // add back testers for the children if they exist + if( options::sygusSymBreakLazy() ){ + for( unsigned j=0; j<dt[tindex].getNumArgs(); j++ ){ + Node sel = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[tindex].getSelectorInternal( ntn.toType(), j ) ), n ); + Trace("sygus-sb-debug2") << " activate child sel : " << sel << std::endl; + Assert( d_active_terms.find( sel )==d_active_terms.end() ); + IntMap::const_iterator itt = d_testers.find( sel ); + if( itt != d_testers.end() ){ + Assert( d_testers_exp.find( sel ) != d_testers_exp.end() ); + assertTesterInternal( (*itt).second, sel, d_testers_exp[sel], lemmas ); + } + } + } +} - //compute the redundant operators +Node SygusSymBreakNew::getRelevancyCondition( Node n ) { + std::map< Node, Node >::iterator itr = d_rlv_cond.find( n ); + if( itr==d_rlv_cond.end() ){ + Node cond; + if( n.getKind()==APPLY_SELECTOR_TOTAL && options::sygusSymBreakRlv() ){ + TypeNode ntn = n[0].getType(); + Type nt = ntn.toType(); + const Datatype& dt = ((DatatypeType)nt).getDatatype(); + Expr selExpr = n.getOperator().toExpr(); + if( options::dtSharedSelectors() ){ + std::vector< Node > disj; + bool excl = false; for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ - bool nred = true; - if( options::sygusNormalForm() ){ - Trace("sygus-split-debug") << "Is " << dt[i].getName() << " a redundant operator?" << std::endl; - Kind ck = d_tds->getArgKind( tn, i ); - if( ck!=UNDEFINED_KIND ){ - Kind dk; - if( d_tds->isAntisymmetric( ck, dk ) ){ - int j = d_tds->getKindArg( tn, dk ); - if( j!=-1 ){ - Trace("sygus-split-debug") << "Possible redundant operator : " << ck << " with " << dk << std::endl; - //check for type mismatches - bool success = true; - for( unsigned k=0; k<2; k++ ){ - unsigned ko = k==0 ? 1 : 0; - TypeNode tni = TypeNode::fromType( ((SelectorType)dt[i][k].getType()).getRangeType() ); - TypeNode tnj = TypeNode::fromType( ((SelectorType)dt[j][ko].getType()).getRangeType() ); - if( tni!=tnj ){ - Trace("sygus-split-debug") << "Argument types " << tni << " and " << tnj << " are not equal." << std::endl; - success = false; - break; - } - } - if( success ){ - Trace("sygus-nf") << "* Sygus norm " << dt.getName() << " : do not consider any " << ck << " terms." << std::endl; - nred = false; - } - } - } - } - if( nred ){ - Trace("sygus-split-debug") << "Check " << dt[i].getName() << " based on generic rewriting" << std::endl; - std::map< TypeNode, int > var_count; - std::map< int, Node > pre; - Node g = d_tds->mkGeneric( dt, i, var_count, pre ); - nred = !isGenericRedundant( tn, g ); - Trace("sygus-split-debug") << "...done check " << dt[i].getName() << " based on generic rewriting" << std::endl; + if( !d_tds->isGenericRedundant( ntn, i ) ){ + int sindexi = dt[i].getSelectorIndexInternal( selExpr ); + if( sindexi!=-1 ){ + disj.push_back( DatatypesRewriter::mkTester( n[0], i, dt ) ); + }else{ + excl = true; } } - d_sygus_nred[tn].push_back( nred ); } + Assert( !disj.empty() ); + if( excl ){ + cond = disj.size()==1 ? disj[0] : NodeManager::currentNM()->mkNode( kind::OR, disj ); + } + }else{ + int sindex = Datatype::cindexOf( selExpr ); + Assert( sindex!=-1 ); + cond = DatatypesRewriter::mkTester( n[0], sindex, dt ); + } + Node c1 = getRelevancyCondition( n[0] ); + if( cond.isNull() ){ + cond = c1; + }else if( !c1.isNull() ){ + cond = NodeManager::currentNM()->mkNode( kind::AND, cond, c1 ); } - Trace("sygus-split-debug") << "...done register type " << dt.getName() << std::endl; } + Trace("sygus-sb-debug2") << "Relevancy condition for " << n << " is " << cond << std::endl; + d_rlv_cond[n] = cond; + return cond; + }else{ + return itr->second; } } -void SygusSplit::registerSygusTypeConstructorArg( TypeNode tnn, const Datatype& dt, TypeNode tnnp, const Datatype& pdt, int csIndex, int sIndex ) { - std::map< int, std::vector< bool > >::iterator it = d_sygus_pc_nred[tnn][csIndex].find( sIndex ); - if( it==d_sygus_pc_nred[tnn][csIndex].end() ){ - d_sygus_pc_nred[tnn][csIndex][sIndex].clear(); - registerSygusType( tnn ); - registerSygusType( tnnp ); - Trace("sygus-split") << "Register type constructor arg " << dt.getName() << " " << csIndex << " " << sIndex << std::endl; - if( !options::sygusNormalForm() ){ - for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ - d_sygus_pc_nred[tnn][csIndex][sIndex].push_back( true ); +Node SygusSymBreakNew::getSimpleSymBreakPred( TypeNode tn, int tindex, unsigned depth ) { + std::map< unsigned, Node >::iterator it = d_simple_sb_pred[tn][tindex].find( depth ); + if( it==d_simple_sb_pred[tn][tindex].end() ){ + Node n = getFreeVar( tn ); + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + Assert( tindex>=0 && tindex<(int)dt.getNumConstructors() ); + //conjunctive conclusion of lemma + std::vector< Node > sbp_conj; + + if( depth==0 ){ + //fairness + if( options::sygusFair()==SYGUS_FAIR_DT_SIZE ){ + Node szl = NodeManager::currentNM()->mkNode( DT_SIZE, n ); + Node szr = NodeManager::currentNM()->mkNode( DT_SIZE, DatatypesRewriter::getInstCons( n, dt, tindex ) ); + szr = Rewriter::rewrite( szr ); + sbp_conj.push_back( szl.eqNode( szr ) ); + //sbp_conj.push_back( NodeManager::currentNM()->mkNode( kind::GEQ, szl, NodeManager::currentNM()->mkConst( Rational(0) ) ) ); } - }else{ - // calculate which constructors we should consider based on normal form for terms - //get parent kind - Kind parentKind = d_tds->getArgKind( tnnp, csIndex ); - for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ - Assert( d_sygus_nred.find( tnn )!=d_sygus_nred.end() ); - bool addSplit = d_sygus_nred[tnn][i]; - if( addSplit && parentKind!=UNDEFINED_KIND ){ - Kind ak = d_tds->getArgKind( tnn, i ); - if( ak!=UNDEFINED_KIND ){ - addSplit = considerSygusSplitKind( dt, pdt, tnn, tnnp, ak, parentKind, sIndex ); - if( !addSplit ){ - Trace("sygus-nf") << "* Sygus norm " << pdt.getName() << " : do not consider " << dt.getName() << "::" << ak; - Trace("sygus-nf") << " as argument " << sIndex << " of " << parentKind << "." << std::endl; + } + + //symmetry breaking + Kind nk = d_tds->getConsNumKind( tn, tindex ); + if( options::sygusSymBreak() ){ + // if less than the maximum depth we consider + if( depth<2 ){ + //get children + std::vector< Node > children; + for( unsigned j=0; j<dt[tindex].getNumArgs(); j++ ){ + Node sel = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[tindex].getSelectorInternal( tn.toType(), j ) ), n ); + Assert( sel.getType().isDatatype() ); + Assert( ((DatatypeType)sel.getType().toType()).getDatatype().isSygus() ); + children.push_back( sel ); + d_tds->registerSygusType( sel.getType() ); + } + //builtin type + TypeNode tnb = TypeNode::fromType( dt.getSygusType() ); + + // direct solving for children + // for instance, we may want to insist that the LHS of MINUS is 0 + std::map< unsigned, unsigned > children_solved; + for( unsigned j=0; j<dt[tindex].getNumArgs(); j++ ){ + int i = d_tds->solveForArgument( tn, tindex, j ); + if( i>=0 ){ + children_solved[j] = i; + TypeNode ctn = children[j].getType(); + const Datatype& cdt = ((DatatypeType)(ctn).toType()).getDatatype(); + Assert( i<(int)cdt.getNumConstructors() ); + sbp_conj.push_back( DatatypesRewriter::mkTester( children[j], i, cdt ) ); + } + } + + // depth 1 symmetry breaking : talks about direct children + if( depth==1 ){ + if( nk!=UNDEFINED_KIND ){ + // commutative operators + if( quantifiers::TermDb::isComm( nk ) ){ + if( children.size()==2 ){ + if( children[0].getType()==children[1].getType() ){ + #if 0 + Node order_pred = NodeManager::currentNM()->mkNode( DT_SYGUS_TERM_ORDER, children[0], children[1] ); + sbp_conj.push_back( order_pred ); + Node child11 = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[tindex].getSelectorInternal( tn.toType(), 1 ) ), children[0] ); + Assert( child11.getType()==children[1].getType() ); + //chainable + if( children[0].getType()==tn ){ + Node order_pred_trans = NodeManager::currentNM()->mkNode( OR, DatatypesRewriter::mkTester( children[0], tindex, dt ).negate(), + NodeManager::currentNM()->mkNode( DT_SYGUS_TERM_ORDER, child11, children[1] ) ); + sbp_conj.push_back( order_pred_trans ); + } + #else + Node order_pred = getTermOrderPredicate( children[0], children[1] ); + sbp_conj.push_back( order_pred ); + #endif + } + } } - }else{ - Node ac = d_tds->getArgConst( tnn, i ); - if( !ac.isNull() ){ - addSplit = considerSygusSplitConst( dt, pdt, tnn, tnnp, ac, parentKind, sIndex ); - if( !addSplit ){ - Trace("sygus-nf") << "* Sygus norm " << pdt.getName() << " : do not consider constant " << dt.getName() << "::" << ac; - Trace("sygus-nf") << " as argument " << sIndex << " of " << parentKind << "." << std::endl; + // operators whose arguments are non-additive (e.g. should be different) + std::vector< unsigned > deq_child[2]; + if( children.size()==2 && children[0].getType()==tn ){ + bool argDeq = false; + if( quantifiers::TermDb::isNonAdditive( nk ) ){ + argDeq = true; + }else{ + //other cases of rewriting x k x -> x' + Node req_const; + if( nk==GT || nk==LT || nk==XOR || nk==MINUS || nk==BITVECTOR_SUB || nk==BITVECTOR_XOR || nk==BITVECTOR_UREM_TOTAL ){ + //must have the zero element + req_const = d_tds->getTypeValue( tnb, 0 ); + }else if( nk==EQUAL || nk==LEQ || nk==GEQ || nk==BITVECTOR_XNOR ){ + req_const = d_tds->getTypeMaxValue( tnb ); + } + // cannot do division since we have to consider when both are zero + if( !req_const.isNull() ){ + if( d_tds->hasConst( tn, req_const ) ){ + argDeq = true; + } + } + } + if( argDeq ){ + deq_child[0].push_back( 0 );deq_child[1].push_back( 1 ); } } - } - if( addSplit ){ - if( pdt[csIndex].getNumArgs()==1 ){ - //generic rewriting - std::map< int, Node > prec; - std::map< TypeNode, int > var_count; - Node gc = d_tds->mkGeneric( dt, i, var_count, prec ); - std::map< int, Node > pre; - pre[sIndex] = gc; - Node g = d_tds->mkGeneric( pdt, csIndex, var_count, pre ); - addSplit = !isGenericRedundant( tnnp, g ); + if( nk==ITE || nk==STRING_STRREPL ){ + deq_child[0].push_back( 1 );deq_child[1].push_back( 2 ); } + if( nk==STRING_STRREPL ){ + deq_child[0].push_back( 0 );deq_child[1].push_back( 1 ); + } + for( unsigned i=0; i<deq_child[0].size(); i++ ){ + unsigned c1 = deq_child[0][i]; + unsigned c2 = deq_child[1][i]; + if( children[c1].getType()==children[c2].getType() ){ + if( !children[c1].getType().getCardinality().isOne() ){ + sbp_conj.push_back( children[c1].eqNode( children[c2] ).negate() ); + } + } + } + /* - else{ - Trace("sygus-nf-temp") << "Check " << dt[i].getName() << " as argument " << sIndex << " under " << parentKind << std::endl; - std::map< int, Node > prec; - std::map< TypeNode, int > var_count; - Node gc = d_tds->mkGeneric( dt, i, var_count, prec ); - std::map< int, Node > pre; - pre[sIndex] = gc; - Node g = d_tds->mkGeneric( pdt, csIndex, var_count, pre ); - bool tmp = !isGenericRedundant( tnnp, g, false ); + // division by zero TODO ? + if( nk==DIVISION || nk==DIVISION_TOTAL || nk==INTS_DIVISION || nk==INTS_DIVISION_TOTAL || + nk==INTS_MODULUS || nk==INTS_MODULUS_TOTAL ){ + Assert( children.size()==2 ); + // do not consider non-constant denominators ? + sbp_conj.push_back( NodeManager::currentNM()->mkNode( kind::DT_SYGUS_IS_CONST, children[1] ) ); + // do not consider zero denominator + Node tzero = d_tds->getTypeValue( tnb, 0 ); + int zero_arg = d_tds->getConstConsNum( children[1].getType(), tzero ); + if( zero_arg!=-1 ){ + + }else{ + // semantic skolem for zero? + } + }else if( nk==BITVECTOR_UDIV_TOTAL || nk==BITVECTOR_UDIV || nk==BITVECTOR_SDIV || nk==BITVECTOR_UREM || nk==BITVECTOR_UREM_TOTAL ){ + } */ - } - } - d_sygus_pc_nred[tnn][csIndex][sIndex].push_back( addSplit ); - } - //compute argument relationships for 2-arg constructors - if( parentKind!=UNDEFINED_KIND && pdt[csIndex].getNumArgs()==2 ){ - int osIndex = sIndex==0 ? 1 : 0; - TypeNode tnno = d_tds->getArgType( pdt[csIndex], osIndex ); - if( tnno.isDatatype() ){ - const Datatype& dto = ((DatatypeType)(tnno).toType()).getDatatype(); - registerSygusTypeConstructorArg( tnno, dto, tnnp, pdt, csIndex, osIndex ); - //compute relationships when doing 0-arg - if( sIndex==0 ){ - Assert( d_sygus_pc_nred[tnn][csIndex].find( sIndex )!=d_sygus_pc_nred[tnn][csIndex].end() ); - Assert( d_sygus_pc_nred[tnno][csIndex].find( osIndex )!=d_sygus_pc_nred[tnno][csIndex].end() ); - - bool isPComm = quantifiers::TermDb::isComm( parentKind ); - std::map< int, bool > larg_consider; - for( unsigned i=0; i<dto.getNumConstructors(); i++ ){ - if( d_sygus_pc_nred[tnno][csIndex][osIndex][i] ){ - //arguments that can be removed - std::map< int, bool > rem_arg; - //collect information about this index - Node oac = d_tds->getArgConst( tnno, i ); - bool isSingularConst = !oac.isNull() && d_tds->isSingularArg( oac, parentKind, 1 ); - bool argConsider = false; - for( unsigned j=0; j<dt.getNumConstructors(); j++ ){ - if( d_sygus_pc_nred[tnn][csIndex][sIndex][j] ){ - Trace("sygus-split-debug") << "Check redundancy of " << dt[j].getSygusOp() << " and " << dto[i].getSygusOp() << " under " << parentKind << std::endl; - bool rem = false; - if( isPComm && j>i && tnn==tnno && d_sygus_pc_nred[tnno][csIndex][osIndex][j] ){ - //based on commutativity - // use term ordering : constructor index of first argument is not greater than constructor index of second argument - rem = true; - Trace("sygus-nf") << "* Sygus norm : commutativity of " << parentKind << " : consider " << dt[j].getSygusOp() << " before " << dto[i].getSygusOp() << std::endl; - }else if( isSingularConst && argConsider ){ - rem = true; - Trace("sygus-nf") << "* Sygus norm : RHS singularity arg " << dto[i].getSygusOp() << " of " << parentKind; - Trace("sygus-nf") << " : do not consider " << dt[j].getSygusOp() << " as first arg." << std::endl; + + Trace("sygus-sb-simple-debug") << "Process arguments for " << tn << " : " << nk << " : " << std::endl; + // singular arguments (e.g. 0 for mult) + // redundant arguments (e.g. 0 for plus, 1 for mult) + // right-associativity + // simple rewrites + for( unsigned j=0; j<dt[tindex].getNumArgs(); j++ ){ + Node nc = children[j]; + // if not already solved + if( children_solved.find( j )==children_solved.end() ){ + TypeNode tnc = nc.getType(); + const Datatype& cdt = ((DatatypeType)(tnc).toType()).getDatatype(); + for( unsigned k=0; k<cdt.getNumConstructors(); k++ ){ + // if not already generic redundant + if( !d_tds->isGenericRedundant( tnc, k ) ){ + Kind nck = d_tds->getConsNumKind( tnc, k ); + bool red = false; + //check if the argument is redundant + if( nck!=UNDEFINED_KIND ){ + Trace("sygus-sb-simple-debug") << " argument " << j << " " << k << " is : " << nck << std::endl; + red = !d_tds->considerArgKind( tnc, tn, nck, nk, j ); }else{ - Node cac = d_tds->getArgConst( tnn, j ); - if( !cac.isNull() && d_tds->isSingularArg( cac, parentKind, 0 ) && larg_consider.find( j )!=larg_consider.end() ){ - rem = true; - Trace("sygus-nf") << "* Sygus norm : LHS singularity arg " << dt[j].getSygusOp() << " of " << parentKind; - Trace("sygus-nf") << " : do not consider " << dto[i].getSygusOp() << " as second arg." << std::endl; + Node cc = d_tds->getConsNumConst( tnc, k ); + if( !cc.isNull() ){ + Trace("sygus-sb-simple-debug") << " argument " << j << " " << k << " is constant : " << cc << std::endl; + red = !d_tds->considerConst( tnc, tn, cc, nk, j ); }else{ - if( parentKind!=UNDEFINED_KIND ){ - std::map< TypeNode, int > var_count; - std::map< int, Node > pre; - Node g1 = d_tds->mkGeneric( dt, j, var_count, pre ); - Node g2 = d_tds->mkGeneric( dto, i, var_count, pre ); - Node g = NodeManager::currentNM()->mkNode( parentKind, g1, g2 ); - if( isGenericRedundant( tnnp, g ) ){ - rem = true; - } - } + //defined function? } } - if( rem ){ - rem_arg[j] = true; - }else{ - argConsider = true; - larg_consider[j] = true; + if( red ){ + Trace("sygus-sb-simple-debug") << " ...redundant." << std::endl; + sbp_conj.push_back( DatatypesRewriter::mkTester( nc, k, cdt ).negate() ); } } } - if( !rem_arg.empty() ){ - d_sygus_pc_arg_pos[tnno][csIndex][i].clear(); - Trace("sygus-split-debug") << "Possibilities for first argument of " << parentKind << ", when second argument is " << dto[i].getName() << " : " << std::endl; - for( unsigned j=0; j<dt.getNumConstructors(); j++ ){ - if( d_sygus_pc_nred[tnn][csIndex][sIndex][j] && rem_arg.find( j )==rem_arg.end() ){ - d_sygus_pc_arg_pos[tnno][csIndex][i].push_back( j ); - Trace("sygus-split-debug") << " " << dt[j].getName() << std::endl; - } - } - //if there are no possibilities for first argument, then this child is redundant - if( d_sygus_pc_arg_pos[tnno][csIndex][i].empty() ){ - Trace("sygus-nf") << "* Sygus norm " << pdt.getName() << " : do not consider constant " << dt.getName() << "::" << dto[i].getName(); - Trace("sygus-nf") << " as argument " << osIndex << " of " << parentKind << " (based on arguments)." << std::endl; - d_sygus_pc_nred[tnno][csIndex][osIndex][i] = false; + } + } + }else{ + // defined function? + } + }else if( depth==2 ){ + if( nk!=UNDEFINED_KIND ){ + // commutative operators + if( quantifiers::TermDb::isComm( nk ) ){ + if( children.size()==2 ){ + if( children[0].getType()==children[1].getType() ){ + //chainable + // TODO : this is depth 2 + if( children[0].getType()==tn ){ + Node child11 = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[tindex].getSelectorInternal( tn.toType(), 1 ) ), children[0] ); + Assert( child11.getType()==children[1].getType() ); + Node order_pred_trans = NodeManager::currentNM()->mkNode( OR, DatatypesRewriter::mkTester( children[0], tindex, dt ).negate(), + getTermOrderPredicate( child11, children[1] ) ); + + sbp_conj.push_back( order_pred_trans ); } } } @@ -399,975 +637,703 @@ void SygusSplit::registerSygusTypeConstructorArg( TypeNode tnn, const Datatype& } } } + + Node sb_pred; + if( !sbp_conj.empty() ){ + sb_pred = sbp_conj.size()==1 ? sbp_conj[0] : NodeManager::currentNM()->mkNode( kind::AND, sbp_conj ); + Trace("sygus-sb-simple") << "Simple predicate for " << tn << " index " << tindex << " (" << nk << ") at depth " << depth << " : " << std::endl; + Trace("sygus-sb-simple") << " " << sb_pred << std::endl; + sb_pred = NodeManager::currentNM()->mkNode( kind::OR, DatatypesRewriter::mkTester( n, tindex, dt ).negate(), sb_pred ); + } + d_simple_sb_pred[tn][tindex][depth] = sb_pred; + return sb_pred; + }else{ + return it->second; } } -class ReqTrie { -public: - ReqTrie() : d_req_kind( UNDEFINED_KIND ){} - std::map< unsigned, ReqTrie > d_children; - Kind d_req_kind; - TypeNode d_req_type; - Node d_req_const; - void print( const char * c, int indent = 0 ){ - if( d_req_kind!=UNDEFINED_KIND ){ - Trace(c) << d_req_kind << " "; - }else if( !d_req_type.isNull() ){ - Trace(c) << d_req_type; - }else if( !d_req_const.isNull() ){ - Trace(c) << d_req_const; - }else{ - Trace(c) << "_"; - } - Trace(c) << std::endl; - for( std::map< unsigned, ReqTrie >::iterator it = d_children.begin(); it != d_children.end(); ++it ){ - for( int i=0; i<=indent; i++ ) { Trace(c) << " "; } - Trace(c) << it->first << " : "; - it->second.print( c, indent+1 ); - } +TNode SygusSymBreakNew::getFreeVar( TypeNode tn ) { + std::map< TypeNode, Node >::iterator it = d_free_var.find( tn ); + if( it==d_free_var.end() ){ + Node x = NodeManager::currentNM()->mkSkolem( "x", tn ); + d_free_var[tn] = x; + return x; + }else{ + return it->second; } - bool satisfiedBy( quantifiers::TermDbSygus * tdb, TypeNode tn ){ - if( d_req_kind!=UNDEFINED_KIND ){ - int c = tdb->getKindArg( tn, d_req_kind ); - if( c!=-1 ){ - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - for( std::map< unsigned, ReqTrie >::iterator it = d_children.begin(); it != d_children.end(); ++it ){ - if( it->first<dt[c].getNumArgs() ){ - TypeNode tnc = tdb->getArgType( dt[c], it->first ); - if( !it->second.satisfiedBy( tdb, tnc ) ){ - return false; - } - }else{ - return false; - } - } - return true; - }else{ - return false; - } - }else if( !d_req_const.isNull() ){ - return tdb->hasConst( tn, d_req_const ); - }else if( !d_req_type.isNull() ){ - return tn==d_req_type; - }else{ - return true; - } +} + +unsigned SygusSymBreakNew::processSelectorChain( Node n, std::map< TypeNode, Node >& top_level, std::map< Node, unsigned >& tdepth, std::vector< Node >& lemmas ) { + unsigned ret = 0; + if( n.getKind()==APPLY_SELECTOR_TOTAL ){ + ret = processSelectorChain( n[0], top_level, tdepth, lemmas ); } -}; + TypeNode tn = n.getType(); + if( top_level.find( tn )==top_level.end() ){ + top_level[tn] = n; + //tdepth[n] = ret; + registerSearchTerm( tn, ret, n, true, lemmas ); + }else{ + registerSearchTerm( tn, ret, n, false, lemmas ); + } + tdepth[n] = ret; + return ret+1; +} +void SygusSymBreakNew::registerSearchTerm( TypeNode tn, unsigned d, Node n, bool topLevel, std::vector< Node >& lemmas ) { + //register this term + std::map< Node, Node >::iterator ita = d_term_to_anchor.find( n ); + Assert( ita != d_term_to_anchor.end() ); + Node a = ita->second; + Assert( !a.isNull() ); + if( std::find( d_cache[a].d_search_terms[tn][d].begin(), d_cache[a].d_search_terms[tn][d].end(), n )==d_cache[a].d_search_terms[tn][d].end() ){ + Trace("sygus-sb-debug") << " register search term : " << n << " at depth " << d << ", type=" << tn << ", tl=" << topLevel << std::endl; + d_cache[a].d_search_terms[tn][d].push_back( n ); + if( !options::sygusSymBreakLazy() ){ + addSymBreakLemmasFor( tn, n, d, lemmas ); + } + } +} -//this function gets all easy redundant cases, before consulting rewriters -bool SygusSplit::considerSygusSplitKind( const Datatype& dt, const Datatype& pdt, TypeNode tn, TypeNode tnp, Kind k, Kind parent, int arg ) { - Assert( d_tds->hasKind( tn, k ) ); - Assert( d_tds->hasKind( tnp, parent ) ); - Trace("sygus-split") << "Consider sygus split kind " << k << ", parent = " << parent << ", arg = " << arg << "?" << std::endl; - int c = d_tds->getKindArg( tn, k ); - int pc = d_tds->getKindArg( tnp, parent ); - if( k==parent ){ - //check for associativity - if( quantifiers::TermDb::isAssoc( k ) ){ - //if the operator is associative, then a repeated occurrence should only occur in the leftmost argument position - int firstArg = getFirstArgOccurrence( pdt[pc], dt ); - Assert( firstArg!=-1 ); - Trace("sygus-split-debug") << "Associative, with first arg = " << firstArg << std::endl; - return arg==firstArg; +class EquivSygusInvarianceTest : public quantifiers::SygusInvarianceTest { +public: + EquivSygusInvarianceTest(){} + ~EquivSygusInvarianceTest(){} + Node d_ex_ar; + Node d_bvr; + std::vector< Node > d_exo; + void init( quantifiers::TermDbSygus * tds, TypeNode tn, Node ar, Node bvr ) { + //compute the current examples + d_bvr = bvr; + if( tds->hasPbeExamples( ar ) ){ + d_ex_ar = ar; + unsigned nex = tds->getNumPbeExamples( ar ); + for( unsigned i=0; i<nex; i++ ){ + d_exo.push_back( tds->evaluateBuiltin( tn, bvr, ar, i ) ); + } } } - //describes the shape of an alternate term to construct - // we check whether this term is in the sygus grammar below - ReqTrie rt; - bool rt_valid = false; - - //construct rt by cases - if( parent==NOT || parent==BITVECTOR_NOT || parent==UMINUS || parent==BITVECTOR_NEG ){ - rt_valid = true; - //negation normal form - if( parent==k ){ - rt.d_req_type = d_tds->getArgType( dt[c], 0 ); +protected: + bool invariant( quantifiers::TermDbSygus * tds, Node nvn, Node x ){ + TypeNode tn = nvn.getType(); + Node nbv = tds->sygusToBuiltin( nvn, tn ); + Node nbvr = tds->extendedRewrite( nbv ); + Trace("sygus-sb-mexp-debug") << " min-exp check : " << nbv << " -> " << nbvr << std::endl; + bool exc_arg = false; + // equivalent / singular up to normalization + if( nbvr==d_bvr ){ + // gives the same result : then the explanation for the child is irrelevant + exc_arg = true; + Trace("sygus-sb-mexp") << "sb-min-exp : " << tds->sygusToBuiltin( nvn ) << " is rewritten to " << nbvr; + Trace("sygus-sb-mexp") << " regardless of the content of " << tds->sygusToBuiltin( x ) << std::endl; }else{ - Kind reqk = UNDEFINED_KIND; //required kind for all children - std::map< unsigned, Kind > reqkc; //required kind for some children - if( parent==NOT ){ - if( k==AND ) { - rt.d_req_kind = OR;reqk = NOT; - }else if( k==OR ){ - rt.d_req_kind = AND;reqk = NOT; - //AJR : eliminate this if we eliminate xor - }else if( k==EQUAL ) { - rt.d_req_kind = XOR; - }else if( k==XOR ) { - rt.d_req_kind = EQUAL; - }else if( k==ITE ){ - rt.d_req_kind = ITE;reqkc[1] = NOT;reqkc[2] = NOT; - rt.d_children[0].d_req_type = d_tds->getArgType( dt[c], 0 ); - }else if( k==LEQ || k==GT ){ - // (not (~ x y)) -----> (~ (+ y 1) x) - rt.d_req_kind = k; - rt.d_children[0].d_req_kind = PLUS; - rt.d_children[0].d_children[0].d_req_type = d_tds->getArgType( dt[c], 1 ); - rt.d_children[0].d_children[1].d_req_const = NodeManager::currentNM()->mkConst( Rational( 1 ) ); - rt.d_children[1].d_req_type = d_tds->getArgType( dt[c], 0 ); - //TODO: other possibilities? - }else if( k==LT || k==GEQ ){ - // (not (~ x y)) -----> (~ y (+ x 1)) - rt.d_req_kind = k; - rt.d_children[0].d_req_type = d_tds->getArgType( dt[c], 1 ); - rt.d_children[1].d_req_kind = PLUS; - rt.d_children[1].d_children[0].d_req_type = d_tds->getArgType( dt[c], 0 ); - rt.d_children[1].d_children[1].d_req_const = NodeManager::currentNM()->mkConst( Rational( 1 ) ); - }else{ - rt_valid = false; - } - }else if( parent==BITVECTOR_NOT ){ - if( k==BITVECTOR_AND ) { - rt.d_req_kind = BITVECTOR_OR;reqk = BITVECTOR_NOT; - }else if( k==BITVECTOR_OR ){ - rt.d_req_kind = BITVECTOR_AND;reqk = BITVECTOR_NOT; - }else if( k==BITVECTOR_XNOR ) { - rt.d_req_kind = BITVECTOR_XOR; - }else if( k==BITVECTOR_XOR ) { - rt.d_req_kind = BITVECTOR_XNOR; - }else{ - rt_valid = false; - } - }else if( parent==UMINUS ){ - if( k==PLUS ){ - rt.d_req_kind = PLUS;reqk = UMINUS; - }else{ - rt_valid = false; - } - }else if( parent==BITVECTOR_NEG ){ - if( k==PLUS ){ - rt.d_req_kind = PLUS;reqk = BITVECTOR_NEG; - }else{ - rt_valid = false; - } - } - if( rt_valid && ( reqk!=UNDEFINED_KIND || !reqkc.empty() ) ){ - int pcr = d_tds->getKindArg( tnp, rt.d_req_kind ); - if( pcr!=-1 ){ - Assert( pcr<(int)pdt.getNumConstructors() ); - //must have same number of arguments - if( pdt[pcr].getNumArgs()==dt[c].getNumArgs() ){ - for( unsigned i=0; i<pdt[pcr].getNumArgs(); i++ ){ - Kind rk = reqk; - if( reqk==UNDEFINED_KIND ){ - std::map< unsigned, Kind >::iterator itr = reqkc.find( i ); - if( itr!=reqkc.end() ){ - rk = itr->second; - } - } - if( rk!=UNDEFINED_KIND ){ - rt.d_children[i].d_req_kind = rk; - rt.d_children[i].d_children[0].d_req_type = d_tds->getArgType( dt[c], i ); - } - } - }else{ - rt_valid = false; + if( nbvr.isVar() ){ + TypeNode xtn = x.getType(); + if( xtn==tn ){ + Node bx = tds->sygusToBuiltin( x, xtn ); + Assert( bx.getType()==nbvr.getType() ); + if( nbvr==bx ){ + Trace("sygus-sb-mexp") << "sb-min-exp : " << tds->sygusToBuiltin( nvn ) << " always rewrites to argument " << nbvr << std::endl; + // rewrites to the variable : then the explanation of this is irrelevant as well + exc_arg = true; + d_bvr = nbvr; } - }else{ - rt_valid = false; } } } - }else if( k==MINUS || k==BITVECTOR_SUB ){ - if( parent==EQUAL || - parent==MINUS || parent==BITVECTOR_SUB || - parent==LEQ || parent==LT || parent==GEQ || parent==GT ){ - int oarg = arg==0 ? 1 : 0; - // (~ x (- y z)) ----> (~ (+ x z) y) - // (~ (- y z) x) ----> (~ y (+ x z)) - rt.d_req_kind = parent; - rt.d_children[arg].d_req_type = d_tds->getArgType( dt[c], 0 ); - rt.d_children[oarg].d_req_kind = k==MINUS ? PLUS : BITVECTOR_PLUS; - rt.d_children[oarg].d_children[0].d_req_type = d_tds->getArgType( pdt[pc], oarg ); - rt.d_children[oarg].d_children[1].d_req_type = d_tds->getArgType( dt[c], 1 ); - rt_valid = true; - }else if( parent==PLUS || parent==BITVECTOR_PLUS ){ - // (+ x (- y z)) -----> (- (+ x y) z) - // (+ (- y z) x) -----> (- (+ x y) z) - rt.d_req_kind = parent==PLUS ? MINUS : BITVECTOR_SUB; - int oarg = arg==0 ? 1 : 0; - rt.d_children[0].d_req_kind = parent; - rt.d_children[0].d_children[0].d_req_type = d_tds->getArgType( pdt[pc], oarg ); - rt.d_children[0].d_children[1].d_req_type = d_tds->getArgType( dt[c], 0 ); - rt.d_children[1].d_req_type = d_tds->getArgType( dt[c], 1 ); - rt_valid = true; - } - }else if( k==ITE ){ - if( parent!=ITE ){ - // (o X (ite y z w) X') -----> (ite y (o X z X') (o X w X')) - rt.d_req_kind = ITE; - rt.d_children[0].d_req_type = d_tds->getArgType( dt[c], 0 ); - unsigned n_args = pdt[pc].getNumArgs(); - for( unsigned r=1; r<=2; r++ ){ - rt.d_children[r].d_req_kind = parent; - for( unsigned q=0; q<n_args; q++ ){ - if( (int)q==arg ){ - rt.d_children[r].d_children[q].d_req_type = d_tds->getArgType( dt[c], r ); - }else{ - rt.d_children[r].d_children[q].d_req_type = d_tds->getArgType( pdt[pc], q ); + // equivalent under examples + if( !exc_arg ){ + if( !d_ex_ar.isNull() ){ + bool ex_equiv = true; + for( unsigned j=0; j<d_exo.size(); j++ ){ + Node nbvr_ex = tds->evaluateBuiltin( tn, nbvr, d_ex_ar, j ); + if( nbvr_ex!=d_exo[j] ){ + ex_equiv = false; + break; } } + if( ex_equiv ){ + Trace("sygus-sb-mexp") << "sb-min-exp : " << tds->sygusToBuiltin( nvn ); + Trace("sygus-sb-mexp") << " is the same w.r.t. examples regardless of the content of " << tds->sygusToBuiltin( x ) << std::endl; + exc_arg = true; + } } - rt_valid = true; - //TODO: this increases term size but is probably a good idea - } - }else if( k==NOT ){ - if( parent==ITE ){ - // (ite (not y) z w) -----> (ite y w z) - rt.d_req_kind = ITE; - rt.d_children[0].d_req_type = d_tds->getArgType( dt[c], 0 ); - rt.d_children[1].d_req_type = d_tds->getArgType( pdt[pc], 2 ); - rt.d_children[2].d_req_type = d_tds->getArgType( pdt[pc], 1 ); } + return exc_arg; } - Trace("sygus-consider-split") << "Consider sygus split kind " << k << ", parent = " << parent << ", arg = " << arg << "?" << std::endl; - if( rt_valid ){ - rt.print("sygus-consider-split"); - //check if it meets the requirements - if( rt.satisfiedBy( d_tds, tnp ) ){ - Trace("sygus-consider-split") << "...success!" << std::endl; - //do not need to consider the kind in the search since there are ways to construct equivalent terms - return false; +}; + + +class DivByZeroSygusInvarianceTest : public quantifiers::SygusInvarianceTest { +public: + DivByZeroSygusInvarianceTest(){} + ~DivByZeroSygusInvarianceTest(){} + +protected: + bool invariant( quantifiers::TermDbSygus * tds, Node nvn, Node x ){ + TypeNode tn = nvn.getType(); + Node nbv = tds->sygusToBuiltin( nvn, tn ); + Node nbvr = tds->extendedRewrite( nbv ); + if( tds->involvesDivByZero( nbvr ) ){ + Trace("sygus-sb-mexp") << "sb-min-exp : " << tds->sygusToBuiltin( nvn ) << " involves div-by-zero regardless of " << tds->sygusToBuiltin( x ) << std::endl; + return true; }else{ - Trace("sygus-consider-split") << "...failed." << std::endl; + return false; } - Trace("sygus-consider-split") << std::endl; } - //must consider this kind in the search - return true; -} +}; -//this function gets all easy redundant cases, before consulting rewriters -bool SygusSplit::considerSygusSplitConst( const Datatype& dt, const Datatype& pdt, TypeNode tn, TypeNode tnp, Node c, Kind parent, int arg ) { - Assert( d_tds->hasConst( tn, c ) ); - Assert( d_tds->hasKind( tnp, parent ) ); - int pc = d_tds->getKindArg( tnp, parent ); - Trace("sygus-split") << "Consider sygus split const " << c << ", parent = " << parent << ", arg = " << arg << "?" << std::endl; - if( d_tds->isIdempotentArg( c, parent, arg ) ){ - Trace("sygus-split-debug") << " " << c << " is idempotent arg " << arg << " of " << parent << "..." << std::endl; - if( pdt[pc].getNumArgs()==2 ){ - int oarg = arg==0 ? 1 : 0; - TypeNode otn = TypeNode::fromType( ((SelectorType)pdt[pc][oarg].getType()).getRangeType() ); - if( otn==tnp ){ +bool SygusSymBreakNew::registerSearchValue( Node a, Node n, Node nv, unsigned d, std::vector< Node >& lemmas ) { + Assert( n.getType()==nv.getType() ); + Assert( nv.getKind()==APPLY_CONSTRUCTOR ); + TypeNode tn = n.getType(); + // currently bottom-up, could be top-down? + if( nv.getNumChildren()>0 ){ + const Datatype& dt = ((DatatypeType)tn.toType()).getDatatype(); + unsigned cindex = Datatype::indexOf( nv.getOperator().toExpr() ); + for( unsigned i=0; i<nv.getNumChildren(); i++ ){ + Node sel = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[cindex].getSelectorInternal( tn.toType(), i ) ), n ); + if( !registerSearchValue( a, sel, nv[i], d+1, lemmas ) ){ return false; } } - }else if( d_tds->isSingularArg( c, parent, arg ) ){ - Trace("sygus-split-debug") << " " << c << " is singular arg " << arg << " of " << parent << "..." << std::endl; - if( d_tds->hasConst( tnp, c ) ){ - return false; - } } - if( pdt[pc].getNumArgs()==2 ){ - Kind ok; - int offset; - if( d_tds->hasOffsetArg( parent, arg, offset, ok ) ){ - Trace("sygus-split-debug") << parent << " has offset arg " << ok << " " << offset << std::endl; - int ok_arg = d_tds->getKindArg( tnp, ok ); - if( ok_arg!=-1 ){ - Trace("sygus-split-debug") << "...at argument " << ok_arg << std::endl; - //other operator be the same type - if( isTypeMatch( pdt[ok_arg], pdt[arg] ) ){ - int status; - Node co = d_tds->getTypeValueOffset( c.getType(), c, offset, status ); - Trace("sygus-split-debug") << c << " with offset " << offset << " is " << co << ", status=" << status << std::endl; - if( status==0 && !co.isNull() ){ - if( d_tds->hasConst( tn, co ) ){ - Trace("sygus-split-debug") << "arg " << arg << " " << c << " in " << parent << " can be treated as " << co << " in " << ok << "..." << std::endl; - return false; - }else{ - Trace("sygus-split-debug") << "Type does not have constant." << std::endl; + Trace("sygus-sb-debug2") << "Registering search value " << n << " -> " << nv << std::endl; + // must do this for all nodes, regardless of top-level + if( d_cache[a].d_search_val_proc.find( nv )==d_cache[a].d_search_val_proc.end() ){ + d_cache[a].d_search_val_proc[nv] = true; + // get the root (for PBE symmetry breaking) + Assert( d_term_to_anchor_root.find( a )!=d_term_to_anchor_root.end() ); + Node ar = d_term_to_anchor_root[a]; + Assert( !ar.isNull() ); + Trace("sygus-sb-debug") << " ...register search value " << nv << ", type=" << tn << std::endl; + Node bv = d_tds->sygusToBuiltin( nv, tn ); + Trace("sygus-sb-debug") << " ......builtin is " << bv << std::endl; + Node bvr = d_tds->extendedRewrite( bv ); + Trace("sygus-sb-debug") << " ......rewrites to " << bvr << std::endl; + unsigned sz = d_tds->getSygusTermSize( nv ); + std::vector< Node > exp; + bool do_exclude = false; + if( d_tds->involvesDivByZero( bvr ) ){ + Node x = getFreeVar( tn ); + DivByZeroSygusInvarianceTest dbzet; + Trace("sygus-sb-mexp-debug") << "Minimize explanation for div-by-zero in " << d_tds->sygusToBuiltin( nv ) << std::endl; + d_tds->getExplanationFor( x, nv, exp, dbzet, Node::null(), sz ); + do_exclude = true; + }else{ + std::map< Node, Node >::iterator itsv = d_cache[a].d_search_val[tn].find( bvr ); + Node bad_val_bvr; + bool by_examples = false; + if( itsv==d_cache[a].d_search_val[tn].end() ){ + // is it equivalent under examples? + Node bvr_equiv = d_tds->addPbeSearchVal( tn, ar, bvr ); + if( !bvr_equiv.isNull() ){ + if( bvr_equiv!=bvr ){ + Trace("sygus-sb-debug") << "......adding search val for " << bvr << " returned " << bvr_equiv << std::endl; + Assert( d_cache[a].d_search_val[tn].find( bvr_equiv )!=d_cache[a].d_search_val[tn].end() ); + Trace("sygus-sb-debug") << "......search value was " << d_cache[a].d_search_val[tn][bvr_equiv] << std::endl; + if( Trace.isOn("sygus-sb-exc") ){ + Node prev = d_tds->sygusToBuiltin( d_cache[a].d_search_val[tn][bvr_equiv], tn ); + Trace("sygus-sb-exc") << " ......programs " << prev << " and " << bv << " are equivalent up to examples." << std::endl; } + bad_val_bvr = bvr_equiv; + by_examples = true; } - }else{ - Trace("sygus-split-debug") << "Type mismatch." << std::endl; } + //store rewritten values, regardless of whether it will be considered + d_cache[a].d_search_val[tn][bvr] = nv; + d_cache[a].d_search_val_sz[tn][bvr] = sz; + }else{ + bad_val_bvr = bvr; + if( Trace.isOn("sygus-sb-exc") ){ + Node prev_bv = d_tds->sygusToBuiltin( itsv->second, tn ); + Trace("sygus-sb-exc") << " ......programs " << prev_bv << " and " << bv << " rewrite to " << bvr << "." << std::endl; + } } + + if( !bad_val_bvr.isNull() ){ + Node bad_val = nv; + Node bad_val_o = d_cache[a].d_search_val[tn][bad_val_bvr]; + Assert( d_cache[a].d_search_val_sz[tn].find( bad_val_bvr )!=d_cache[a].d_search_val_sz[tn].end() ); + unsigned prev_sz = d_cache[a].d_search_val_sz[tn][bad_val_bvr]; + if( prev_sz>sz ){ + //swap : the excluded value is the previous + d_cache[a].d_search_val_sz[tn][bad_val_bvr] = sz; + bad_val = d_cache[a].d_search_val[tn][bad_val_bvr]; + bad_val_o = nv; + sz = prev_sz; + } + if( Trace.isOn("sygus-sb-exc") ){ + Node bad_val_bv = d_tds->sygusToBuiltin( bad_val, tn ); + Trace("sygus-sb-exc") << " ........exclude : " << bad_val_bv; + if( by_examples ){ + Trace("sygus-sb-exc") << " (by examples)"; + } + Trace("sygus-sb-exc") << std::endl; + } + Assert( d_tds->getSygusTermSize( bad_val )==sz ); + + Node x = getFreeVar( tn ); + + // do analysis of the evaluation FIXME: does not work (evaluation is non-constant) + EquivSygusInvarianceTest eset; + eset.init( d_tds, tn, ar, bvr ); + Trace("sygus-sb-mexp-debug") << "Minimize explanation for eval[" << d_tds->sygusToBuiltin( bad_val ) << "] = " << bvr << std::endl; + d_tds->getExplanationFor( x, bad_val, exp, eset, bad_val_o, sz ); + do_exclude = true; + } + } + if( do_exclude ){ + Node lem = exp.size()==1 ? exp[0] : NodeManager::currentNM()->mkNode( kind::AND, exp ); + lem = lem.negate(); + /* add min type depth to size : TODO? + Assert( d_term_to_anchor.find( n )!=d_term_to_anchor.end() ); + TypeNode atype = d_term_to_anchor[n].getType(); + if( atype!=tn ){ + unsigned min_type_depth = d_tds->getMinTypeDepth( atype, tn ); + if( min_type_depth>0 ){ + Trace("sygus-sb-exc") << " ........min type depth for " << ((DatatypeType)tn.toType()).getDatatype().getName() << " in "; + Trace("sygus-sb-exc") << ((DatatypeType)atype.toType()).getDatatype().getName() << " is " << min_type_depth << std::endl; + sz = sz + min_type_depth; + } + } + */ + Trace("sygus-sb-exc") << " ........exc lemma is " << lem << ", size = " << sz << std::endl; + registerSymBreakLemma( tn, lem, sz, a, lemmas ); + return false; } } return true; } -int SygusSplit::getFirstArgOccurrence( const DatatypeConstructor& c, const Datatype& dt ) { - for( unsigned i=0; i<c.getNumArgs(); i++ ){ - if( isArgDatatype( c, i, dt ) ){ - return i; - } - } - return -1; -} -bool SygusSplit::isArgDatatype( const DatatypeConstructor& c, int i, const Datatype& dt ) { - TypeNode tni = d_tds->getArgType( c, i ); - if( tni.isDatatype() ){ - const Datatype& adt = ((DatatypeType)(tni).toType()).getDatatype(); - if( adt==dt ){ - return true; - } - } - return false; -} -bool SygusSplit::isTypeMatch( const DatatypeConstructor& c1, const DatatypeConstructor& c2 ){ - if( c1.getNumArgs()!=c2.getNumArgs() ){ - return false; - }else{ - for( unsigned i=0; i<c1.getNumArgs(); i++ ){ - if( d_tds->getArgType( c1, i )!=d_tds->getArgType( c2, i ) ){ - return false; +void SygusSymBreakNew::registerSymBreakLemma( TypeNode tn, Node lem, unsigned sz, Node a, std::vector< Node >& lemmas ) { + // lem holds for all terms of type tn, and is applicable to terms of size sz + Trace("sygus-sb-debug") << " register sym break lemma : " << lem << ", size " << sz << std::endl; + Assert( !a.isNull() ); + d_cache[a].d_sb_lemmas[tn][sz].push_back( lem ); + TNode x = getFreeVar( tn ); + unsigned csz = getSearchSizeForAnchor( a ); + int max_depth = ((int)csz)-((int)sz); + for( int d=0; d<=max_depth; d++ ){ + std::map< unsigned, std::vector< Node > >::iterator itt = d_cache[a].d_search_terms[tn].find( d ); + if( itt!=d_cache[a].d_search_terms[tn].end() ){ + for( unsigned k=0; k<itt->second.size(); k++ ){ + TNode t = itt->second[k]; + if( !options::sygusSymBreakLazy() || d_active_terms.find( t )!=d_active_terms.end() ){ + addSymBreakLemma( tn, lem, x, t, sz, d, lemmas ); + } } } - return true; } } +void SygusSymBreakNew::addSymBreakLemmasFor( TypeNode tn, Node t, unsigned d, std::vector< Node >& lemmas ) { + Assert( d_term_to_anchor.find( t )!=d_term_to_anchor.end() ); + Node a = d_term_to_anchor[t]; + addSymBreakLemmasFor( tn, t, d, a, lemmas ); +} -bool SygusSplit::isGenericRedundant( TypeNode tn, Node g, bool active ) { - //everything added to this cache should be mutually exclusive cases - std::map< Node, bool >::iterator it = d_gen_redundant[tn].find( g ); - if( it==d_gen_redundant[tn].end() ){ - Trace("sygus-gnf") << "Register generic for " << tn << " : " << g << std::endl; - Node gr = d_tds->getNormalized( tn, g, false ); - Trace("sygus-gnf-debug") << "Generic " << g << " rewrites to " << gr << std::endl; - if( active ){ - std::map< Node, Node >::iterator itg = d_gen_terms[tn].find( gr ); - bool red = true; - if( itg==d_gen_terms[tn].end() ){ - red = false; - d_gen_terms[tn][gr] = g; - d_gen_terms_inactive[tn][gr] = g; - Trace("sygus-gnf-debug") << "...not redundant." << std::endl; - Trace("sygus-nf-reg") << "*** Sygus (generic) normal form : normal form of " << g << " is " << gr << std::endl; - }else{ - Trace("sygus-gnf-debug") << "...redundant." << std::endl; - Trace("sygus-nf") << "* Sygus normal form : simplify since " << g << " and " << itg->second << " both rewrite to " << gr << std::endl; - } - d_gen_redundant[tn][g] = red; - return red; - }else{ - std::map< Node, Node >::iterator itg = d_gen_terms_inactive[tn].find( gr ); - if( itg==d_gen_terms_inactive[tn].end() ){ - Trace("sygus-nf-temp") << "..." << g << " rewrites to " << gr << std::endl; - d_gen_terms_inactive[tn][gr] = g; - }else{ - Trace("sygus-nf-temp") << "* Note " << g << " and " << itg->second << " both rewrite to " << gr << std::endl; +void SygusSymBreakNew::addSymBreakLemmasFor( TypeNode tn, Node t, unsigned d, Node a, std::vector< Node >& lemmas ) { + Assert( t.getType()==tn ); + Assert( !a.isNull() ); + std::map< TypeNode, std::map< unsigned, std::vector< Node > > >::iterator its = d_cache[a].d_sb_lemmas.find( tn ); + if( its != d_cache[a].d_sb_lemmas.end() ){ + TNode x = getFreeVar( tn ); + //get symmetry breaking lemmas for this term + unsigned csz = getSearchSizeForAnchor( a ); + int max_sz = ((int)csz) - ((int)d); + for( std::map< unsigned, std::vector< Node > >::iterator it = its->second.begin(); it != its->second.end(); ++it ){ + if( (int)it->first<=max_sz ){ + for( unsigned k=0; k<it->second.size(); k++ ){ + Node lem = it->second[k]; + addSymBreakLemma( tn, lem, x, t, it->first, d, lemmas ); + } } - return false; } - }else{ - return it->second; } } - - -SygusSymBreak::SygusSymBreak( quantifiers::TermDbSygus * tds, context::Context* c ) : d_tds( tds ), d_context( c ) { - +void SygusSymBreakNew::addSymBreakLemma( TypeNode tn, Node lem, TNode x, TNode n, unsigned lem_sz, unsigned n_depth, std::vector< Node >& lemmas ) { + Assert( !options::sygusSymBreakLazy() || d_active_terms.find( n )!=d_active_terms.end() ); + // apply lemma + Node slem = lem.substitute( x, n ); + Trace("sygus-sb-exc-debug") << "SymBreak lemma : " << slem << std::endl; + Node rlv = getRelevancyCondition( n ); + if( !rlv.isNull() ){ + slem = NodeManager::currentNM()->mkNode( kind::OR, rlv.negate(), slem ); + } + lemmas.push_back( slem ); } - -SygusSymBreak::~SygusSymBreak() { - for(std::map< Node, ProgSearch* >::iterator i = d_prog_search.begin(), iend = d_prog_search.end(); - i != iend; ++i){ - ProgSearch* current = (*i).second; - if(current != NULL){ - delete current; - } + +void SygusSymBreakNew::preRegisterTerm( TNode n, std::vector< Node >& lemmas ) { + if( n.isVar() ){ + Trace("sygus-sb-debug") << "Pre-register variable : " << n << std::endl; + registerSizeTerm( n, lemmas ); } } -void SygusSymBreak::addTester( int tindex, Node n, Node exp ) { - if( options::sygusNormalFormGlobal() ){ - Node a = getAnchor( n ); - Trace("sygus-sym-break-debug") << "Add tester " << tindex << " " << n << " for " << a << std::endl; - std::map< Node, ProgSearch * >::iterator it = d_prog_search.find( a ); - ProgSearch * ps; - if( it==d_prog_search.end() ){ - //check if sygus type - TypeNode tn = a.getType(); - Assert( tn.isDatatype() ); - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); +void SygusSymBreakNew::registerSizeTerm( Node e, std::vector< Node >& lemmas ) { + if( d_register_st.find( e )==d_register_st.end() ){ + if( e.getType().isDatatype() ){ + const Datatype& dt = ((DatatypeType)(e.getType()).toType()).getDatatype(); if( dt.isSygus() ){ - ps = new ProgSearch( this, a, d_context ); + if( !d_tds->isMeasuredTerm( e ).isNull() ){ + d_register_st[e] = true; + Node ag = d_tds->getActiveGuardForMeasureTerm( e ); + if( !ag.isNull() ){ + d_anchor_to_active_guard[e] = ag; + } + Node m; + if( !ag.isNull() ){ + // if it has an active guard (it is an enumerator), use itself as measure term. This will enforce fairness on it independently. + m = e; + }else{ + // otherwise we enforce fairness in a unified way for all + if( d_generic_measure_term.isNull() ){ + // choose e as master for all future terms + d_generic_measure_term = e; + } + m = d_generic_measure_term; + } + Trace("sygus-sb") << "Sygus : register size term : " << e << " with measure " << m << std::endl; + registerMeasureTerm( m ); + d_szinfo[m]->d_anchors.push_back( e ); + d_anchor_to_measure_term[e] = m; + if( options::sygusFair()==SYGUS_FAIR_DT_SIZE ){ + // update constraints on the measure term + if( options::sygusFairMax() ){ + if( options::sygusFair()==SYGUS_FAIR_DT_SIZE ){ + Node ds = NodeManager::currentNM()->mkNode( kind::DT_SIZE, e ); + Node slem = NodeManager::currentNM()->mkNode( kind::LEQ, ds, d_szinfo[m]->getOrMkSygusMeasureTerm( lemmas ) ); + lemmas.push_back( slem ); + } + }else{ + Node mt = d_szinfo[m]->getOrMkSygusActiveMeasureTerm( lemmas ); + Node new_mt = NodeManager::currentNM()->mkSkolem( "mt", NodeManager::currentNM()->integerType() ); + lemmas.push_back( NodeManager::currentNM()->mkNode( kind::GEQ, new_mt, d_zero ) ); + if( options::sygusFair()==SYGUS_FAIR_DT_SIZE ){ + Node ds = NodeManager::currentNM()->mkNode( kind::DT_SIZE, e ); + lemmas.push_back( mt.eqNode( NodeManager::currentNM()->mkNode( kind::PLUS, new_mt, ds ) ) ); + //lemmas.push_back( NodeManager::currentNM()->mkNode( kind::GEQ, ds, d_zero ) ); + } + d_szinfo[m]->d_sygus_measure_term_active = new_mt; + } + } + }else{ + // not sure if it is a size term or not (may be registered later?) + } }else{ - ps = NULL; + d_register_st[e] = false; } - d_prog_search[a] = ps; }else{ - ps = it->second; - } - if( ps ){ - ps->addTester( tindex, n, exp ); + d_register_st[e] = false; } } } -Node SygusSymBreak::getAnchor( Node n ) { - if( n.getKind()==APPLY_SELECTOR_TOTAL ){ - return getAnchor( n[0] ); - }else{ - return n; +void SygusSymBreakNew::registerMeasureTerm( Node m ) { + std::map< Node, SearchSizeInfo * >::iterator it = d_szinfo.find( m ); + if( it==d_szinfo.end() ){ + Trace("sygus-sb") << "Sygus : register measure term : " << m << std::endl; + d_szinfo[m] = new SearchSizeInfo( m, d_td->getSatContext() ); } } -void SygusSymBreak::ProgSearch::addTester( int tindex, Node n, Node exp ) { -#ifdef CVC4_ASSERTIONS - Node a; - int teindex = DatatypesRewriter::isTester( exp, a ); - Assert( teindex==tindex ); - Assert( a==n ); -#endif - NodeMap::const_iterator it = d_testers.find( n ); - if( it==d_testers.end() ){ - d_testers[n] = exp; - if( n==d_anchor ){ - assignTester( tindex, n, 0 ); - }else{ - IntMap::const_iterator it = d_watched_terms.find( n ); - if( it!=d_watched_terms.end() ){ - assignTester( tindex, n, (*it).second ); +void SygusSymBreakNew::notifySearchSize( Node m, unsigned s, Node exp, std::vector< Node >& lemmas ) { + std::map< Node, SearchSizeInfo * >::iterator its = d_szinfo.find( m ); + Assert( its!=d_szinfo.end() ); + if( its->second->d_search_size.find( s )==its->second->d_search_size.end() ){ + its->second->d_search_size[s] = true; + its->second->d_search_size_exp[s] = exp; + Assert( s==0 || its->second->d_search_size.find( s-1 )!=its->second->d_search_size.end() ); + Trace("sygus-fair") << "SygusSymBreakNew:: now considering term measure : " << s << " for " << m << std::endl; + Assert( s>=its->second->d_curr_search_size ); + while( s>its->second->d_curr_search_size ){ + incrementCurrentSearchSize( m, lemmas ); + } + Trace("sygus-fair") << "...finish increment for term measure : " << s << std::endl; + /* + //re-add all testers (some may now be relevant) TODO + for( IntMap::const_iterator it = d_testers.begin(); it != d_testers.end(); ++it ){ + Node n = (*it).first; + NodeMap::const_iterator itx = d_testers_exp.find( n ); + if( itx!=d_testers_exp.end() ){ + int tindex = (*it).second; + Node exp = (*itx).second; + assertTester( tindex, n, exp, lemmas ); }else{ - Trace("sygus-sym-break-debug2") << "...add to wait list " << tindex << " " << n << " for " << d_anchor << std::endl; + Assert( false ); } } - }else{ - Trace("sygus-sym-break-debug2") << "...already seen " << tindex << " " << n << " for " << d_anchor << std::endl; + */ } } -bool SygusSymBreak::ProgSearch::assignTester( int tindex, Node n, int depth ) { - Trace("sygus-sym-break-debug") << "SymBreak : Assign tester : " << tindex << " " << n << ", depth = " << depth << " of " << d_anchor << std::endl; - TypeNode tn = n.getType(); - Assert( tn.isDatatype() ); - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - std::vector< Node > tst_waiting; - for( unsigned i=0; i<dt[tindex].getNumArgs(); i++ ){ - Node sel = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[tindex][i].getSelector() ), n ); - NodeMap::const_iterator it = d_testers.find( sel ); - if( it!=d_testers.end() ){ - tst_waiting.push_back( (*it).second ); - }else{ - Trace("sygus-sym-break-debug") << "...add " << sel << " as watch term for " << (depth+1) << std::endl; - d_watched_terms[sel] = depth+1; - } - } - //update watched count - IntIntMap::const_iterator it = d_watched_count.find( depth+1 ); - if( it==d_watched_count.end() ){ - d_watched_count[depth+1] = dt[tindex].getNumArgs(); - }else{ - d_watched_count[depth+1] = d_watched_count[depth+1] + dt[tindex].getNumArgs(); - } - Trace("sygus-sym-break-debug") << "...watched count now " << d_watched_count[depth+1].get() << " for " << (depth+1) << " of " << d_anchor << std::endl; - //now decrement watch count and process - if( depth>0 ){ - Assert( d_watched_count[depth]>0 ); - d_watched_count[depth] = d_watched_count[depth] - 1; - } - //determine if any subprograms on the current path are redundant - if( processSubprograms( n, depth, depth ) ){ - if( processProgramDepth( depth ) ){ - //assign preexisting testers - for( unsigned i=0; i<tst_waiting.size(); i++ ){ - Node nw; - int tindexw = DatatypesRewriter::isTester( tst_waiting[i], nw ); - Assert( tindexw!=-1 ); - if( !assignTester( tindexw, nw, depth+1 ) ){ - return false; +unsigned SygusSymBreakNew::getSearchSizeFor( Node n ) { + Trace("sygus-sb-debug2") << "get search size for term : " << n << std::endl; + std::map< Node, Node >::iterator ita = d_term_to_anchor.find( n ); + Assert( ita != d_term_to_anchor.end() ); + return getSearchSizeForAnchor( ita->second ); +} + +unsigned SygusSymBreakNew::getSearchSizeForAnchor( Node a ) { + Trace("sygus-sb-debug2") << "get search size for anchor : " << a << std::endl; + std::map< Node, Node >::iterator it = d_anchor_to_measure_term.find( a ); + Assert( it!=d_anchor_to_measure_term.end() ); + return getSearchSizeForMeasureTerm( it->second ); +} + +unsigned SygusSymBreakNew::getSearchSizeForMeasureTerm( Node m ) { + Trace("sygus-sb-debug2") << "get search size for measure : " << m << std::endl; + std::map< Node, SearchSizeInfo * >::iterator its = d_szinfo.find( m ); + Assert( its!=d_szinfo.end() ); + return its->second->d_curr_search_size; +} + +void SygusSymBreakNew::incrementCurrentSearchSize( Node m, std::vector< Node >& lemmas ) { + std::map< Node, SearchSizeInfo * >::iterator itsz = d_szinfo.find( m ); + Assert( itsz!=d_szinfo.end() ); + itsz->second->d_curr_search_size++; + Trace("sygus-fair") << " register search size " << itsz->second->d_curr_search_size << " for " << m << std::endl; + for( std::map< Node, SearchCache >::iterator itc = d_cache.begin(); itc != d_cache.end(); ++itc ){ + Node a = itc->first; + Trace("sygus-fair-debug") << " look at anchor " << a << "..." << std::endl; + // check whether a is bounded by m + Assert( d_anchor_to_measure_term.find( a )!=d_anchor_to_measure_term.end() ); + if( d_anchor_to_measure_term[a]==m ){ + for( std::map< TypeNode, std::map< unsigned, std::vector< Node > > >::iterator its = itc->second.d_sb_lemmas.begin(); + its != itc->second.d_sb_lemmas.end(); ++its ){ + TypeNode tn = its->first; + TNode x = getFreeVar( tn ); + for( std::map< unsigned, std::vector< Node > >::iterator it = its->second.begin(); it != its->second.end(); ++it ){ + unsigned sz = it->first; + int new_depth = ((int)itsz->second->d_curr_search_size) - ((int)sz); + std::map< unsigned, std::vector< Node > >::iterator itt = itc->second.d_search_terms[tn].find( new_depth ); + if( itt!=itc->second.d_search_terms[tn].end() ){ + for( unsigned k=0; k<itt->second.size(); k++ ){ + TNode t = itt->second[k]; + if( !options::sygusSymBreakLazy() || d_active_terms.find( t )!=d_active_terms.end() ){ + for( unsigned j=0; j<it->second.size(); j++ ){ + Node lem = it->second[j]; + addSymBreakLemma( tn, lem, x, t, sz, new_depth, lemmas ); + } + } + } + } } } - return true; } } - return false; } -bool SygusSymBreak::ProgSearch::processProgramDepth( int depth ){ - if( depth==d_prog_depth.get() && ( depth==0 || ( d_watched_count.find( depth )!=d_watched_count.end() && d_watched_count[depth]==0 ) ) ){ - d_prog_depth = d_prog_depth + 1; - if( depth>0 ){ - Trace("sygus-sym-break-debug") << "Program is set for depth " << depth << std::endl; - std::map< TypeNode, int > var_count; - std::vector< Node > testers; - std::map< Node, std::vector< Node > > testers_u; - //now have entire information about candidate program at given depth - Node prog = getCandidateProgramAtDepth( depth, d_anchor, 0, Node::null(), var_count, testers, testers_u ); - if( !prog.isNull() ){ - if( !d_parent->processCurrentProgram( d_anchor, d_anchor_type, depth, prog, testers, testers_u, var_count ) ){ - return false; - } +void SygusSymBreakNew::check( std::vector< Node >& lemmas ) { + Trace("sygus-sb") << "SygusSymBreakNew::check" << std::endl; + for( std::map< Node, bool >::iterator it = d_register_st.begin(); it != d_register_st.end(); ++it ){ + if( it->second ){ + Node prog = it->first; + Node progv = d_td->getValuation().getModel()->getValue( prog ); + // TODO : remove this step (ensure there is no way a sygus term cannot be assigned a tester before this point) + if( !debugTesters( prog, progv, 0, lemmas ) ){ + Trace("sygus-sb") << " SygusSymBreakNew::check: ...WARNING: considered missing split for " << prog << "." << std::endl; + // this should not happen generally, it is caused by a sygus term not being assigned a tester + //Assert( false ); }else{ - Assert( false ); + //debugging : ensure fairness was properly handled + if( options::sygusFair()==SYGUS_FAIR_DT_SIZE ){ + Node prog_sz = NodeManager::currentNM()->mkNode( kind::DT_SIZE, prog ); + Node prog_szv = d_td->getValuation().getModel()->getValue( prog_sz ); + Node progv_sz = NodeManager::currentNM()->mkNode( kind::DT_SIZE, progv ); + + Trace("sygus-sb") << " Mv[" << prog << "] = " << progv << ", size = " << prog_szv << std::endl; + if( prog_szv.getConst<Rational>().getNumerator().toUnsignedInt() > getSearchSizeForAnchor( prog ) ){ + AlwaysAssert( false ); + Node szlem = NodeManager::currentNM()->mkNode( kind::OR, prog.eqNode( progv ).negate(), + prog_sz.eqNode( progv_sz ) ); + Trace("sygus-sb-warn") << "SygusSymBreak : WARNING : adding size correction : " << szlem << std::endl; + lemmas.push_back( szlem ); + return; + } + } + + // register the search value ( prog -> progv ), this may invoke symmetry breaking + if( options::sygusSymBreakDynamic() ){ + if( !registerSearchValue( prog, prog, progv, 0, lemmas ) ){ + Trace("sygus-sb") << " SygusSymBreakNew::check: ...added new symmetry breaking lemma for " << prog << "." << std::endl; + } + } } } - return processProgramDepth( depth+1 ); - }else{ - return true; } -} - -bool SygusSymBreak::ProgSearch::processSubprograms( Node n, int depth, int odepth ) { - Trace("sygus-sym-break-debug") << "Processing subprograms on path " << n << ", which has depth " << depth << std::endl; - depth--; - if( depth>0 ){ - Assert( n.getKind()==APPLY_SELECTOR_TOTAL ); - std::map< TypeNode, int > var_count; - std::vector< Node > testers; - std::map< Node, std::vector< Node > > testers_u; - //now have entire information about candidate program at given depth - Node prog = getCandidateProgramAtDepth( odepth-depth, n[0], 0, Node::null(), var_count, testers, testers_u ); - if( !prog.isNull() ){ - if( !d_parent->processCurrentProgram( n[0], n[0].getType(), odepth-depth, prog, testers, testers_u, var_count ) ){ - return false; + //register any measured terms that we haven't encountered yet (should only be invoked on first call to check + std::vector< Node > mts; + d_tds->getMeasuredTerms( mts ); + for( unsigned i=0; i<mts.size(); i++ ){ + registerSizeTerm( mts[i], lemmas ); + } + Trace("sygus-sb") << " SygusSymBreakNew::check: finished." << std::endl; + + if( Trace.isOn("cegqi-engine") ){ + if( lemmas.empty() ){ + Trace("cegqi-engine") << "*** Sygus : passed datatypes check. term size(s) : "; + for( std::map< Node, SearchSizeInfo * >::iterator it = d_szinfo.begin(); it != d_szinfo.end(); ++it ){ + SearchSizeInfo * s = it->second; + Trace("cegqi-engine") << s->d_curr_search_size << " "; } - //also try higher levels - return processSubprograms( n[0], depth, odepth ); - }else{ - Trace("sygus-sym-break-debug") << "...program incomplete." << std::endl; + Trace("cegqi-engine") << std::endl; } } - return true; } -Node SygusSymBreak::ProgSearch::getCandidateProgramAtDepth( int depth, Node prog, int curr_depth, Node parent, std::map< TypeNode, int >& var_count, - std::vector< Node >& testers, std::map< Node, std::vector< Node > >& testers_u ) { - Assert( depth>=curr_depth ); - Trace("sygus-sym-break-debug") << "Reconstructing program for " << prog << " at depth " << curr_depth << "/" << depth << " " << prog.getType() << std::endl; - NodeMap::const_iterator it = d_testers.find( prog ); - if( it!=d_testers.end() ){ - Node tst = (*it).second; - testers.push_back( tst ); - testers_u[parent].push_back( tst ); - //Assert( tst[0]==prog ); - int tindex = DatatypesRewriter::isTester( tst );//Datatype::indexOf( tst.getOperator().toExpr() ); - Assert( tindex!=-1 ); - TypeNode tn = prog.getType(); - Assert( tn.isDatatype() ); - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - std::map< int, Node > pre; - if( curr_depth<depth ){ - for( unsigned i=0; i<dt[tindex].getNumArgs(); i++ ){ - Node sel = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[tindex][i].getSelector() ), prog ); - pre[i] = getCandidateProgramAtDepth( depth, sel, curr_depth+1, prog, var_count, testers, testers_u ); - if( pre[i].isNull() ){ - return Node::null(); - } - } +void SygusSymBreakNew::getPossibleCons( const Datatype& dt, TypeNode tn, std::vector< bool >& pcons ) { + Assert( pcons.size()==dt.getNumConstructors() ); + d_tds->registerSygusType( tn ); + for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ + if( d_tds->isGenericRedundant( tn, i ) ){ + pcons[i] = false; } - return d_parent->d_tds->mkGeneric( dt, tindex, var_count, pre ); - }else{ - Trace("sygus-sym-break-debug") << "...failure." << std::endl; - return Node::null(); } } -bool SygusSymBreak::processCurrentProgram( Node a, TypeNode at, int depth, Node prog, - std::vector< Node >& testers, std::map< Node, std::vector< Node > >& testers_u, - std::map< TypeNode, int >& var_count ) { - Assert( a.getType()==at ); - std::map< Node, bool >::iterator it = d_redundant[at].find( prog ); - bool red; - if( it==d_redundant[at].end() ){ - Trace("sygus-sym-break") << "Currently considering program : " << prog << " at depth " << depth << " for " << a << std::endl; - Node progr = d_tds->getNormalized( at, prog ); - Node rep_prog; - std::map< Node, Node >::iterator itnp = d_normalized_to_orig[at].find( progr ); - int tsize = d_tds->getSygusTermSize( prog ); - if( itnp==d_normalized_to_orig[at].end() ){ - d_normalized_to_orig[at][progr] = prog; - if( progr.getKind()==SKOLEM && d_tds->getSygusTypeForVar( progr )==at ){ - Trace("sygus-nf") << "* Sygus sym break : " << prog << " rewrites to variable " << progr << " of same type as self" << std::endl; - d_redundant[at][prog] = true; - red = true; - }else{ - d_redundant[at][prog] = false; - red = false; - Trace("sygus-nf-reg") << "*** Sygus normal form : normal form of " << prog << " is " << progr << std::endl; - } - }else{ - rep_prog = itnp->second; - if( tsize<d_normalized_to_term_size[at][progr] ){ - d_normalized_to_orig[at][progr] = prog; - Trace("sygus-nf-debug") << "Program is redundant, but has smaller size than " << rep_prog << std::endl; - d_redundant[at].erase( rep_prog ); - d_redundant[at][prog] = false; - red = false; - Trace("sygus-nf-reg") << "*** Sygus normal form : normal form of " << prog << " is " << progr << " (redundant but smaller than " << rep_prog << ") " << std::endl; - }else{ - Assert( prog!=itnp->second ); - d_redundant[at][prog] = true; - red = true; - Trace("sygus-nf") << "* Sygus sym break : " << prog << " and " << rep_prog << " both rewrite to " << progr << std::endl; - Trace("sygus-nf-debug") << " sizes : " << tsize << " " << d_normalized_to_term_size[at][progr] << std::endl; - } +bool SygusSymBreakNew::debugTesters( Node n, Node vn, int ind, std::vector< Node >& lemmas ) { + Assert( vn.getKind()==kind::APPLY_CONSTRUCTOR ); + if( Trace.isOn("sygus-sb-warn") ){ + Node prog_sz = NodeManager::currentNM()->mkNode( kind::DT_SIZE, n ); + Node prog_szv = d_td->getValuation().getModel()->getValue( prog_sz ); + for( int i=0; i<ind; i++ ){ + Trace("sygus-sb-warn") << " "; } - if( !red ){ - d_normalized_to_term_size[at][progr] = tsize; - }else{ - Assert( !testers.empty() ); - bool conflict_gen_set = false; - if( options::sygusNormalFormGlobalGen() ){ - bool narrow = false; - Trace("sygus-nf-gen-debug") << "Tester tree is : " << std::endl; - for( std::map< Node, std::vector< Node > >::iterator it = testers_u.begin(); it != testers_u.end(); ++it ){ - Trace("sygus-nf-gen-debug") << " " << it->first << " -> " << std::endl; - for( unsigned i=0; i<it->second.size(); i++ ){ - Trace("sygus-nf-gen-debug") << " " << it->second[i] << std::endl; - } - } - Trace("sygus-nf-gen-debug") << std::endl; - - //generalize conflict - if( prog.getNumChildren()>0 ){ - Assert( !testers.empty() ); - d_tds->registerSygusType( at ); - //Trace("sygus-nf-gen-debug") << "Testers are : " << std::endl; - //for( unsigned i=0; i<testers.size(); i++ ){ - // Trace("sygus-nf-gen-debug") << "* " << testers[i] << std::endl; - //} - Assert( testers[0][0]==a ); - Assert( prog.getNumChildren()==testers_u[a].size() ); - //get the normal form for each child - Kind parentKind = prog.getKind(); - Kind parentOpKind = prog.getOperator().getKind(); - Trace("sygus-nf-gen-debug") << "Parent kind is " << parentKind << " " << parentOpKind << std::endl; - //std::map< int, Node > norm_children; - - //arguments that are relevant - std::map< unsigned, bool > rlv; - //testers that are irrelevant - std::map< Node, bool > irrlv_tst; - - std::vector< Node > children; - std::vector< TypeNode > children_stype; - std::vector< Node > nchildren; - for( unsigned i=0; i<testers_u[a].size(); i++ ){ - TypeNode tn = testers_u[a][i][0].getType(); - children.push_back( prog[i] ); - children_stype.push_back( tn ); - Node nc = d_tds->getNormalized( tn, prog[i], true ); - //norm_children[i] = nc; - rlv[i] = true; - nchildren.push_back( nc ); - Trace("sygus-nf-gen") << "- child " << i << " normalizes to " << nc << std::endl; - } - if( testers_u[a].size()>1 ){ - bool finished = false; - const Datatype & pdt = ((DatatypeType)(at).toType()).getDatatype(); - int pc = DatatypesRewriter::isTester( testers[0] );//Datatype::indexOf( testers[0].getOperator().toExpr() ); - Assert( pc!=-1 ); - // [1] determine a minimal subset of the arguments that the rewriting depended on - //quick checks based on constants - for( unsigned i=0; i<nchildren.size(); i++ ){ - Node arg = nchildren[i]; - if( arg.isConst() ){ - if( parentOpKind==kind::BUILTIN ){ - Trace("sygus-nf-gen") << "-- constant arg " <<i << " under builtin operator." << std::endl; - if( !processConstantArg( at, pdt, pc, parentKind, i, arg, rlv ) ){ - Trace("sygus-nf") << " - argument " << i << " is singularly redundant." << std::endl; - for( std::map< unsigned, bool >::iterator itr = rlv.begin(); itr != rlv.end(); ++itr ){ - if( itr->first!=i ){ - rlv[itr->first] = false; - } - } - narrow = true; - finished = true; - break; - } - } - } - } - - if( !finished ){ - // [2] check replacing each argument with a fresh variable gives the same result - Node progc = prog; - if( options::sygusNormalFormGlobalArg() ){ - bool argChanged = false; - Trace("sygus-nf-gen-debug") << "Check replacements on " << prog << " " << prog.getKind() << std::endl; - for( unsigned i=0; i<prog.getNumChildren(); i++ ){ - Node prev = children[i]; - children[i] = d_tds->getVarInc( children_stype[i], var_count ); - if( parentOpKind!=kind::BUILTIN ){ - children.insert( children.begin(), prog.getOperator() ); - } - Node progcn = NodeManager::currentNM()->mkNode( prog.getKind(), children ); - if( parentOpKind!=kind::BUILTIN ){ - children.erase( children.begin(), children.begin() + 1 ); - } - Node progcr = Rewriter::rewrite( progcn ); - Trace("sygus-nf-gen-debug") << "Var replace argument " << i << " : " << progcn << " -> " << progcr << std::endl; - if( progcr==progr ){ - //this argument is not relevant, continue with it remaining as variable - rlv[i] = false; - argChanged = true; - narrow = true; - Trace("sygus-nf") << " - argument " << i << " is not relevant." << std::endl; - }else{ - //go back to original - children[i] = prev; - var_count[children_stype[i]]--; - } - } - if( argChanged ){ - progc = NodeManager::currentNM()->mkNode( prog.getKind(), children ); - } - } - Trace("sygus-nf-gen-debug") << "Relevant template (post argument analysis) is : " << progc << std::endl; - - // [3] generalize content - if( options::sygusNormalFormGlobalContent() ){ - std::map< Node, std::vector< Node > > nodes; - std::vector< Node > curr_vars; - std::vector< Node > curr_subs; - collectSubterms( progc, testers[0], testers_u, nodes ); - for( std::map< Node, std::vector< Node > >::iterator it = nodes.begin(); it != nodes.end(); ++it ){ - if( it->second.size()>1 ){ - Trace("sygus-nf-gen-debug") << it->first << " occurs " << it->second.size() << " times, at : " << std::endl; - bool success = true; - TypeNode tn; - for( unsigned j=0; j<it->second.size(); j++ ){ - Trace("sygus-nf-gen-debug") << " " << it->second[j] << " "; - TypeNode tnc = it->second[j][0].getType(); - if( !tn.isNull() && tn!=tnc ){ - success = false; - } - tn = tnc; - } - Trace("sygus-nf-gen-debug") << std::endl; - if( success ){ - Node prev = progc; - //try a substitution on all terms of this form simultaneously to see if the content of this subterm is irrelevant - TypeNode tn = it->second[0][0].getType(); - TNode st = it->first; - //we may already have substituted within this subterm - if( !curr_subs.empty() ){ - st = st.substitute( curr_vars.begin(), curr_vars.end(), curr_subs.begin(), curr_subs.end() ); - Trace("sygus-nf-gen-debug") << "...substituted : " << st << std::endl; - } - TNode nv = d_tds->getVarInc( tn, var_count ); - progc = progc.substitute( st, nv ); - Node progcr = Rewriter::rewrite( progc ); - Trace("sygus-nf-gen-debug") << "Var replace content " << st << " : " << progc << " -> " << progcr << std::endl; - if( progcr==progr ){ - narrow = true; - Trace("sygus-nf") << " - content " << st << " is not relevant." << std::endl; - int t_prev = -1; - for( unsigned i=0; i<it->second.size(); i++ ){ - irrlv_tst[it->second[i]] = true; - Trace("sygus-nf-gen-debug") << "By content, " << it->second[i] << " is irrelevant." << std::endl; - int t_curr = std::find( testers.begin(), testers.end(), it->second[i] )-testers.begin(); - Assert( testers[t_curr]==it->second[i] ); - if( t_prev!=-1 ){ - d_lemma_inc_eq[at][prog].push_back( std::pair< int, int >( t_prev, t_curr ) ); - Trace("sygus-nf-gen-debug") << "Which requires " << testers[t_prev][0] << " = " << testers[t_curr][0] << std::endl; - } - t_prev = t_curr; - } - curr_vars.push_back( st ); - curr_subs.push_back( nv ); - }else{ - var_count[tn]--; - progc = prev; - } - }else{ - Trace("sygus-nf-gen-debug") << "...content is from multiple grammars, abort." << std::endl; - } - } - } - } - Trace("sygus-nf-gen-debug") << "Relevant template (post content analysis) is : " << progc << std::endl; - } - if( narrow ){ - //relevant testers : root + recursive collection of relevant children - Trace("sygus-nf-gen-debug") << "Collect relevant testers..." << std::endl; - std::vector< Node > rlv_testers; - rlv_testers.push_back( testers[0] ); - for( unsigned i=0; i<testers_u[a].size(); i++ ){ - if( rlv[i] ){ - collectTesters( testers_u[a][i], testers_u, rlv_testers, irrlv_tst ); - } - } - //must guard case : generalized lemma cannot exclude original representation - if( !isSeparation( rep_prog, testers[0], testers_u, rlv_testers ) ){ - //must construct template - Node anc_var; - std::map< TypeNode, Node >::iterator itav = d_anchor_var.find( at ); - if( itav==d_anchor_var.end() ){ - anc_var = NodeManager::currentNM()->mkSkolem( "a", at, "Sygus nf global gen anchor var" ); - d_anchor_var[at] = anc_var; - }else{ - anc_var = itav->second; - } - int status = 0; - Node anc_temp = getSeparationTemplate( at, rep_prog, anc_var, status ); - Trace("sygus-nf") << " -- separation template is " << anc_temp << ", status = " << status << std::endl; - d_lemma_inc_eq_gr[status][at][prog].push_back( anc_temp ); - }else{ - Trace("sygus-nf") << " -- no separation necessary" << std::endl; - } - Trace("sygus-nf-gen-debug") << "Relevant testers : " << std::endl; - for( unsigned i=0; i<testers.size(); i++ ){ - bool rl = std::find( rlv_testers.begin(), rlv_testers.end(), testers[i] )!=rlv_testers.end(); - Trace("sygus-nf-gen-debug") << "* " << testers[i] << " -> " << rl << std::endl; - d_lemma_inc_tst[at][prog].push_back( rl ); - } - - conflict_gen_set = true; - } - } - } - } - if( !conflict_gen_set ){ - for( unsigned i=0; i<testers.size(); i++ ){ - d_lemma_inc_tst[at][prog].push_back( true ); - } - } + Trace("sygus-sb-warn") << n << " : " << vn << " : " << prog_szv << std::endl; + } + TypeNode tn = n.getType(); + const Datatype& dt = ((DatatypeType)tn.toType()).getDatatype(); + int cindex = Datatype::indexOf( vn.getOperator().toExpr() ); + Node tst = DatatypesRewriter::mkTester( n, cindex, dt ); + bool hastst = d_td->getValuation().getModel()->hasTerm( tst ); + Node tstrep = d_td->getValuation().getModel()->getRepresentative( tst ); + if( !hastst || tstrep!=NodeManager::currentNM()->mkConst( true ) ){ + Trace("sygus-sb-warn") << "- has tester : " << tst << " : " << ( hastst ? "true" : "false" ); + Trace("sygus-sb-warn") << ", value=" << tstrep << std::endl; + if( !hastst ){ + Node split = SygusSplitNew::getSygusSplit( d_tds, n, dt ); + Assert( !split.isNull() ); + lemmas.push_back( split ); + return false; } - }else{ - red = it->second; - Trace("sygus-nf-debug") << "Already processed, redundant : " << red << std::endl; } - if( red ){ - if( std::find( d_lemmas_reported[at][prog].begin(), d_lemmas_reported[at][prog].end(), a )==d_lemmas_reported[at][prog].end() ){ - d_lemmas_reported[at][prog].push_back( a ); - Assert( d_lemma_inc_tst[at][prog].size()==testers.size() ); - std::vector< Node > disj; - //get the guard equalities - for( unsigned r=0; r<2; r++ ){ - for( unsigned i=0; i<d_lemma_inc_eq_gr[r][at][prog].size(); i++ ){ - TNode n2 = d_lemma_inc_eq_gr[r][at][prog][i]; - if( r==1 ){ - TNode anc_var = d_anchor_var[at]; - TNode anc = a; - Assert( !anc_var.isNull() ); - n2 = n2.substitute( anc_var, anc ); - } - disj.push_back( a.eqNode( n2 ) ); - } - } - //get the equalities that should be included - for( unsigned i=0; i<d_lemma_inc_eq[at][prog].size(); i++ ){ - TNode n1 = testers[ d_lemma_inc_eq[at][prog][i].first ][0]; - TNode n2 = testers[ d_lemma_inc_eq[at][prog][i].second ][0]; - disj.push_back( n1.eqNode( n2 ).negate() ); - } - //get the testers that should be included - for( unsigned i=0; i<testers.size(); i++ ){ - if( d_lemma_inc_tst[at][prog][i] ){ - disj.push_back( testers[i].negate() ); - } - } - Node lem = disj.size()==1 ? disj[0] : NodeManager::currentNM()->mkNode( OR, disj ); - d_lemmas.push_back( lem ); - Trace("sygus-sym-break-lemma") << "Sym break lemma : " << lem << std::endl; - }else{ - Trace("sygus-sym-break2") << "repeated lemma for " << prog << " from " << a << std::endl; + for( unsigned i=0; i<vn.getNumChildren(); i++ ){ + Node sel = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[cindex].getSelectorInternal( tn.toType(), i ) ), n ); + if( !debugTesters( sel, vn[i], ind+1, lemmas ) ){ + return false; } - //for now, continue adding lemmas (since we are not forcing conflicts) - //return false; } return true; } -bool SygusSymBreak::isSeparation( Node rep_prog, Node tst_curr, std::map< Node, std::vector< Node > >& testers_u, std::vector< Node >& rlv_testers ) { - TypeNode tn = tst_curr[0].getType(); - Trace("sygus-nf-gen-debug") << "is separation " << rep_prog << " " << tst_curr << " " << tn << std::endl; - Node rop = rep_prog.getNumChildren()==0 ? rep_prog : rep_prog.getOperator(); - //we can continue if the tester in question is relevant - if( std::find( rlv_testers.begin(), rlv_testers.end(), tst_curr )!=rlv_testers.end() ){ - int tindex = DatatypesRewriter::isTester( tst_curr ); - Assert( tindex!=-1 ); - //unsigned tindex = Datatype::indexOf( tst_curr.getOperator().toExpr() ); - d_tds->registerSygusType( tn ); - Node op = d_tds->getArgOp( tn, tindex ); - if( op!=rop ){ - Trace("sygus-nf-gen-debug") << "mismatch, success." << std::endl; - return true; - }else if( !testers_u[tst_curr[0]].empty() ){ - Assert( testers_u[tst_curr[0]].size()==rep_prog.getNumChildren() ); - for( unsigned i=0; i<rep_prog.getNumChildren(); i++ ){ - if( isSeparation( rep_prog[i], testers_u[tst_curr[0]][i], testers_u, rlv_testers ) ){ - return true; - } - } +Node SygusSymBreakNew::getCurrentTemplate( Node n, std::map< TypeNode, int >& var_count ) { + if( d_active_terms.find( n )!=d_active_terms.end() ){ + TypeNode tn = n.getType(); + IntMap::const_iterator it = d_testers.find( n ); + Assert( it != d_testers.end() ); + const Datatype& dt = ((DatatypeType)tn.toType()).getDatatype(); + int tindex = (*it).second; + Assert( tindex>=0 ); + Assert( tindex<(int)dt.getNumConstructors() ); + std::vector< Node > children; + children.push_back( Node::fromExpr( dt[tindex].getConstructor() ) ); + for( unsigned i=0; i<dt[tindex].getNumArgs(); i++ ){ + Node sel = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[tindex].getSelectorInternal( tn.toType(), i ) ), n ); + Node cc = getCurrentTemplate( sel, var_count ); + children.push_back( cc ); } - return false; + return NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, children ); }else{ - Trace("sygus-nf-gen-debug") << "not relevant, fail." << std::endl; - return false; + return d_tds->getFreeVarInc( n.getType(), var_count ); } } -Node SygusSymBreak::getSeparationTemplate( TypeNode tn, Node rep_prog, Node anc_var, int& status ) { - Trace("sygus-nf-gen-debug") << "get separation template " << rep_prog << std::endl; - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - if( d_tds->isVar( rep_prog ) ){ - status = 1; - return anc_var; - }else{ - Node rop = rep_prog.getNumChildren()==0 ? rep_prog : rep_prog.getOperator(); - int rop_arg = d_tds->getOpArg( tn, rop ); - Assert( rop_arg>=0 && rop_arg<(int)dt.getNumConstructors() ); - Assert( rep_prog.getNumChildren()==dt[rop_arg].getNumArgs() ); - - std::vector< Node > children; - children.push_back( Node::fromExpr( dt[rop_arg].getConstructor() ) ); - for( unsigned i=0; i<rep_prog.getNumChildren(); i++ ){ - TypeNode tna = TypeNode::fromType( ((SelectorType)dt[rop_arg][i].getType()).getRangeType() ); +Node SygusSymBreakNew::SearchSizeInfo::getOrMkSygusMeasureTerm( std::vector< Node >& lemmas ) { + if( d_sygus_measure_term.isNull() ){ + d_sygus_measure_term = NodeManager::currentNM()->mkSkolem( "mt", NodeManager::currentNM()->integerType() ); + lemmas.push_back( NodeManager::currentNM()->mkNode( kind::GEQ, d_sygus_measure_term, NodeManager::currentNM()->mkConst( Rational(0) ) ) ); + } + return d_sygus_measure_term; +} - int new_status = 0; - Node arg = getSeparationTemplate( tna, rep_prog[i], anc_var, new_status ); - if( new_status==1 ){ - TNode tanc_var = anc_var; - TNode tanc_var_subs = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[rop_arg][i].getSelector() ), anc_var ); - arg = arg.substitute( tanc_var, tanc_var_subs ); - status = 1; - } - children.push_back( arg ); - } - return NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, children ); +Node SygusSymBreakNew::SearchSizeInfo::getOrMkSygusActiveMeasureTerm( std::vector< Node >& lemmas ) { + if( d_sygus_measure_term_active.isNull() ){ + d_sygus_measure_term_active = getOrMkSygusMeasureTerm( lemmas ); } + return d_sygus_measure_term_active; } -bool SygusSymBreak::processConstantArg( TypeNode tnp, const Datatype & pdt, int pc, - Kind k, int i, Node arg, std::map< unsigned, bool >& rlv ) { - Assert( d_tds->hasKind( tnp, k ) ); - if( k==AND || k==OR || ( k==EQUAL && arg.getType().isBoolean() ) || k==XOR || k==IMPLIES || ( k==ITE && i==0 ) ){ - return false; - }else if( d_tds->isIdempotentArg( arg, k, i ) ){ - if( pdt[pc].getNumArgs()==2 ){ - int oi = i==0 ? 1 : 0; - TypeNode otn = TypeNode::fromType( ((SelectorType)pdt[pc][oi].getType()).getRangeType() ); - if( otn==tnp ){ - return false; - } - } - }else if( d_tds->isSingularArg( arg, k, i ) ){ - if( d_tds->hasConst( tnp, arg ) ){ - return false; +Node SygusSymBreakNew::SearchSizeInfo::getFairnessLiteral( unsigned s, TheoryDatatypes * d, std::vector< Node >& lemmas ) { + if( options::sygusFair()!=SYGUS_FAIR_NONE ){ + std::map< unsigned, Node >::iterator it = d_lits.find( s ); + if( it==d_lits.end() ){ + Assert( !d_this.isNull() ); + Node c = NodeManager::currentNM()->mkConst( Rational( s ) ); + Node lit = NodeManager::currentNM()->mkNode( DT_SYGUS_BOUND, d_this, c ); + lit = d->getValuation().ensureLiteral( lit ); + + Trace("sygus-fair") << "******* Sygus : allocate size literal " << s << " for " << d_this << " : " << lit << std::endl; + Trace("cegqi-engine") << "******* Sygus : allocate size literal " << s << " for " << d_this << std::endl; + Node lem = NodeManager::currentNM()->mkNode( kind::OR, lit, lit.negate() ); + Trace("sygus-dec") << "Sygus : Fairness split : " << lem << std::endl; + lemmas.push_back( lem ); + d->getOutputChannel().requirePhase( lit, true ); + + d_lits[s] = lit; + return lit; + }else{ + return it->second; } + }else{ + return Node::null(); } - TypeNode tn = arg.getType(); - return true; } -void SygusSymBreak::collectTesters( Node tst, std::map< Node, std::vector< Node > >& testers_u, std::vector< Node >& testers, std::map< Node, bool >& irrlv_tst ) { - if( irrlv_tst.find( tst )==irrlv_tst.end() ){ - testers.push_back( tst ); - std::map< Node, std::vector< Node > >::iterator it = testers_u.find( tst[0] ); - if( it!=testers_u.end() ){ - for( unsigned i=0; i<it->second.size(); i++ ){ - collectTesters( it->second[i], testers_u, testers, irrlv_tst ); - } +Node SygusSymBreakNew::getNextDecisionRequest( unsigned& priority, std::vector< Node >& lemmas ) { + Trace("sygus-dec-debug") << "SygusSymBreakNew: Get next decision " << std::endl; + for( std::map< Node, Node >::iterator it = d_anchor_to_active_guard.begin(); it != d_anchor_to_active_guard.end(); ++it ){ + if( getGuardStatus( it->second )==0 ){ + Trace("sygus-dec") << "Sygus : Decide next on active guard : " << it->second << "..." << std::endl; + priority = 1; + return it->second; + } + } + for( std::map< Node, SearchSizeInfo * >::iterator it = d_szinfo.begin(); it != d_szinfo.end(); ++it ){ + SearchSizeInfo * s = it->second; + std::vector< Node > new_lit; + Node c_lit = s->getCurrentFairnessLiteral( d_td, lemmas ); + Assert( !c_lit.isNull() ); + int gstatus = getGuardStatus( c_lit ); + if( gstatus==-1 ){ + s->incrementCurrentLiteral(); + c_lit = s->getCurrentFairnessLiteral( d_td, lemmas ); + Assert( !c_lit.isNull() ); + Trace("sygus-dec") << "Sygus : Decide on next lit : " << c_lit << "..." << std::endl; + priority = 1; + return c_lit; + }else if( gstatus==0 ){ + Trace("sygus-dec") << "Sygus : Decide on current lit : " << c_lit << "..." << std::endl; + priority = 1; + return c_lit; } } + return Node::null(); } -void SygusSymBreak::collectSubterms( Node n, Node tst_curr, std::map< Node, std::vector< Node > >& testers_u, std::map< Node, std::vector< Node > >& nodes ) { - if( !d_tds->isVar( n ) ){ - nodes[n].push_back( tst_curr ); - for( unsigned i=0; i<testers_u[tst_curr[0]].size(); i++ ){ - collectSubterms( n[i], testers_u[tst_curr[0]][i], testers_u, nodes ); +int SygusSymBreakNew::getGuardStatus( Node g ) { + bool value; + if( d_td->getValuation().hasSatValue( g, value ) ) { + if( value ){ + return 1; + }else{ + return -1; } + }else{ + return 0; } } + diff --git a/src/theory/datatypes/datatypes_sygus.h b/src/theory/datatypes/datatypes_sygus.h index 155b15e52..7d88447ea 100644 --- a/src/theory/datatypes/datatypes_sygus.h +++ b/src/theory/datatypes/datatypes_sygus.h @@ -2,9 +2,9 @@ /*! \file datatypes_sygus.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -16,8 +16,8 @@ #include "cvc4_private.h" -#ifndef __CVC4__THEORY__DATATYPES__DATATYPES_SYGUS_H -#define __CVC4__THEORY__DATATYPES__DATATYPES_SYGUS_H +#ifndef __CVC4__THEORY__DATATYPES__DATATYPES_SYGUS_NEW_H +#define __CVC4__THEORY__DATATYPES__DATATYPES_SYGUS_NEW_H #include <iostream> #include <map> @@ -27,115 +27,145 @@ #include "context/context.h" #include "context/cdchunk_list.h" #include "context/cdhashmap.h" +#include "context/cdhashset.h" #include "context/cdo.h" +#include "theory/quantifiers/term_database.h" namespace CVC4 { namespace theory { -namespace quantifiers { - class TermDbSygus; -} /* namespace quantifiers */ - namespace datatypes { -class SygusSplit +class TheoryDatatypes; + +class SygusSplitNew { private: quantifiers::TermDbSygus * d_tds; std::map< Node, std::vector< Node > > d_splits; - std::map< TypeNode, std::vector< bool > > d_sygus_nred; - std::map< TypeNode, std::map< int, std::map< int, std::vector< bool > > > > d_sygus_pc_nred; - std::map< TypeNode, std::map< int, std::map< int, std::vector< int > > > > d_sygus_pc_arg_pos; - std::map< TypeNode, TypeNode > d_register; //stores sygus type - // type to (rewritten) to original - std::map< TypeNode, std::map< Node, Node > > d_gen_terms; - std::map< TypeNode, std::map< Node, Node > > d_gen_terms_inactive; - std::map< TypeNode, std::map< Node, bool > > d_gen_redundant; -private: - /** register sygus type */ - void registerSygusType( TypeNode tn ); - /** register sygus operator */ - void registerSygusTypeConstructorArg( TypeNode tnn, const Datatype& dt, TypeNode tnnp, const Datatype& pdt, int csIndex, int sIndex ); - /** consider sygus split */ - bool considerSygusSplitKind( const Datatype& dt, const Datatype& pdt, TypeNode tn, TypeNode tnp, Kind k, Kind parent, int arg ); - bool considerSygusSplitConst( const Datatype& dt, const Datatype& pdt, TypeNode tn, TypeNode tnp, Node c, Kind parent, int arg ); - /** get first occurrence */ - int getFirstArgOccurrence( const DatatypeConstructor& c, const Datatype& dt ); - /** is arg datatype */ - bool isArgDatatype( const DatatypeConstructor& c, int i, const Datatype& dt ); - /** is type match */ - bool isTypeMatch( const DatatypeConstructor& c1, const DatatypeConstructor& c2 ); -private: - // generic cache - bool isGenericRedundant( TypeNode tn, Node g, bool active = true ); public: - SygusSplit( quantifiers::TermDbSygus * tds ) : d_tds( tds ){} - ~SygusSplit(){} + SygusSplitNew( quantifiers::TermDbSygus * tds ) : d_tds( tds ){} + virtual ~SygusSplitNew(){} /** get sygus splits */ void getSygusSplits( Node n, const Datatype& dt, std::vector< Node >& splits, std::vector< Node >& lemmas ); + static Node getSygusSplit( quantifiers::TermDbSygus * tds, Node n, const Datatype& dt ); }; - - - -class SygusSymBreak +class SygusSymBreakNew { private: + TheoryDatatypes * d_td; quantifiers::TermDbSygus * d_tds; context::Context* d_context; - class ProgSearch { - typedef context::CDHashMap< Node, Node, NodeHashFunction > NodeMap; - typedef context::CDHashMap< Node, int, NodeHashFunction > IntMap; - typedef context::CDHashMap< int, int > IntIntMap; - private: - SygusSymBreak * d_parent; - Node getCandidateProgramAtDepth( int depth, Node prog, int curr_depth, Node parent, std::map< TypeNode, int >& var_count, - std::vector< Node >& testers, std::map< Node, std::vector< Node > >& testers_u ); - bool processProgramDepth( int depth ); - bool processSubprograms( Node n, int depth, int odepth ); - bool assignTester( int tindex, Node n, int depth ); + typedef context::CDHashMap< Node, int, NodeHashFunction > IntMap; + typedef context::CDHashMap< Node, Node, NodeHashFunction > NodeMap; + typedef context::CDHashMap< Node, bool, NodeHashFunction > BoolMap; + typedef context::CDChunkList<Node> NodeList; + typedef context::CDHashSet<Node, NodeHashFunction> NodeSet; + IntMap d_testers; + IntMap d_is_const; + NodeMap d_testers_exp; + NodeSet d_active_terms; + IntMap d_currTermSize; + Node d_zero; +private: + std::map< Node, Node > d_term_to_anchor; + std::map< Node, Node > d_term_to_anchor_root; + std::map< Node, unsigned > d_term_to_depth; + std::map< Node, bool > d_is_top_level; + void registerTerm( Node n, std::vector< Node >& lemmas ); + bool computeTopLevel( TypeNode tn, Node n ); +private: + //list of all terms encountered in search at depth + class SearchCache { public: - ProgSearch( SygusSymBreak * p, Node a, context::Context* c ) : - d_parent( p ), d_anchor( a ), d_testers( c ), d_watched_terms( c ), d_watched_count( c ), d_prog_depth( c, 0 ) { - d_anchor_type = d_anchor.getType(); + SearchCache(){} + std::map< TypeNode, std::map< unsigned, std::vector< Node > > > d_search_terms; + std::map< TypeNode, std::map< unsigned, std::vector< Node > > > d_sb_lemmas; + // search values + std::map< TypeNode, std::map< Node, Node > > d_search_val; + std::map< TypeNode, std::map< Node, unsigned > > d_search_val_sz; + std::map< TypeNode, std::map< Node, Node > > d_search_val_b; + std::map< Node, bool > d_search_val_proc; + }; + // anchor -> cache + std::map< Node, SearchCache > d_cache; + Node d_null; + void assertTesterInternal( int tindex, TNode n, Node exp, std::vector< Node >& lemmas ); + // register search term + void registerSearchTerm( TypeNode tn, unsigned d, Node n, bool topLevel, std::vector< Node >& lemmas ); + bool registerSearchValue( Node a, Node n, Node nv, unsigned d, std::vector< Node >& lemmas ); + void registerSymBreakLemma( TypeNode tn, Node lem, unsigned sz, Node e, std::vector< Node >& lemmas ); + void addSymBreakLemmasFor( TypeNode tn, Node t, unsigned d, Node e, std::vector< Node >& lemmas ); + void addSymBreakLemmasFor( TypeNode tn, Node t, unsigned d, std::vector< Node >& lemmas ); + void addSymBreakLemma( TypeNode tn, Node lem, TNode x, TNode n, unsigned lem_sz, unsigned n_depth, std::vector< Node >& lemmas ); +private: + std::map< Node, Node > d_rlv_cond; + Node getRelevancyCondition( Node n ); +private: + std::map< TypeNode, std::map< int, std::map< unsigned, Node > > > d_simple_sb_pred; + std::map< TypeNode, Node > d_free_var; + // user-context dependent if sygus-incremental + std::map< Node, unsigned > d_simple_proc; + //get simple symmetry breaking predicate + Node getSimpleSymBreakPred( TypeNode tn, int tindex, unsigned depth ); + TNode getFreeVar( TypeNode tn ); + Node getTermOrderPredicate( Node n1, Node n2 ); +private: + //should be user-context dependent if sygus in incremental mode + std::map< Node, bool > d_register_st; + void registerSizeTerm( Node e, std::vector< Node >& lemmas ); + class SearchSizeInfo { + public: + SearchSizeInfo( Node t, context::Context* c ) : d_this( t ), d_curr_search_size(0), d_curr_lit( c, 0 ) {} + Node d_this; + std::map< unsigned, Node > d_search_size_exp; + std::map< unsigned, bool > d_search_size; + unsigned d_curr_search_size; + Node d_sygus_measure_term; + Node d_sygus_measure_term_active; + std::vector< Node > d_anchors; + Node getOrMkSygusMeasureTerm( std::vector< Node >& lemmas ); + Node getOrMkSygusActiveMeasureTerm( std::vector< Node >& lemmas ); + public: + /** current cardinality */ + context::CDO< unsigned > d_curr_lit; + std::map< unsigned, Node > d_lits; + Node getFairnessLiteral( unsigned s, TheoryDatatypes * d, std::vector< Node >& lemmas ); + Node getCurrentFairnessLiteral( TheoryDatatypes * d, std::vector< Node >& lemmas ) { + return getFairnessLiteral( d_curr_lit.get(), d, lemmas ); } - ~ProgSearch(){} - Node d_anchor; - NodeMap d_testers; - IntMap d_watched_terms; - IntIntMap d_watched_count; - TypeNode d_anchor_type; - context::CDO<int> d_prog_depth; - void addTester( int tindex, Node n, Node exp ); + /** increment current term size */ + void incrementCurrentLiteral() { d_curr_lit.set( d_curr_lit.get() + 1 ); } }; - std::map< Node, ProgSearch * > d_prog_search; - std::map< TypeNode, std::map< Node, Node > > d_normalized_to_orig; - std::map< TypeNode, std::map< Node, bool > > d_redundant; - std::map< TypeNode, std::map< Node, int > > d_normalized_to_term_size; - std::map< TypeNode, std::map< Node, std::vector< Node > > > d_lemmas_reported; - //which testers to include in the lemma - std::map< TypeNode, std::map< Node, std::vector< bool > > > d_lemma_inc_tst; - //additional equalities to include in the lemma - std::map< TypeNode, std::map< Node, std::vector< std::pair< int, int > > > > d_lemma_inc_eq; - //other equalities - std::map< TypeNode, Node > d_anchor_var; - std::map< TypeNode, std::map< Node, std::vector< Node > > > d_lemma_inc_eq_gr[2]; + std::map< Node, SearchSizeInfo * > d_szinfo; + std::map< Node, Node > d_anchor_to_measure_term; + std::map< Node, Node > d_anchor_to_active_guard; + Node d_generic_measure_term; + void incrementCurrentSearchSize( Node m, std::vector< Node >& lemmas ); + void notifySearchSize( Node m, unsigned s, Node exp, std::vector< Node >& lemmas ); + void registerMeasureTerm( Node m ); + unsigned getSearchSizeFor( Node n ); + unsigned getSearchSizeForAnchor( Node n ); + unsigned getSearchSizeForMeasureTerm( Node m ); +private: + unsigned processSelectorChain( Node n, std::map< TypeNode, Node >& top_level, + std::map< Node, unsigned >& tdepth, std::vector< Node >& lemmas ); + bool debugTesters( Node n, Node vn, int ind, std::vector< Node >& lemmas ); + Node getCurrentTemplate( Node n, std::map< TypeNode, int >& var_count ); + int getGuardStatus( Node g ); private: - Node getAnchor( Node n ); - bool processCurrentProgram( Node a, TypeNode at, int depth, Node prog, - std::vector< Node >& testers, std::map< Node, std::vector< Node > >& testers_u, - std::map< TypeNode, int >& var_count ); - bool processConstantArg( TypeNode tnp, const Datatype & pdt, int pc, Kind k, int i, Node arg, std::map< unsigned, bool >& rlv ); - void collectTesters( Node tst, std::map< Node, std::vector< Node > >& testers_u, std::vector< Node >& testers, std::map< Node, bool >& irrlv_tst ); - void collectSubterms( Node n, Node tst_curr, std::map< Node, std::vector< Node > >& testers_u, std::map< Node, std::vector< Node > >& nodes ); - bool isSeparation( Node rep_prog, Node tst_curr, std::map< Node, std::vector< Node > >& testers_u, std::vector< Node >& rlv_testers ); - Node getSeparationTemplate( TypeNode tn, Node rep_prog, Node anc_var, int& status ); + void assertIsConst( Node n, bool polarity, std::vector< Node >& lemmas ); public: - SygusSymBreak( quantifiers::TermDbSygus * tds, context::Context* c ); - ~SygusSymBreak(); + SygusSymBreakNew( TheoryDatatypes * td, quantifiers::TermDbSygus * tds, context::Context* c ); + ~SygusSymBreakNew(); /** add tester */ - void addTester( int tindex, Node n, Node exp ); - /** lemmas we have generated */ - std::vector< Node > d_lemmas; + void assertTester( int tindex, TNode n, Node exp, std::vector< Node >& lemmas ); + void assertFact( Node n, bool polarity, std::vector< Node >& lemmas ); + void preRegisterTerm( TNode n, std::vector< Node >& lemmas ); + void check( std::vector< Node >& lemmas ); + void getPossibleCons( const Datatype& dt, TypeNode tn, std::vector< bool >& pcons ); +public: + Node getNextDecisionRequest( unsigned& priority, std::vector< Node >& lemmas ); }; } @@ -143,3 +173,4 @@ public: } #endif + diff --git a/src/theory/datatypes/kinds b/src/theory/datatypes/kinds index efee5e876..3ce416b40 100644 --- a/src/theory/datatypes/kinds +++ b/src/theory/datatypes/kinds @@ -7,7 +7,7 @@ theory THEORY_DATATYPES ::CVC4::theory::datatypes::TheoryDatatypes "theory/datatypes/theory_datatypes.h" typechecker "theory/datatypes/theory_datatypes_type_rules.h" -properties check presolve parametric propagate +properties check presolve parametric propagate getNextDecisionRequest rewriter ::CVC4::theory::datatypes::DatatypesRewriter "theory/datatypes/datatypes_rewriter.h" @@ -106,6 +106,18 @@ operator DT_SIZE 1 "datatypes size" typerule DT_SIZE ::CVC4::theory::datatypes::DtSizeTypeRule operator DT_HEIGHT_BOUND 2 "datatypes height bound" -typerule DT_HEIGHT_BOUND ::CVC4::theory::datatypes::DtHeightBoundTypeRule +typerule DT_HEIGHT_BOUND ::CVC4::theory::datatypes::DtBoundTypeRule + +operator DT_SIZE_BOUND 2 "datatypes height bound" +typerule DT_SIZE_BOUND ::CVC4::theory::datatypes::DtBoundTypeRule + +operator DT_SYGUS_BOUND 2 "datatypes sygus bound" +typerule DT_SYGUS_BOUND ::CVC4::theory::datatypes::DtSygusBoundTypeRule + +operator DT_SYGUS_TERM_ORDER 2 "datatypes sygus term order" +typerule DT_SYGUS_TERM_ORDER ::CVC4::theory::datatypes::DtSygusPredTypeRule + +operator DT_SYGUS_IS_CONST 1 "datatypes sygus is constant" +typerule DT_SYGUS_IS_CONST ::CVC4::theory::datatypes::DtSygusPredTypeRule endtheory diff --git a/src/theory/datatypes/theory_datatypes.cpp b/src/theory/datatypes/theory_datatypes.cpp index 1a466ff8a..874f49f1e 100644 --- a/src/theory/datatypes/theory_datatypes.cpp +++ b/src/theory/datatypes/theory_datatypes.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -31,6 +31,7 @@ #include "theory/type_enumerator.h" #include "theory/valuation.h" #include "options/theory_options.h" +#include "options/quantifiers_options.h" using namespace std; using namespace CVC4::kind; @@ -62,12 +63,15 @@ TheoryDatatypes::TheoryDatatypes(Context* c, UserContext* u, OutputChannel& out, // The kinds we are treating as function application in congruence d_equalityEngine.addFunctionKind(kind::APPLY_CONSTRUCTOR); d_equalityEngine.addFunctionKind(kind::APPLY_SELECTOR_TOTAL); - d_equalityEngine.addFunctionKind(kind::DT_SIZE); - d_equalityEngine.addFunctionKind(kind::DT_HEIGHT_BOUND); + //d_equalityEngine.addFunctionKind(kind::DT_SIZE); + //d_equalityEngine.addFunctionKind(kind::DT_HEIGHT_BOUND); + //d_equalityEngine.addFunctionKind(kind::DT_SYGUS_TERM_ORDER); + //d_equalityEngine.addFunctionKind(kind::DT_SYGUS_IS_CONST); d_equalityEngine.addFunctionKind(kind::APPLY_TESTER); //d_equalityEngine.addFunctionKind(kind::APPLY_UF); d_true = NodeManager::currentNM()->mkConst( true ); + d_zero = NodeManager::currentNM()->mkConst( Rational(0) ); d_dtfCounter = 0; d_sygus_split = NULL; @@ -134,11 +138,19 @@ TNode TheoryDatatypes::getEqcConstructor( TNode r ) { } void TheoryDatatypes::check(Effort e) { - if (done() && !fullEffort(e)) { + if (done() && e<EFFORT_FULL) { return; } Assert( d_pending.empty() && d_pending_merge.empty() ); d_addedLemma = false; + + if( e == EFFORT_LAST_CALL ){ + Assert( d_sygus_sym_break ); + std::vector< Node > lemmas; + d_sygus_sym_break->check( lemmas ); + doSendLemmas( lemmas ); + return; + } TimerStat::CodeTimer checkTimer(d_checkTime); @@ -273,7 +285,7 @@ void TheoryDatatypes::check(Effort e) { consIndex = fconsIndex!=-1 ? fconsIndex : consIndex; } - if( needSplit && consIndex!=-1 ) { + if( needSplit ) { if( dt.getNumConstructors()==1 ){ //this may not be necessary? //if only one constructor, then this term must be this constructor @@ -283,7 +295,8 @@ void TheoryDatatypes::check(Effort e) { Trace("datatypes-infer") << "DtInfer : 1-cons (full) : " << t << std::endl; d_infer.push_back( t ); }else{ - if( options::dtBinarySplit() ){ + Assert( consIndex!=-1 || dt.isSygus() ); + if( options::dtBinarySplit() && consIndex!=-1 ){ Node test = DatatypesRewriter::mkTester( n, consIndex, dt ); Trace("dt-split") << "*************Split for possible constructor " << dt[consIndex] << " for " << n << endl; test = Rewriter::rewrite( test ); @@ -296,8 +309,10 @@ void TheoryDatatypes::check(Effort e) { Trace("dt-split") << "*************Split for constructors on " << n << endl; std::vector< Node > children; if( dt.isSygus() && d_sygus_split ){ + Trace("dt-sygus") << "DtSygus : split on " << n << std::endl; std::vector< Node > lemmas; d_sygus_split->getSygusSplits( n, dt, children, lemmas ); + Trace("dt-sygus") << "Finished compute split, returned " << lemmas.size() << " lemmas." << std::endl; for( unsigned i=0; i<lemmas.size(); i++ ){ Trace("dt-lemma-sygus") << "Dt sygus lemma : " << lemmas[i] << std::endl; doSendLemma( lemmas[i] ); @@ -360,6 +375,10 @@ void TheoryDatatypes::check(Effort e) { } } +bool TheoryDatatypes::needsCheckLastEffort() { + return d_sygus_sym_break!=NULL; +} + void TheoryDatatypes::flushPendingFacts(){ doPendingMerges(); //pending lemmas: used infrequently, only for definitional lemmas @@ -403,9 +422,7 @@ void TheoryDatatypes::flushPendingFacts(){ } } Trace("dt-lemma") << "Datatypes lemma : " << lem << std::endl; - if( doSendLemma( lem ) ){ - d_addedLemma = true; - } + doSendLemma( lem ); }else{ assertFact( fact, exp ); d_addedFact = true; @@ -435,12 +452,22 @@ bool TheoryDatatypes::doSendLemma( Node lem ) { Trace("dt-lemma-send") << "TheoryDatatypes::doSendLemma : " << lem << std::endl; d_lemmas_produced_c[lem] = true; d_out->lemma( lem ); + d_addedLemma = true; return true; }else{ return false; } } - +bool TheoryDatatypes::doSendLemmas( std::vector< Node >& lemmas ){ + bool ret = false; + for( unsigned i=0; i<lemmas.size(); i++ ){ + bool cret = doSendLemma( lemmas[i] ); + ret = ret || cret; + } + lemmas.clear(); + return ret; +} + void TheoryDatatypes::assertFact( Node fact, Node exp ){ Assert( d_pending_merge.empty() ); Trace("datatypes-debug") << "TheoryDatatypes::assertFact : " << fact << std::endl; @@ -452,6 +479,12 @@ void TheoryDatatypes::assertFact( Node fact, Node exp ){ d_equalityEngine.assertPredicate( atom, polarity, exp ); } doPendingMerges(); + // could be sygus-specific + if( d_sygus_sym_break ){ + std::vector< Node > lemmas; + d_sygus_sym_break->assertFact( atom, polarity, lemmas ); + doSendLemmas( lemmas ); + } //add to tester if applicable Node t_arg; int tindex = DatatypesRewriter::isTester( atom, t_arg ); @@ -461,36 +494,22 @@ void TheoryDatatypes::assertFact( Node fact, Node exp ){ EqcInfo* eqc = getOrMakeEqcInfo( rep, true ); addTester( tindex, fact, eqc, rep, t_arg ); Trace("dt-tester") << "Done assert tester." << std::endl; + //do pending merges + doPendingMerges(); + Trace("dt-tester") << "Done pending merges." << std::endl; if( !d_conflict && polarity ){ if( d_sygus_sym_break ){ + Trace("dt-sygus") << "Assert tester to sygus : " << atom << std::endl; //Assert( !d_sygus_util->d_conflict ); - Trace("dt-tester") << "Assert tester to sygus : " << atom << std::endl; - d_sygus_sym_break->addTester( tindex, t_arg, atom ); - Trace("dt-tester") << "Done assert tester to sygus." << std::endl; - for( unsigned i=0; i<d_sygus_sym_break->d_lemmas.size(); i++ ){ - Trace("dt-lemma-sygus") << "Sygus symmetry breaking lemma : " << d_sygus_sym_break->d_lemmas[i] << std::endl; - doSendLemma( d_sygus_sym_break->d_lemmas[i] ); - } - d_sygus_sym_break->d_lemmas.clear(); - /* - if( d_sygus_util->d_conflict ){ - //d_conflict = true; - if( !d_sygus_util->d_conflictNode.isNull() ){ - std::vector< TNode > assumptions; - explain( d_sygus_util->d_conflictNode, assumptions ); - d_conflictNode = mkAnd( assumptions ); - Trace("dt-conflict") << "CONFLICT: sygus symmetry breaking conflict : " << d_conflictNode << std::endl; - d_out->conflict( d_conflictNode ); - } - return; - } - */ + std::vector< Node > lemmas; + d_sygus_sym_break->assertTester( tindex, t_arg, atom, lemmas ); + Trace("dt-sygus") << "Done assert tester to sygus." << std::endl; + doSendLemmas( lemmas ); } } }else{ Trace("dt-tester-debug") << "Assert (non-tester) : " << atom << std::endl; } - doPendingMerges(); Trace("datatypes-debug") << "TheoryDatatypes::assertFact : finished " << fact << std::endl; } @@ -507,8 +526,16 @@ void TheoryDatatypes::preRegisterTerm(TNode n) { d_equalityEngine.addTriggerPredicate(n); break; default: + if( n.getKind()==kind::DT_SIZE ){ + d_out->lemma( NodeManager::currentNM()->mkNode( LEQ, d_zero, n ) ); + } // Function applications/predicates d_equalityEngine.addTerm(n); + if( d_sygus_sym_break ){ + std::vector< Node > lemmas; + d_sygus_sym_break->preRegisterTerm(n, lemmas); + doSendLemmas( lemmas ); + } //d_equalityEngine.addTriggerTerm(n, THEORY_DATATYPES); break; } @@ -519,23 +546,35 @@ void TheoryDatatypes::finishInit() { if( getQuantifiersEngine() && options::ceGuidedInst() ){ quantifiers::TermDbSygus * tds = getQuantifiersEngine()->getTermDatabaseSygus(); Assert( tds!=NULL ); - d_sygus_split = new SygusSplit( tds ); - d_sygus_sym_break = new SygusSymBreak( tds, getSatContext() ); + d_sygus_split = new SygusSplitNew( tds ); + d_sygus_sym_break = new SygusSymBreakNew( this, tds, getSatContext() ); } } Node TheoryDatatypes::expandDefinition(LogicRequest &logicRequest, Node n) { switch( n.getKind() ){ case kind::APPLY_SELECTOR: { + Trace("dt-expand") << "Dt Expand definition : " << n << std::endl; Node selector = n.getOperator(); Expr selectorExpr = selector.toExpr(); - Node sel = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( selectorExpr ), n[0] ); + // APPLY_SELECTOR always applies to an external selector, cindexOf is legal here + size_t cindex = Datatype::cindexOf(selectorExpr); + const Datatype& dt = Datatype::datatypeOf(selectorExpr); + const DatatypeConstructor& c = dt[cindex]; + Node selector_use; + TypeNode ndt = n[0].getType(); + if( options::dtSharedSelectors() ){ + size_t selectorIndex = Datatype::indexOf(selectorExpr); + Trace("dt-expand") << "...selector index = " << selectorIndex << std::endl; + Assert( selectorIndex<c.getNumArgs() ); + selector_use = Node::fromExpr( c.getSelectorInternal( ndt.toType(), selectorIndex ) ); + }else{ + selector_use = selector; + } + Node sel = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, selector_use, n[0] ); if( options::dtRewriteErrorSel() ){ return sel; }else{ - size_t selectorIndex = Datatype::cindexOf(selectorExpr); - const Datatype& dt = Datatype::datatypeOf(selectorExpr); - const DatatypeConstructor& c = dt[selectorIndex]; Expr tester = c.getTester(); Node tst = NodeManager::currentNM()->mkNode( kind::APPLY_TESTER, Node::fromExpr( tester ), n[0] ); tst = Rewriter::rewrite( tst ); @@ -543,7 +582,6 @@ Node TheoryDatatypes::expandDefinition(LogicRequest &logicRequest, Node n) { if( tst==d_true ){ n_ret = sel; }else{ - TypeNode ndt = n[0].getType(); mkExpDefSkolem( selector, ndt, n.getType() ); Node sk = NodeManager::currentNM()->mkNode( kind::APPLY_UF, d_exp_def_skolem[ndt][ selector ], n[0] ); if( tst==NodeManager::currentNM()->mkConst( false ) ){ @@ -599,7 +637,7 @@ Node TheoryDatatypes::ppRewrite(TNode in) { b << in[1]; Debug("tuprec") << "arg " << i << " gets updated to " << in[1] << std::endl; } else { - b << NodeManager::currentNM()->mkNode(kind::APPLY_SELECTOR_TOTAL, Node::fromExpr(dt[0][i].getSelector()), in[0]); + b << NodeManager::currentNM()->mkNode(kind::APPLY_SELECTOR_TOTAL, Node::fromExpr(dt[0].getSelectorInternal( t.toType(), i )), in[0]); Debug("tuprec") << "arg " << i << " copies " << b[b.getNumChildren() - 1] << std::endl; } } @@ -965,7 +1003,8 @@ bool TheoryDatatypes::hasTester( Node n ) { } void TheoryDatatypes::getPossibleCons( EqcInfo* eqc, Node n, std::vector< bool >& pcons ){ - const Datatype& dt = ((DatatypeType)(n.getType()).toType()).getDatatype(); + TypeNode tn = n.getType(); + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); int lindex = getLabelIndex( eqc, n ); pcons.resize( dt.getNumConstructors(), lindex==-1 ); if( lindex!=-1 ){ @@ -982,17 +1021,10 @@ void TheoryDatatypes::getPossibleCons( EqcInfo* eqc, Node n, std::vector< bool > Assert( tindex!=-1 ); pcons[ tindex ] = false; } - } - } -} - -void TheoryDatatypes::getSelectorsForCons( Node r, std::map< int, bool >& sels ) { - NodeIntMap::iterator sel_i = d_selector_apps.find( r ); - if( sel_i != d_selector_apps.end() ){ - int n_sel = (*sel_i).second; - for( int j=0; j<n_sel; j++ ){ - int sindex = Datatype::indexOf( d_selector_apps_data[r][j].getOperator().toExpr() ); - sels[sindex] = true; + //further limit the possibilities based on grammar minimization + if( d_sygus_sym_break && dt.isSygus() ){ + d_sygus_sym_break->getPossibleCons( dt, tn, pcons ); + } } } } @@ -1061,6 +1093,7 @@ void TheoryDatatypes::addTester( int ttindex, Node t, EqcInfo* eqc, Node n, Node NodeIntMap::iterator lbl_i = d_labels.find( n ); Assert( lbl_i != d_labels.end() ); int n_lbl = (*lbl_i).second; + std::map< int, bool > neg_testers; for( int i=0; i<n_lbl; i++ ){ Node ti = d_labels_data[n][i]; Assert( ti.getKind()==NOT ); @@ -1076,6 +1109,8 @@ void TheoryDatatypes::addTester( int ttindex, Node t, EqcInfo* eqc, Node n, Node }else{ //it is redundant return; } + }else{ + neg_testers[jtindex] = true; } } if( !makeConflict ){ @@ -1093,11 +1128,21 @@ void TheoryDatatypes::addTester( int ttindex, Node t, EqcInfo* eqc, Node n, Node Debug("datatypes-labels") << "Labels at " << n_lbl << " / " << dt.getNumConstructors() << std::endl; if( tpolarity ){ instantiate( eqc, n ); + //TODO : and it is not the other testers FIXME + for( int i=0; i<(int)dt.getNumConstructors(); i++ ){ + if( i!=ttindex && neg_testers.find( i )==neg_testers.end() ){ + Assert( n.getKind()!=APPLY_CONSTRUCTOR ); + Node infer = DatatypesRewriter::mkTester( n, i, dt ).negate(); + Trace("datatypes-infer") << "DtInfer : neg label : " << infer << " by " << t << std::endl; + d_infer.push_back( infer ); + d_infer_exp.push_back( t ); + } + } }else{ //check if we have reached the maximum number of testers // in this case, add the positive tester //this should not be done for sygus, since cases may be limited - if( n_lbl==(int)dt.getNumConstructors()-1 && !dt.isSygus() ){ + if( n_lbl==(int)dt.getNumConstructors()-1 ){ std::vector< bool > pcons; getPossibleCons( eqc, n, pcons ); int testerIndex = -1; @@ -1107,7 +1152,7 @@ void TheoryDatatypes::addTester( int ttindex, Node t, EqcInfo* eqc, Node n, Node break; } } - Assert( testerIndex!=-1 ); + Assert( dt.isSygus() || testerIndex!=-1 ); //we must explain why each term in the set of testers for this equivalence class is equal std::vector< Node > eq_terms; NodeBuilder<> nb(kind::AND); @@ -1127,7 +1172,7 @@ void TheoryDatatypes::addTester( int ttindex, Node t, EqcInfo* eqc, Node n, Node } } } - Node t_concl = DatatypesRewriter::mkTester( t_arg, testerIndex, dt ); + Node t_concl = testerIndex==-1 ? NodeManager::currentNM()->mkConst( false ) : DatatypesRewriter::mkTester( t_arg, testerIndex, dt ); Node t_concl_exp = ( nb.getNumChildren() == 1 ) ? nb.getChild( 0 ) : nb; d_pending.push_back( t_concl ); d_pending_exp[ t_concl ] = t_concl_exp; @@ -1257,7 +1302,6 @@ Node TheoryDatatypes::removeUninterpretedConstants( Node n, std::map< Node, Node } } - void TheoryDatatypes::collapseSelector( Node s, Node c ) { Assert( c.getKind()==APPLY_CONSTRUCTOR ); Trace("dt-collapse-sel") << "collapse selector : " << s << " " << c << std::endl; @@ -1273,8 +1317,13 @@ void TheoryDatatypes::collapseSelector( Node s, Node c ) { use_s = s; } if( s.getKind()==kind::APPLY_SELECTOR_TOTAL ){ - //Trace("dt-collapse-sel") << "Indices : " << Datatype::indexOf(c.getOperator().toExpr()) << " " << Datatype::cindexOf(s.getOperator().toExpr()) << std::endl; - wrong = Datatype::indexOf(c.getOperator().toExpr())!=Datatype::cindexOf(s.getOperator().toExpr()); + Expr selectorExpr = s.getOperator().toExpr(); + size_t constructorIndex = Datatype::indexOf(c.getOperator().toExpr()); + const Datatype& dt = Datatype::datatypeOf(selectorExpr); + const DatatypeConstructor& dtc = dt[constructorIndex]; + int selectorIndex = dtc.getSelectorIndexInternal( selectorExpr ); + wrong = selectorIndex<0; + //if( wrong ){ // return; //} @@ -1286,21 +1335,6 @@ void TheoryDatatypes::collapseSelector( Node s, Node c ) { if( options::dtRefIntro() ){ use_s = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, s.getOperator(), use_s ); } - }else{ - if( s.getKind()==DT_SIZE ){ - r = NodeManager::currentNM()->mkNode( DT_SIZE, c ); - if( options::dtRefIntro() ){ - use_s = NodeManager::currentNM()->mkNode( DT_SIZE, use_s ); - } - }else if( s.getKind()==DT_HEIGHT_BOUND ){ - r = NodeManager::currentNM()->mkNode( DT_HEIGHT_BOUND, c, s[1] ); - if( options::dtRefIntro() ){ - use_s = NodeManager::currentNM()->mkNode( DT_HEIGHT_BOUND, use_s, s[1] ); - } - if( r==d_true ){ - return; - } - } } if( !r.isNull() ){ Node rr = Rewriter::rewrite( r ); @@ -1321,7 +1355,7 @@ void TheoryDatatypes::collapseSelector( Node s, Node c ) { eq_exp = c.eqNode( s[0] ); } Trace("datatypes-infer") << "DtInfer : collapse sel"; - Trace("datatypes-infer") << ( wrong ? " wrong" : ""); + //Trace("datatypes-infer") << ( wrong ? " wrong" : ""); Trace("datatypes-infer") << " : " << eq << " by " << eq_exp << std::endl; d_pending.push_back( eq ); d_pending_exp[ eq ] = eq_exp; @@ -1643,13 +1677,6 @@ void TheoryDatatypes::collectTerms( Node n ) { addSelector( n, eqc, rep ); if( n.getKind() == DT_SIZE ){ - Node conc = NodeManager::currentNM()->mkNode( LEQ, NodeManager::currentNM()->mkConst( Rational(0) ), n ); - //must be non-negative - Trace("datatypes-infer") << "DtInfer : non-negative size : " << conc << std::endl; - //d_pending.push_back( conc ); - //d_pending_exp[ conc ] = d_true; - //d_infer.push_back( conc ); - d_pending_lem.push_back( conc ); /* //add size = 0 lemma Node nn = n.eqNode( NodeManager::currentNM()->mkConst( Rational(0) ) ); @@ -1703,14 +1730,19 @@ Node TheoryDatatypes::getInstantiateCons( Node n, const Datatype& dt, int index if( it!=d_inst_map[n].end() ){ return it->second; }else{ - //add constructor to equivalence class - Node k = getTermSkolemFor( n ); - Node n_ic = DatatypesRewriter::getInstCons( k, dt, index ); - //Assert( n_ic==Rewriter::rewrite( n_ic ) ); - n_ic = Rewriter::rewrite( n_ic ); - collectTerms( n_ic ); - d_equalityEngine.addTerm(n_ic); - Debug("dt-enum") << "Made instantiate cons " << n_ic << std::endl; + Node n_ic; + if( n.getKind()==APPLY_CONSTRUCTOR && n.getNumChildren()==0 ){ + n_ic = n; + }else{ + //add constructor to equivalence class + Node k = getTermSkolemFor( n ); + n_ic = DatatypesRewriter::getInstCons( k, dt, index ); + //Assert( n_ic==Rewriter::rewrite( n_ic ) ); + n_ic = Rewriter::rewrite( n_ic ); + collectTerms( n_ic ); + d_equalityEngine.addTerm(n_ic); + Debug("dt-enum") << "Made instantiate cons " << n_ic << std::endl; + } d_inst_map[n][index] = n_ic; return n_ic; } @@ -2258,6 +2290,17 @@ std::pair<bool, Node> TheoryDatatypes::entailmentCheck(TNode lit, const Entailme return make_pair(false, Node::null()); } +Node TheoryDatatypes::getNextDecisionRequest( unsigned& priority ) { + if( d_sygus_sym_break ){ + std::vector< Node > lemmas; + Node ret = d_sygus_sym_break->getNextDecisionRequest( priority, lemmas ); + doSendLemmas( lemmas ); + return ret; + }else{ + return Node::null(); + } +} + } /* namepsace CVC4::theory::datatypes */ } /* namepsace CVC4::theory */ } /* namepsace CVC4 */ diff --git a/src/theory/datatypes/theory_datatypes.h b/src/theory/datatypes/theory_datatypes.h index 98d8d53b1..a0333ed8b 100644 --- a/src/theory/datatypes/theory_datatypes.h +++ b/src/theory/datatypes/theory_datatypes.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,7 +19,6 @@ #ifndef __CVC4__THEORY__DATATYPES__THEORY_DATATYPES_H #define __CVC4__THEORY__DATATYPES__THEORY_DATATYPES_H -#include <ext/hash_set> #include <iostream> #include <map> @@ -29,6 +28,7 @@ #include "theory/theory.h" #include "theory/uf/equality_engine.h" #include "util/hash.h" +#include "expr/attribute.h" namespace CVC4 { namespace theory { @@ -54,6 +54,7 @@ private: NodeList d_infer; NodeList d_infer_exp; Node d_true; + Node d_zero; /** mkAnd */ Node mkAnd( std::vector< TNode >& assumptions ); private: @@ -136,7 +137,6 @@ private: bool hasTester( Node n ); /** get the possible constructors for n */ void getPossibleCons( EqcInfo* eqc, Node n, std::vector< bool >& cons ); - void getSelectorsForCons( Node r, std::map< int, bool >& sels ); /** mkExpDefSkolem */ void mkExpDefSkolem( Node sel, TypeNode dt, TypeNode rt ); /** skolems for terms */ @@ -189,9 +189,6 @@ private: unsigned d_dtfCounter; /** expand definition skolem functions */ std::map< TypeNode, std::map< Node, Node > > d_exp_def_skolem; - /** sygus utilities */ - SygusSplit * d_sygus_split; - SygusSymBreak * d_sygus_sym_break; /** uninterpreted constant to variable map */ std::map< Node, Node > d_uc_to_fresh_var; private: @@ -212,6 +209,7 @@ private: void doPendingMerges(); /** do send lemma */ bool doSendLemma( Node lem ); + bool doSendLemmas( std::vector< Node >& lem ); /** get or make eqc info */ EqcInfo* getOrMakeEqcInfo( TNode n, bool doMake = false ); @@ -257,6 +255,7 @@ public: void eqNotifyDisequal(TNode t1, TNode t2, TNode reason); void check(Effort e); + bool needsCheckLastEffort(); void preRegisterTerm(TNode n); void finishInit(); Node expandDefinition(LogicRequest &logicRequest, Node n); @@ -320,6 +319,12 @@ private: bool areDisequal( TNode a, TNode b ); bool areCareDisequal( TNode x, TNode y ); TNode getRepresentative( TNode a ); +private: + /** sygus utilities */ + SygusSplitNew * d_sygus_split; + SygusSymBreakNew * d_sygus_sym_break; +public: + Node getNextDecisionRequest( unsigned& priority ); };/* class TheoryDatatypes */ }/* CVC4::theory::datatypes namespace */ diff --git a/src/theory/datatypes/theory_datatypes_type_rules.h b/src/theory/datatypes/theory_datatypes_type_rules.h index 412b3d7ec..e787ebc49 100644 --- a/src/theory/datatypes/theory_datatypes_type_rules.h +++ b/src/theory/datatypes/theory_datatypes_type_rules.h @@ -2,9 +2,9 @@ /*! \file theory_datatypes_type_rules.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Tim King, Morgan Deters, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -79,10 +79,12 @@ struct DatatypeConstructorTypeRule { Debug("typecheck-idt") << "typecheck cons arg: " << childType << " " << (*tchild_it) << std::endl; TypeNode argumentType = *tchild_it; - if (!childType.isComparableTo(argumentType)) { + if (!childType.isSubtypeOf(argumentType)) { std::stringstream ss; - ss << "bad type for constructor argument:\nexpected: " - << argumentType << "\ngot : " << childType; + ss << "bad type for constructor argument:\n" + << "child type: " << childType << "\n" + << "not subtype: " << argumentType << "\n" + << "in term : " << n; throw TypeCheckingExceptionPrivate(n, ss.str()); } } @@ -308,7 +310,7 @@ class DtSizeTypeRule { } }; /* class DtSizeTypeRule */ -class DtHeightBoundTypeRule { +class DtBoundTypeRule { public: inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) { @@ -317,20 +319,64 @@ class DtHeightBoundTypeRule { if (!t.isDatatype()) { throw TypeCheckingExceptionPrivate( n, - "expecting datatype height bound term to have datatype argument."); + "expecting datatype bound term to have datatype argument."); } if (n[1].getKind() != kind::CONST_RATIONAL) { throw TypeCheckingExceptionPrivate( - n, "datatype height bound must be a constant"); + n, "datatype bound must be a constant"); } if (n[1].getConst<Rational>().getNumerator().sgn() == -1) { throw TypeCheckingExceptionPrivate( - n, "datatype height bound must be non-negative"); + n, "datatype bound must be non-negative"); } } return nodeManager->booleanType(); } -}; /* class DtHeightBoundTypeRule */ +}; /* class DtBoundTypeRule */ + +class DtSygusBoundTypeRule { + public: + inline static TypeNode computeType(NodeManager* nodeManager, TNode n, + bool check) { + if (check) { + if (!n[0].getType().isDatatype()) { + throw TypeCheckingExceptionPrivate( + n, "datatype sygus bound takes a datatype"); + } + if (n[1].getKind() != kind::CONST_RATIONAL) { + throw TypeCheckingExceptionPrivate( + n, "datatype sygus bound must be a constant"); + } + if (n[1].getConst<Rational>().getNumerator().sgn() == -1) { + throw TypeCheckingExceptionPrivate( + n, "datatype sygus bound must be non-negative"); + } + } + return nodeManager->booleanType(); + } +}; /* class DtSygusBoundTypeRule */ + + +class DtSygusPredTypeRule { + public: + inline static TypeNode computeType(NodeManager* nodeManager, TNode n, + bool check) { + if (check) { + TypeNode tn = n[0].getType(); + if (!tn.isDatatype() || !((DatatypeType)tn.toType()).getDatatype().isSygus()) { + throw TypeCheckingExceptionPrivate( + n, "datatype sygus predicate expecting terms of sygus type"); + } + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + if (tn!=n[i].getType()) { + throw TypeCheckingExceptionPrivate( + n, "datatype sygus predicate expecting two terms of the same type"); + } + } + } + return nodeManager->booleanType(); + } +}; /* class DtSygusPredTypeRule */ } /* CVC4::theory::datatypes namespace */ } /* CVC4::theory namespace */ diff --git a/src/theory/datatypes/type_enumerator.cpp b/src/theory/datatypes/type_enumerator.cpp index 60d319da3..ee03b7815 100644 --- a/src/theory/datatypes/type_enumerator.cpp +++ b/src/theory/datatypes/type_enumerator.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/datatypes/type_enumerator.h b/src/theory/datatypes/type_enumerator.h index 5889090aa..8cf4ab3d9 100644 --- a/src/theory/datatypes/type_enumerator.h +++ b/src/theory/datatypes/type_enumerator.h @@ -2,9 +2,9 @@ /*! \file type_enumerator.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tim King + ** Andrew Reynolds, Morgan Deters, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/example/ecdata.cpp b/src/theory/example/ecdata.cpp index a85db3cc9..427146429 100644 --- a/src/theory/example/ecdata.cpp +++ b/src/theory/example/ecdata.cpp @@ -2,9 +2,9 @@ /*! \file ecdata.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/example/ecdata.h b/src/theory/example/ecdata.h index cd582c150..475d0e615 100644 --- a/src/theory/example/ecdata.h +++ b/src/theory/example/ecdata.h @@ -2,9 +2,9 @@ /*! \file ecdata.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/example/theory_uf_tim.cpp b/src/theory/example/theory_uf_tim.cpp index 825c8fbe4..da87058fe 100644 --- a/src/theory/example/theory_uf_tim.cpp +++ b/src/theory/example/theory_uf_tim.cpp @@ -2,9 +2,9 @@ /*! \file theory_uf_tim.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/example/theory_uf_tim.h b/src/theory/example/theory_uf_tim.h index 7470b4d57..a62d9fbe5 100644 --- a/src/theory/example/theory_uf_tim.h +++ b/src/theory/example/theory_uf_tim.h @@ -2,9 +2,9 @@ /*! \file theory_uf_tim.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/fp/theory_fp.cpp b/src/theory/fp/theory_fp.cpp index f3212277b..6c8e49e74 100644 --- a/src/theory/fp/theory_fp.cpp +++ b/src/theory/fp/theory_fp.cpp @@ -2,9 +2,9 @@ /*! \file theory_fp.cpp ** \verbatim ** Top contributors (to current version): - ** Martin Brain, Tim King + ** Martin Brain, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/fp/theory_fp.h b/src/theory/fp/theory_fp.h index b1915e3b7..0355ed811 100644 --- a/src/theory/fp/theory_fp.h +++ b/src/theory/fp/theory_fp.h @@ -2,9 +2,9 @@ /*! \file theory_fp.h ** \verbatim ** Top contributors (to current version): - ** Martin Brain, Tim King + ** Martin Brain, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/fp/theory_fp_rewriter.cpp b/src/theory/fp/theory_fp_rewriter.cpp index 612112db7..ba4bf9228 100644 --- a/src/theory/fp/theory_fp_rewriter.cpp +++ b/src/theory/fp/theory_fp_rewriter.cpp @@ -2,10 +2,10 @@ /*! \file theory_fp_rewriter.cpp ** \verbatim ** Top contributors (to current version): - ** Martin Brain, Tim King, Clark Barrett + ** Martin Brain, Paul Meng, Tim King ** Copyright (c) 2013 University of Oxford ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/fp/theory_fp_rewriter.h b/src/theory/fp/theory_fp_rewriter.h index 93547b4de..d2a9a0466 100644 --- a/src/theory/fp/theory_fp_rewriter.h +++ b/src/theory/fp/theory_fp_rewriter.h @@ -2,9 +2,9 @@ /*! \file theory_fp_rewriter.h ** \verbatim ** Top contributors (to current version): - ** Martin Brain + ** Martin Brain, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/fp/theory_fp_type_rules.h b/src/theory/fp/theory_fp_type_rules.h index edda93de8..296a2f475 100644 --- a/src/theory/fp/theory_fp_type_rules.h +++ b/src/theory/fp/theory_fp_type_rules.h @@ -2,9 +2,9 @@ /*! \file theory_fp_type_rules.h ** \verbatim ** Top contributors (to current version): - ** Martin Brain + ** Martin Brain, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/idl/idl_assertion.cpp b/src/theory/idl/idl_assertion.cpp index 1d42f771d..7738c6c2f 100644 --- a/src/theory/idl/idl_assertion.cpp +++ b/src/theory/idl/idl_assertion.cpp @@ -2,9 +2,9 @@ /*! \file idl_assertion.cpp ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/idl/idl_assertion.h b/src/theory/idl/idl_assertion.h index 5db1db0fe..e70e2d4b8 100644 --- a/src/theory/idl/idl_assertion.h +++ b/src/theory/idl/idl_assertion.h @@ -2,9 +2,9 @@ /*! \file idl_assertion.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/idl/idl_assertion_db.cpp b/src/theory/idl/idl_assertion_db.cpp index c08cb644f..55ef29bbc 100644 --- a/src/theory/idl/idl_assertion_db.cpp +++ b/src/theory/idl/idl_assertion_db.cpp @@ -2,9 +2,9 @@ /*! \file idl_assertion_db.cpp ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/idl/idl_assertion_db.h b/src/theory/idl/idl_assertion_db.h index 6481deba5..a89c8e483 100644 --- a/src/theory/idl/idl_assertion_db.h +++ b/src/theory/idl/idl_assertion_db.h @@ -2,9 +2,9 @@ /*! \file idl_assertion_db.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/idl/idl_model.cpp b/src/theory/idl/idl_model.cpp index 4d2071962..5096c1197 100644 --- a/src/theory/idl/idl_model.cpp +++ b/src/theory/idl/idl_model.cpp @@ -2,9 +2,9 @@ /*! \file idl_model.cpp ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/idl/idl_model.h b/src/theory/idl/idl_model.h index 35663a256..e4a9f05ef 100644 --- a/src/theory/idl/idl_model.h +++ b/src/theory/idl/idl_model.h @@ -2,9 +2,9 @@ /*! \file idl_model.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/idl/theory_idl.cpp b/src/theory/idl/theory_idl.cpp index 8f85dc9b0..60d04fe4d 100644 --- a/src/theory/idl/theory_idl.cpp +++ b/src/theory/idl/theory_idl.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/idl/theory_idl.h b/src/theory/idl/theory_idl.h index 1d2aecad6..625770869 100644 --- a/src/theory/idl/theory_idl.h +++ b/src/theory/idl/theory_idl.h @@ -2,9 +2,9 @@ /*! \file theory_idl.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/interrupted.h b/src/theory/interrupted.h index e56f3513c..d53ee9d54 100644 --- a/src/theory/interrupted.h +++ b/src/theory/interrupted.h @@ -2,9 +2,9 @@ /*! \file interrupted.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/ite_utilities.cpp b/src/theory/ite_utilities.cpp index 419e5b4dd..6d81dbab0 100644 --- a/src/theory/ite_utilities.cpp +++ b/src/theory/ite_utilities.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Kshitij Bansal ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -1092,7 +1092,7 @@ bool ITESimplifier::leavesAreConst(TNode e, TheoryId tid) return true; } - hash_map<Node, bool, NodeHashFunction>::iterator it; + unordered_map<Node, bool, NodeHashFunction>::iterator it; it = d_leavesConstCache.find(e); if (it != d_leavesConstCache.end()) { return (*it).second; @@ -1173,7 +1173,7 @@ Node ITESimplifier::simpConstants(TNode simpContext, TNode iteNode, TNode simpVa Node ITESimplifier::getSimpVar(TypeNode t) { - std::hash_map<TypeNode, Node, TypeNode::HashFunction>::iterator it; + std::unordered_map<TypeNode, Node, TypeNode::HashFunction>::iterator it; it = d_simpVars.find(t); if (it != d_simpVars.end()) { return (*it).second; @@ -1231,7 +1231,7 @@ Node ITESimplifier::createSimpContext(TNode c, Node& iteNode, Node& simpVar) d_simpContextCache[c] = result; return result; } -typedef std::hash_set<Node, NodeHashFunction> NodeSet; +typedef std::unordered_set<Node, NodeHashFunction> NodeSet; void countReachable_(Node x, Kind k, NodeSet& visited, uint32_t& reached){ if(visited.find(x) != visited.end()){ return; diff --git a/src/theory/ite_utilities.h b/src/theory/ite_utilities.h index 98141d4e3..4aad9a3f0 100644 --- a/src/theory/ite_utilities.h +++ b/src/theory/ite_utilities.h @@ -2,9 +2,9 @@ /*! \file ite_utilities.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -22,8 +22,7 @@ #ifndef __CVC4__ITE_UTILITIES_H #define __CVC4__ITE_UTILITIES_H -#include <ext/hash_map> -#include <ext/hash_set> +#include <unordered_map> #include <vector> #include "expr/node.h" @@ -80,7 +79,7 @@ public: size_t cache_size() const { return d_cache.size(); } private: - typedef std::hash_map<Node, bool, NodeHashFunction> NodeBoolMap; + typedef std::unordered_map<Node, bool, NodeHashFunction> NodeBoolMap; NodeBoolMap d_cache; }; @@ -100,7 +99,7 @@ public: } void clear(); private: - typedef std::hash_map<Node, uint32_t, NodeHashFunction> NodeCountMap; + typedef std::unordered_map<Node, uint32_t, NodeHashFunction> NodeCountMap; NodeCountMap d_reachCount; bool d_skipVariables; @@ -131,7 +130,7 @@ public: size_t cache_size() const; private: - typedef std::hash_map<Node, uint32_t, NodeHashFunction> NodeCountMap; + typedef std::unordered_map<Node, uint32_t, NodeHashFunction> NodeCountMap; NodeCountMap d_termITEHeight; }; /* class TermITEHeightCounter */ @@ -158,7 +157,7 @@ private: std::vector<Node>* d_assertions; IncomingArcCounter d_incoming; - typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeMap; NodeMap d_compressed; void reset(); @@ -206,7 +205,7 @@ private: // constant // or termITE(cnd, ConstantIte, ConstantIte) typedef std::vector<Node> NodeVec; - typedef std::hash_map<Node, NodeVec*, NodeHashFunction > ConstantLeavesMap; + typedef std::unordered_map<Node, NodeVec*, NodeHashFunction > ConstantLeavesMap; ConstantLeavesMap d_constantLeaves; // d_constantLeaves satisfies the following invariants: @@ -249,23 +248,23 @@ private: return hash; } };/* struct ITESimplifier::NodePairHashFunction */ - typedef std::hash_map<NodePair, Node, NodePairHashFunction> NodePairMap; + typedef std::unordered_map<NodePair, Node, NodePairHashFunction> NodePairMap; NodePairMap d_constantIteEqualsConstantCache; NodePairMap d_replaceOverCache; NodePairMap d_replaceOverTermIteCache; Node replaceOver(Node n, Node replaceWith, Node simpVar); Node replaceOverTermIte(Node term, Node simpAtom, Node simpVar); - std::hash_map<Node, bool, NodeHashFunction> d_leavesConstCache; + std::unordered_map<Node, bool, NodeHashFunction> d_leavesConstCache; bool leavesAreConst(TNode e, theory::TheoryId tid); bool leavesAreConst(TNode e); NodePairMap d_simpConstCache; Node simpConstants(TNode simpContext, TNode iteNode, TNode simpVar); - std::hash_map<TypeNode, Node, TypeNode::HashFunction> d_simpVars; + std::unordered_map<TypeNode, Node, TypeNode::HashFunction> d_simpVars; Node getSimpVar(TypeNode t); - typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeMap; NodeMap d_simpContextCache; Node createSimpContext(TNode c, Node& iteNode, Node& simpVar); @@ -314,7 +313,7 @@ private: Node d_true; Node d_false; - typedef std::hash_map<TNode, Node, TNodeHashFunction> TNodeMap; + typedef std::unordered_map<TNode, Node, TNodeHashFunction> TNodeMap; class CareSetPtr; class CareSetPtrVal { diff --git a/src/theory/logic_info.cpp b/src/theory/logic_info.cpp index 0e4ccf0f7..ad3a010c0 100644 --- a/src/theory/logic_info.cpp +++ b/src/theory/logic_info.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -36,7 +36,7 @@ LogicInfo::LogicInfo() : d_sharingTheories(0), d_integers(true), d_reals(true), - d_linear(true),// for now, "everything enabled" doesn't include non-linear arith + d_linear(false), d_differenceLogic(false), d_cardinalityConstraints(false), d_locked(false) { @@ -340,21 +340,25 @@ void LogicInfo::setLogicString(std::string logicString) throw(IllegalArgumentExc // the "all theories included" logic, no quantifiers enableEverything(); disableQuantifiers(); + arithNonLinear(); p += 16; } else if(!strcmp(p, "QF_ALL")) { // the "all theories included" logic, no quantifiers enableEverything(); disableQuantifiers(); + arithNonLinear(); p += 6; } else if(!strcmp(p, "ALL_SUPPORTED")) { // the "all theories included" logic, with quantifiers enableEverything(); enableQuantifiers(); + arithNonLinear(); p += 13; } else if(!strcmp(p, "ALL")) { // the "all theories included" logic, with quantifiers enableEverything(); enableQuantifiers(); + arithNonLinear(); p += 3; } else { if(!strncmp(p, "QF_", 3)) { diff --git a/src/theory/logic_info.h b/src/theory/logic_info.h index 6efdd4615..a502041f5 100644 --- a/src/theory/logic_info.h +++ b/src/theory/logic_info.h @@ -2,9 +2,9 @@ /*! \file logic_info.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Dejan Jovanovic + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/output_channel.h b/src/theory/output_channel.h index 4ca113eed..355936d77 100644 --- a/src/theory/output_channel.h +++ b/src/theory/output_channel.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Liana Hadarean, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/alpha_equivalence.cpp b/src/theory/quantifiers/alpha_equivalence.cpp index a5fd34c64..6af5bd92f 100644 --- a/src/theory/quantifiers/alpha_equivalence.cpp +++ b/src/theory/quantifiers/alpha_equivalence.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/alpha_equivalence.h b/src/theory/quantifiers/alpha_equivalence.h index 8e7556eb6..3c04393d2 100644 --- a/src/theory/quantifiers/alpha_equivalence.h +++ b/src/theory/quantifiers/alpha_equivalence.h @@ -2,9 +2,9 @@ /*! \file alpha_equivalence.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/ambqi_builder.cpp b/src/theory/quantifiers/ambqi_builder.cpp index bc638080f..1bab682f4 100644 --- a/src/theory/quantifiers/ambqi_builder.cpp +++ b/src/theory/quantifiers/ambqi_builder.cpp @@ -2,9 +2,9 @@ /*! \file ambqi_builder.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/ambqi_builder.h b/src/theory/quantifiers/ambqi_builder.h index 68cb27038..89cd8b6a8 100644 --- a/src/theory/quantifiers/ambqi_builder.h +++ b/src/theory/quantifiers/ambqi_builder.h @@ -2,9 +2,9 @@ /*! \file ambqi_builder.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Clark Barrett + ** Morgan Deters, Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/anti_skolem.cpp b/src/theory/quantifiers/anti_skolem.cpp index 908aeecfd..e63dc6abb 100644 --- a/src/theory/quantifiers/anti_skolem.cpp +++ b/src/theory/quantifiers/anti_skolem.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/anti_skolem.h b/src/theory/quantifiers/anti_skolem.h index c996b171e..078675420 100644 --- a/src/theory/quantifiers/anti_skolem.h +++ b/src/theory/quantifiers/anti_skolem.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/bounded_integers.cpp b/src/theory/quantifiers/bounded_integers.cpp index 41face8f7..903a729f5 100644 --- a/src/theory/quantifiers/bounded_integers.cpp +++ b/src/theory/quantifiers/bounded_integers.cpp @@ -2,9 +2,9 @@ /*! \file bounded_integers.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -778,7 +778,7 @@ Node BoundedIntegers::matchBoundVar( Node v, Node t, Node e ){ if( e.getKind()==kind::APPLY_CONSTRUCTOR ){ u = matchBoundVar( v, t[i], e[i] ); }else{ - Node se = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[index][i].getSelector() ), e ); + Node se = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[index].getSelectorInternal( e.getType().toType(), i ) ), e ); u = matchBoundVar( v, t[i], se ); } if( !u.isNull() ){ diff --git a/src/theory/quantifiers/bounded_integers.h b/src/theory/quantifiers/bounded_integers.h index f367b328c..f0a3a85f5 100644 --- a/src/theory/quantifiers/bounded_integers.h +++ b/src/theory/quantifiers/bounded_integers.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/candidate_generator.cpp b/src/theory/quantifiers/candidate_generator.cpp index 17c8e0300..01e71be95 100644 --- a/src/theory/quantifiers/candidate_generator.cpp +++ b/src/theory/quantifiers/candidate_generator.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/candidate_generator.h b/src/theory/quantifiers/candidate_generator.h index 4fc6969fc..dd71ef56e 100644 --- a/src/theory/quantifiers/candidate_generator.h +++ b/src/theory/quantifiers/candidate_generator.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/ce_guided_instantiation.cpp b/src/theory/quantifiers/ce_guided_instantiation.cpp index 08d705fa8..cb8e6f200 100644 --- a/src/theory/quantifiers/ce_guided_instantiation.cpp +++ b/src/theory/quantifiers/ce_guided_instantiation.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -16,9 +16,10 @@ #include "expr/datatype.h" #include "options/quantifiers_options.h" +#include "options/datatypes_options.h" #include "smt/smt_statistics_registry.h" #include "theory/quantifiers/first_order_model.h" -#include "theory/quantifiers/term_database.h" +#include "theory/quantifiers/term_database_sygus.h" #include "theory/theory_engine.h" #include "prop/prop_engine.h" #include "theory/bv/theory_bv_rewriter.h" @@ -32,19 +33,142 @@ namespace quantifiers { CegConjecture::CegConjecture( QuantifiersEngine * qe, context::Context* c ) - : d_qe( qe ), d_curr_lit( c, 0 ) { + : d_qe( qe ) { d_refine_count = 0; d_ceg_si = new CegConjectureSingleInv( qe, this ); + d_ceg_pbe = new CegConjecturePbe( qe, this ); } CegConjecture::~CegConjecture() { delete d_ceg_si; + delete d_ceg_pbe; +} + +Node CegConjecture::convertToEmbedding( Node n, std::map< Node, Node >& synth_fun_vars, std::map< Node, Node >& visited ){ + std::map< Node, Node >::iterator it = visited.find( n ); + if( it==visited.end() ){ + Node ret = n; + + std::vector< Node > children; + bool childChanged = false; + bool madeOp = false; + Kind ret_k = n.getKind(); + Node op; + if( n.getNumChildren()>0 ){ + if( n.getKind()==kind::APPLY_UF ){ + op = n.getOperator(); + } + }else{ + op = n; + } + // is it a synth function? + std::map< Node, Node >::iterator its = synth_fun_vars.find( op ); + if( its!=synth_fun_vars.end() ){ + Assert( its->second.getType().isDatatype() ); + // make into evaluation function + const Datatype& dt = ((DatatypeType)its->second.getType().toType()).getDatatype(); + Assert( dt.isSygus() ); + children.push_back( Node::fromExpr( dt.getSygusEvaluationFunc() ) ); + children.push_back( its->second ); + madeOp = true; + childChanged = true; + ret_k = kind::APPLY_UF; + } + if( n.getNumChildren()>0 || childChanged ){ + if( !madeOp ){ + if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){ + children.push_back( n.getOperator() ); + } + } + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + Node nc = convertToEmbedding( n[i], synth_fun_vars, visited ); + childChanged = childChanged || nc!=n[i]; + children.push_back( nc ); + } + if( childChanged ){ + ret = NodeManager::currentNM()->mkNode( ret_k, children ); + } + } + visited[n] = ret; + return ret; + }else{ + return it->second; + } +} + +void CegConjecture::collectConstants( Node n, std::map< TypeNode, std::vector< Node > >& consts, std::map< Node, bool >& visited ) { + if( visited.find( n )==visited.end() ){ + visited[n] = true; + if( n.isConst() ){ + TypeNode tn = n.getType(); + Node nc = n; + if( tn.isReal() ){ + nc = NodeManager::currentNM()->mkConst( n.getConst<Rational>().abs() ); + } + if( std::find( consts[tn].begin(), consts[tn].end(), nc )==consts[tn].end() ){ + Trace("cegqi-debug") << "...consider const : " << nc << std::endl; + consts[tn].push_back( nc ); + } + } + + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + collectConstants( n[i], consts, visited ); + } + } } void CegConjecture::assign( Node q ) { Assert( d_quant.isNull() ); Assert( q.getKind()==FORALL ); + Trace("cegqi") << "CegConjecture : assign : " << q << std::endl; d_assert_quant = q; + std::map< TypeNode, std::vector< Node > > extra_cons; + + Trace("cegqi") << "CegConjecture : collect constants..." << std::endl; + if( options::sygusAddConstGrammar() ){ + std::map< Node, bool > cvisited; + collectConstants( q[1], extra_cons, cvisited ); + } + + Trace("cegqi") << "CegConjecture : convert to deep embedding..." << std::endl; + //convert to deep embedding + std::vector< Node > qchildren; + std::map< Node, Node > visited; + std::map< Node, Node > synth_fun_vars; + std::vector< Node > ebvl; + for( unsigned i=0; i<q[0].getNumChildren(); i++ ){ + Node v = q[0][i]; + Node sf = v.getAttribute(SygusSynthFunAttribute()); + Assert( !sf.isNull() ); + Node sfvl = sf.getAttribute(SygusSynthFunVarListAttribute()); + // sfvl may be null for constant synthesis functions + Trace("cegqi-debug") << "...sygus var list associated with " << sf << " is " << sfvl << std::endl; + TypeNode tn; + if( v.getType().isDatatype() && ((DatatypeType)v.getType().toType()).getDatatype().isSygus() ){ + tn = v.getType(); + }else{ + // make the default grammar + std::stringstream ss; + ss << sf; + tn = d_qe->getTermDatabaseSygus()->mkSygusDefaultType( v.getType(), sfvl, ss.str(), extra_cons ); + } + d_qe->getTermDatabaseSygus()->registerSygusType( tn ); + // ev is the first-order variable corresponding to this synth fun + std::stringstream ss; + ss << "f" << sf; + Node ev = NodeManager::currentNM()->mkBoundVar( ss.str(), tn ); + ebvl.push_back( ev ); + synth_fun_vars[sf] = ev; + Trace("cegqi") << "...embedding synth fun : " << sf << " -> " << ev << std::endl; + } + qchildren.push_back( NodeManager::currentNM()->mkNode( kind::BOUND_VAR_LIST, ebvl ) ); + qchildren.push_back( convertToEmbedding( q[1], synth_fun_vars, visited ) ); + if( q.getNumChildren()==3 ){ + qchildren.push_back( q[2] ); + } + q = NodeManager::currentNM()->mkNode( kind::FORALL, qchildren ); + Trace("cegqi") << "CegConjecture : converted to embedding : " << q << std::endl; + //register with single invocation if applicable if( d_qe->getTermDatabase()->isQAttrSygus( d_assert_quant ) && options::cegqiSingleInvMode()!=CEGQI_SI_MODE_NONE ){ d_ceg_si->initialize( q ); @@ -52,18 +176,44 @@ void CegConjecture::assign( Node q ) { //Node red_lem = NodeManager::currentNM()->mkNode( OR, q.negate(), d_cegqi_si->d_quant ); //may have rewritten quantified formula (for invariant synthesis) q = d_ceg_si->d_quant; + Assert( q.getKind()==kind::FORALL ); } } + d_quant = q; Assert( d_candidates.empty() ); std::vector< Node > vars; for( unsigned i=0; i<q[0].getNumChildren(); i++ ){ vars.push_back( q[0][i] ); - d_candidates.push_back( NodeManager::currentNM()->mkSkolem( "e", q[0][i].getType() ) ); + Node e = NodeManager::currentNM()->mkSkolem( "e", q[0][i].getType() ); + d_candidates.push_back( e ); } Trace("cegqi") << "Base quantified formula is : " << q << std::endl; //construct base instantiation d_base_inst = Rewriter::rewrite( d_qe->getInstantiation( q, vars, d_candidates ) ); + + // register this term with sygus database + std::vector< Node > guarded_lemmas; + if( !isSingleInvocation() ){ + if( options::sygusPbe() ){ + d_ceg_pbe->initialize( d_base_inst, d_candidates, guarded_lemmas ); + } + for( unsigned i=0; i<d_candidates.size(); i++ ){ + Node e = d_candidates[i]; + if( options::sygusPbe() ){ + std::vector< std::vector< Node > > exs; + std::vector< Node > exos; + std::vector< Node > exts; + // use the PBE examples, regardless of the search algorith, since these help search space pruning + if( d_ceg_pbe->getPbeExamples( e, exs, exos, exts ) ){ + d_qe->getTermDatabaseSygus()->registerPbeExamples( e, exs, exos, exts ); + } + }else{ + d_qe->getTermDatabaseSygus()->registerMeasuredTerm( e, e ); + } + } + } + Trace("cegqi") << "Base instantiation is : " << d_base_inst << std::endl; if( d_qe->getTermDatabase()->isQAttrSygus( d_assert_quant ) ){ CegInstantiation::collectDisjuncts( d_base_inst, d_base_disj ); @@ -80,269 +230,50 @@ void CegConjecture::assign( Node q ) { } } } - if( options::sygusUnifCondSol() ){ - // for each variable, determine whether we can do conditional counterexamples - for( unsigned i=0; i<d_candidates.size(); i++ ){ - registerCandidateConditional( d_candidates[i] ); - } - } d_syntax_guided = true; }else if( d_qe->getTermDatabase()->isQAttrSynthesis( d_assert_quant ) ){ d_syntax_guided = false; }else{ Assert( false ); } -} - -void CegConjecture::registerCandidateConditional( Node v ) { - TypeNode tn = v.getType(); - bool type_valid = false; - bool success = false; - std::vector< TypeNode > unif_types; - if( tn.isDatatype() ){ - const Datatype& dt = ((DatatypeType)tn.toType()).getDatatype(); - if( dt.isSygus() ){ - type_valid = true; - if( d_candidates.size()==1 ){ // conditional solutions for multiple function conjectures TODO? - for( unsigned r=0; r<2; r++ ){ - for( unsigned j=0; j<dt.getNumConstructors(); j++ ){ - Node op = Node::fromExpr( dt[j].getSygusOp() ); - if( r==0 ){ - if( op.getKind() == kind::BUILTIN ){ - Kind sk = NodeManager::operatorToKind( op ); - if( sk==kind::ITE ){ - // we can do unification - success = true; - d_cinfo[v].d_csol_op = Node::fromExpr( dt[j].getConstructor() ); - Assert( dt[j].getNumArgs()==3 ); - for( unsigned k=0; k<3; k++ ){ - unif_types.push_back( TypeNode::fromType( dt[j][k].getRangeType() ) ); - } - break; - } - } - }else{ - if( dt[j].getNumArgs()>=3 ){ - // could be a defined ITE (this is a hack for ICFP benchmarks) - std::vector< Node > utchildren; - utchildren.push_back( Node::fromExpr( dt[j].getConstructor() ) ); - std::vector< Node > sks; - for( unsigned k=0; k<dt[j].getNumArgs(); k++ ){ - Type t = dt[j][k].getRangeType(); - Node kv = NodeManager::currentNM()->mkSkolem( "ut", TypeNode::fromType( t ) ); - sks.push_back( kv ); - utchildren.push_back( kv ); - } - Node ut = NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, utchildren ); - std::vector< Node > echildren; - echildren.push_back( Node::fromExpr( dt.getSygusEvaluationFunc() ) ); - echildren.push_back( ut ); - Node sbvl = Node::fromExpr( dt.getSygusVarList() ); - for( unsigned k=0; k<sbvl.getNumChildren(); k++ ){ - echildren.push_back( sbvl[k] ); - } - Node eut = NodeManager::currentNM()->mkNode( kind::APPLY_UF, echildren ); - Trace("sygus-unif-debug") << "Test evaluation of " << eut << "..." << std::endl; - eut = d_qe->getTermDatabaseSygus()->unfold( eut ); - Trace("sygus-unif-debug") << "...got " << eut << std::endl; - if( eut.getKind()==kind::ITE ){ - success = true; - std::vector< Node > vs; - std::vector< Node > ss; - std::map< Node, unsigned > templ_var_index; - for( unsigned k=0; k<sks.size(); k++ ){ - echildren[1] = sks[k]; - Node esk = NodeManager::currentNM()->mkNode( kind::APPLY_UF, echildren ); - vs.push_back( esk ); - Node tvar = NodeManager::currentNM()->mkSkolem( "templ", esk.getType() ); - templ_var_index[tvar] = k; - ss.push_back( tvar ); - } - eut = eut.substitute( vs.begin(), vs.end(), ss.begin(), ss.end() ); - Trace("sygus-unif") << "Defined constructor " << j << ", base term is " << eut << std::endl; - //success if we can find a injection from ITE args to sygus args - std::map< unsigned, unsigned > templ_injection; - for( unsigned k=0; k<3; k++ ){ - if( !inferIteTemplate( k, eut[k], templ_var_index, templ_injection ) ){ - Trace("sygus-unif") << "...failed to find injection (range)." << std::endl; - success = false; - break; - } - if( templ_injection.find( k )==templ_injection.end() ){ - Trace("sygus-unif") << "...failed to find injection (domain)." << std::endl; - success = false; - break; - } - } - if( success ){ - d_cinfo[v].d_csol_op = Node::fromExpr( dt[j].getConstructor() ); - for( unsigned k=0; k<3; k++ ){ - Assert( templ_injection.find( k )!=templ_injection.end() ); - unsigned sk_index = templ_injection[k]; - unif_types.push_back( sks[sk_index].getType() ); - //also store the template information, if necessary - Node teut = eut[k]; - if( !teut.isVar() ){ - d_cinfo[v].d_template[k] = teut; - d_cinfo[v].d_template_arg[k] = ss[sk_index]; - Trace("sygus-unif") << " Arg " << k << " : template : " << teut << ", arg " << ss[sk_index] << std::endl; - }else{ - Assert( teut==ss[sk_index] ); - } - } - } - } - } - } - } - if( success ){ - break; - } - } - } - } - } - //mark active - if( !success ){ - d_cinfo[v].d_csol_status = -1; - }else{ - //make progress guard - Node pg = Rewriter::rewrite( NodeManager::currentNM()->mkSkolem( "P", NodeManager::currentNM()->booleanType(), "Progress guard for conditional solution." ) ); - Node pglem = NodeManager::currentNM()->mkNode( kind::OR, pg.negate(), pg ); - Trace("cegqi-lemma") << "Cegqi::Lemma : progress split : " << pglem << std::endl; - d_qe->getOutputChannel().lemma( pglem ); - d_qe->getOutputChannel().requirePhase( pg, true ); - - Assert( unif_types.size()==3 ); - d_cinfo[v].d_csol_cond = NodeManager::currentNM()->mkSkolem( "c", unif_types[0] ); - for( unsigned k=0; k<2; k++ ){ - d_cinfo[v].d_csol_var[k] = NodeManager::currentNM()->mkSkolem( "e", unif_types[k+1] ); - // optimization : need not be an ITE if types are equivalent TODO - } - d_cinfo[v].d_csol_progress_guard = pg; - Trace("sygus-unif") << "Can do synthesis unification for variable " << v << ", based on operator " << d_cinfo[v].d_csol_op << std::endl; - } - if( !type_valid ){ - Assert( false ); - } -} - -bool CegConjecture::inferIteTemplate( unsigned k, Node n, std::map< Node, unsigned >& templ_var_index, std::map< unsigned, unsigned >& templ_injection ){ - if( n.getNumChildren()==0 ){ - std::map< Node, unsigned >::iterator itt = templ_var_index.find( n ); - if( itt!=templ_var_index.end() ){ - unsigned kk = itt->second; - std::map< unsigned, unsigned >::iterator itti = templ_injection.find( k ); - if( itti==templ_injection.end() ){ - templ_injection[k] = kk; - }else if( itti->second!=kk ){ - return false; - } - } - return true; - }else{ - for( unsigned i=0; i<n.getNumChildren(); i++ ){ - if( !inferIteTemplate( k, n[i], templ_var_index, templ_injection ) ){ - return false; - } - } - } - return true; -} - -void CegConjecture::initializeGuard(){ - if( isAssigned() ){ - if( !d_syntax_guided ){ - if( d_nsg_guard.isNull() ){ - d_nsg_guard = Rewriter::rewrite( NodeManager::currentNM()->mkSkolem( "G", NodeManager::currentNM()->booleanType() ) ); - d_nsg_guard = d_qe->getValuation().ensureLiteral( d_nsg_guard ); - AlwaysAssert( !d_nsg_guard.isNull() ); - d_qe->getOutputChannel().requirePhase( d_nsg_guard, true ); - //add immediate lemma - Node lem = NodeManager::currentNM()->mkNode( OR, d_nsg_guard.negate(), d_base_inst.negate() ); - Trace("cegqi-lemma") << "Cegqi::Lemma : non-syntax-guided : " << lem << std::endl; - d_qe->getOutputChannel().lemma( lem ); - } - }else if( d_ceg_si->d_si_guard.isNull() ){ - std::vector< Node > lems; - d_ceg_si->getInitialSingleInvLemma( lems ); - for( unsigned i=0; i<lems.size(); i++ ){ - Trace("cegqi-lemma") << "Cegqi::Lemma : single invocation " << i << " : " << lems[i] << std::endl; - d_qe->getOutputChannel().lemma( lems[i] ); - if( Trace.isOn("cegqi-debug") ){ - Node rlem = Rewriter::rewrite( lems[i] ); - Trace("cegqi-debug") << "...rewritten : " << rlem << std::endl; - } + + // initialize the guard + if( !d_syntax_guided ){ + if( d_nsg_guard.isNull() ){ + d_nsg_guard = Rewriter::rewrite( NodeManager::currentNM()->mkSkolem( "G", NodeManager::currentNM()->booleanType() ) ); + d_nsg_guard = d_qe->getValuation().ensureLiteral( d_nsg_guard ); + AlwaysAssert( !d_nsg_guard.isNull() ); + d_qe->getOutputChannel().requirePhase( d_nsg_guard, true ); + // negated base as a guarded lemma + guarded_lemmas.push_back( d_base_inst.negate() ); + } + }else if( d_ceg_si->d_si_guard.isNull() ){ + std::vector< Node > lems; + d_ceg_si->getInitialSingleInvLemma( lems ); + for( unsigned i=0; i<lems.size(); i++ ){ + Trace("cegqi-lemma") << "Cegqi::Lemma : single invocation " << i << " : " << lems[i] << std::endl; + d_qe->getOutputChannel().lemma( lems[i] ); + if( Trace.isOn("cegqi-debug") ){ + Node rlem = Rewriter::rewrite( lems[i] ); + Trace("cegqi-debug") << "...rewritten : " << rlem << std::endl; } } - Assert( !getGuard().isNull() ); } -} - -void CegConjecture::setMeasureTerm( Node mt ){ - d_measure_term = mt; - d_active_measure_term = mt; -} - -Node CegConjecture::getMeasureTermFactor( Node v ) { - Node ret; - if( getCegqiFairMode()==CEGQI_FAIR_DT_SIZE ){ - if( v.getType().isDatatype() ){ - ret = NodeManager::currentNM()->mkNode( DT_SIZE, v ); - } + Assert( !getGuard().isNull() ); + Node gneg = getGuard().negate(); + for( unsigned i=0; i<guarded_lemmas.size(); i++ ){ + Node lem = NodeManager::currentNM()->mkNode( OR, gneg, guarded_lemmas[i] ); + Trace("cegqi-lemma") << "Cegqi::Lemma : initial (guarded) lemma : " << lem << std::endl; + d_qe->getOutputChannel().lemma( lem ); } - //TODO - Assert( ret.isNull() || ret.getType().isInteger() ); - return ret; -} - -Node CegConjecture::getFairnessLiteral( int i ) { - if( d_measure_term.isNull() ){ - return Node::null(); - }else{ - std::map< int, Node >::iterator it = d_lits.find( i ); - if( it==d_lits.end() ){ - Trace("cegqi-engine") << "******* CEGQI : allocate size literal " << i << std::endl; - Node c = NodeManager::currentNM()->mkConst( Rational( i ) ); - Node lit = NodeManager::currentNM()->mkNode( LEQ, d_measure_term, c ); - lit = Rewriter::rewrite( lit ); - d_lits[i] = lit; - - Node lem = NodeManager::currentNM()->mkNode( kind::OR, lit, lit.negate() ); - Trace("cegqi-lemma") << "Cegqi::Lemma : Fairness split : " << lem << std::endl; - d_qe->getOutputChannel().lemma( lem ); - d_qe->getOutputChannel().requirePhase( lit, true ); - - if( getCegqiFairMode()==CEGQI_FAIR_DT_HEIGHT_PRED || getCegqiFairMode()==CEGQI_FAIR_DT_SIZE_PRED ){ - //implies height bounds on each candidate variable - std::vector< Node > lem_c; - for( unsigned j=0; j<d_candidates.size(); j++ ){ - if( getCegqiFairMode()==CEGQI_FAIR_DT_HEIGHT_PRED ){ - lem_c.push_back( NodeManager::currentNM()->mkNode( DT_HEIGHT_BOUND, d_candidates[j], c ) ); - }else{ - //lem_c.push_back( NodeManager::currentNM()->mkNode( DT_SIZE_BOUND, d_candidates[j], c ) ); - } - } - Node hlem = NodeManager::currentNM()->mkNode( OR, lit.negate(), lem_c.size()==1 ? lem_c[0] : NodeManager::currentNM()->mkNode( AND, lem_c ) ); - Trace("cegqi-lemma") << "Cegqi::Lemma : Fairness expansion (pred) : " << hlem << std::endl; - d_qe->getOutputChannel().lemma( hlem ); - } - return lit; - }else{ - return it->second; - } - } + Trace("cegqi") << "...finished, single invocation = " << isSingleInvocation() << std::endl; } Node CegConjecture::getGuard() { return !d_syntax_guided ? d_nsg_guard : d_ceg_si->d_si_guard; } -CegqiFairMode CegConjecture::getCegqiFairMode() { - return isSingleInvocation() ? CEGQI_FAIR_NONE : options::ceGuidedInstFair(); -} - bool CegConjecture::isSingleInvocation() const { return d_ceg_si->isSingleInvocation(); } @@ -410,99 +341,21 @@ bool CegConjecture::needsRefinement() { return !d_ce_sk.empty(); } -void CegConjecture::getConditionalCandidateList( std::vector< Node >& clist, Node curr, bool reqAdd ){ - Assert( options::sygusUnifCondSol() ); - std::map< Node, CandidateInfo >::iterator it = d_cinfo.find( curr ); - if( it!=d_cinfo.end() ){ - if( !it->second.d_csol_cond.isNull() ){ - if( it->second.d_csol_status!=-1 ){ - int pstatus = getProgressStatus( curr ); - if( pstatus!=-1 ){ - Assert( it->second.d_csol_status==0 || it->second.d_csol_status==1 ); - //interested in model value for condition and branched variables - clist.push_back( it->second.d_csol_cond ); - //assume_flat_ITEs - clist.push_back( it->second.d_csol_var[it->second.d_csol_status] ); - //conditionally get the other branch - getConditionalCandidateList( clist, it->second.d_csol_var[1-it->second.d_csol_status], false ); - return; - }else{ - // it is progress-inactive, will not be included - } - } - //otherwise, yet to expand branch - if( !reqAdd ){ - // if we are not top-level, we can ignore this (it won't be part of solution) - return; - } - }else{ - // a standard variable not handlable by unification - } - clist.push_back( curr ); - } -} - void CegConjecture::getCandidateList( std::vector< Node >& clist, bool forceOrig ) { - if( options::sygusUnifCondSol() && !forceOrig ){ - for( unsigned i=0; i<d_candidates.size(); i++ ){ - getConditionalCandidateList( clist, d_candidates[i], true ); - } + if( d_ceg_pbe->isPbe() && !forceOrig ){ + //Assert( isGround() ); + d_ceg_pbe->getCandidateList( d_candidates, clist ); }else{ clist.insert( clist.end(), d_candidates.begin(), d_candidates.end() ); } } -Node CegConjecture::constructConditionalCandidate( std::map< Node, Node >& cmv, Node curr ) { - Assert( options::sygusUnifCondSol() ); - std::map< Node, Node >::iterator itc = cmv.find( curr ); - if( itc!=cmv.end() ){ - return itc->second; - }else{ - std::map< Node, CandidateInfo >::iterator it = d_cinfo.find( curr ); - if( it!=d_cinfo.end() ){ - if( !it->second.d_csol_cond.isNull() ){ - if( it->second.d_csol_status!=-1 ){ - int pstatus = getProgressStatus( curr ); - if( pstatus!=-1 ){ - Assert( it->second.d_csol_status==0 || it->second.d_csol_status==1 ); - Node v_curr = constructConditionalCandidate( cmv, it->second.d_csol_var[it->second.d_csol_status] ); - Node v_next = constructConditionalCandidate( cmv, it->second.d_csol_var[1-it->second.d_csol_status] ); - if( v_next.isNull() ){ - // try taking current branch as a leaf - return v_curr; - }else{ - Node v_cond = constructConditionalCandidate( cmv, it->second.d_csol_cond ); - std::vector< Node > args; - args.push_back( it->second.d_csol_op ); - args.push_back( v_cond ); - args.push_back( it->second.d_csol_status==0 ? v_curr : v_next ); - args.push_back( it->second.d_csol_status==0 ? v_next : v_curr ); - return NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, args ); - } - } - } - } - } - } - return Node::null(); -} - -bool CegConjecture::constructCandidates( std::vector< Node >& clist, std::vector< Node >& model_values, std::vector< Node >& candidate_values ) { +bool CegConjecture::constructCandidates( std::vector< Node >& clist, std::vector< Node >& model_values, std::vector< Node >& candidate_values, + std::vector< Node >& lems ) { Assert( clist.size()==model_values.size() ); - if( options::sygusUnifCondSol() ){ - std::map< Node, Node > cmv; - for( unsigned i=0; i<clist.size(); i++ ){ - cmv[ clist[i] ] = model_values[i]; - } - for( unsigned i=0; i<d_candidates.size(); i++ ){ - Node n = constructConditionalCandidate( cmv, d_candidates[i] ); - Trace("cegqi-candidate") << "...constructed conditional candidate " << n << " for " << d_candidates[i] << std::endl; - candidate_values.push_back( n ); - if( n.isNull() ){ - Assert( false ); //currently should never happen - return false; - } - } + if( d_ceg_pbe->isPbe() ){ + //Assert( isGround() ); + return d_ceg_pbe->constructCandidates( clist, model_values, d_candidates, candidate_values, lems ); }else{ Assert( model_values.size()==d_candidates.size() ); candidate_values.insert( candidate_values.end(), model_values.begin(), model_values.end() ); @@ -515,175 +368,73 @@ void CegConjecture::doCegConjectureCheck(std::vector< Node >& lems, std::vector< getCandidateList( clist ); std::vector< Node > c_model_values; Trace("cegqi-check") << "CegConjuncture : check, build candidates..." << std::endl; - if( constructCandidates( clist, model_values, c_model_values ) ){ - Assert( c_model_values.size()==d_candidates.size() ); + bool constructed_cand = constructCandidates( clist, model_values, c_model_values, lems ); + + //must get a counterexample to the value of the current candidate + Node inst; + if( constructed_cand ){ if( Trace.isOn("cegqi-check") ){ Trace("cegqi-check") << "CegConjuncture : check candidate : " << std::endl; for( unsigned i=0; i<c_model_values.size(); i++ ){ Trace("cegqi-check") << " " << i << " : " << d_candidates[i] << " -> " << c_model_values[i] << std::endl; } } - //must get a counterexample to the value of the current candidate - Node inst = d_base_inst.substitute( d_candidates.begin(), d_candidates.end(), c_model_values.begin(), c_model_values.end() ); - bool hasActiveConditionalNode = false; - if( options::sygusUnifCondSol() ){ - //TODO - hasActiveConditionalNode = true; - } - //check whether we will run CEGIS on inner skolem variables - bool sk_refine = ( !isGround() || d_refine_count==0 || hasActiveConditionalNode ); - if( sk_refine ){ - Assert( d_ce_sk.empty() ); - d_ce_sk.push_back( std::vector< Node >() ); + Assert( c_model_values.size()==d_candidates.size() ); + inst = d_base_inst.substitute( d_candidates.begin(), d_candidates.end(), c_model_values.begin(), c_model_values.end() ); + }else{ + inst = d_base_inst; + } + + //check whether we will run CEGIS on inner skolem variables + bool sk_refine = ( !isGround() || d_refine_count==0 ) && ( !d_ceg_pbe->isPbe() || constructed_cand ); + if( sk_refine ){ + Assert( d_ce_sk.empty() ); + d_ce_sk.push_back( std::vector< Node >() ); + }else{ + if( !constructed_cand ){ + return; } - std::vector< Node > ic; - ic.push_back( d_assert_quant.negate() ); - std::vector< Node > d; - CegInstantiation::collectDisjuncts( inst, d ); - Assert( d.size()==d_base_disj.size() ); - //immediately skolemize inner existentials - for( unsigned i=0; i<d.size(); i++ ){ - Node dr = Rewriter::rewrite( d[i] ); - if( dr.getKind()==NOT && dr[0].getKind()==FORALL ){ + } + + std::vector< Node > ic; + ic.push_back( d_assert_quant.negate() ); + std::vector< Node > d; + CegInstantiation::collectDisjuncts( inst, d ); + Assert( d.size()==d_base_disj.size() ); + //immediately skolemize inner existentials + for( unsigned i=0; i<d.size(); i++ ){ + Node dr = Rewriter::rewrite( d[i] ); + if( dr.getKind()==NOT && dr[0].getKind()==FORALL ){ + if( constructed_cand ){ ic.push_back( d_qe->getTermDatabase()->getSkolemizedBody( dr[0] ).negate() ); - if( sk_refine ){ - d_ce_sk.back().push_back( dr[0] ); - } - }else{ + } + if( sk_refine ){ + Assert( !isGround() ); + d_ce_sk.back().push_back( dr[0] ); + } + }else{ + if( constructed_cand ){ ic.push_back( dr ); - if( sk_refine ){ - d_ce_sk.back().push_back( Node::null() ); - } if( !d_inner_vars_disj[i].empty() ){ Trace("cegqi-debug") << "*** quantified disjunct : " << d[i] << " simplifies to " << dr << std::endl; } } + if( sk_refine ){ + d_ce_sk.back().push_back( Node::null() ); + } } + } + if( constructed_cand ){ Node lem = NodeManager::currentNM()->mkNode( OR, ic ); lem = Rewriter::rewrite( lem ); + //eagerly unfold applications of evaluation function + if( options::sygusDirectEval() ){ + Trace("cegqi-debug") << "pre-unfold counterexample : " << lem << std::endl; + std::map< Node, Node > visited_n; + lem = d_qe->getTermDatabaseSygus()->getEagerUnfold( lem, visited_n ); + } lems.push_back( lem ); recordInstantiation( c_model_values ); - }else{ - Assert( false ); - } -} - -Node CegConjecture::getActiveConditional( Node curr ) { - Assert( options::sygusUnifCondSol() ); - std::map< Node, CandidateInfo >::iterator it = d_cinfo.find( curr ); - Assert( it!=d_cinfo.end() ); - if( !it->second.d_csol_cond.isNull() ){ - if( it->second.d_csol_status==-1 ){ - //yet to branch, this is the one - return curr; - }else{ - int pstatus = getProgressStatus( curr ); - if( pstatus==-1 ){ - // it is progress-inactive - return curr; - }else{ - Assert( it->second.d_csol_status==0 || it->second.d_csol_status==1 ); - return getActiveConditional( it->second.d_csol_var[1-it->second.d_csol_status] ); - } - } - }else{ - //not a conditional - return curr; - } -} - -void CegConjecture::getContextConditionalNodes( Node curr, Node x, std::vector< Node >& nodes ) { - if( curr!=x ){ - std::map< Node, CandidateInfo >::iterator it = d_cinfo.find( curr ); - if( !it->second.d_csol_cond.isNull() ){ - if( it->second.d_csol_status!=-1 ){ - nodes.push_back( curr ); - getContextConditionalNodes( it->second.d_csol_var[1-it->second.d_csol_status], x, nodes ); - } - } - } -} - -Node CegConjecture::mkConditionalEvalNode( Node c, std::vector< Node >& args ) { - Assert( !c.isNull() ); - std::vector< Node > condc; - //get evaluator - Assert( c.getType().isDatatype() ); - const Datatype& cd = ((DatatypeType)c.getType().toType()).getDatatype(); - Assert( cd.isSygus() ); - condc.push_back( Node::fromExpr( cd.getSygusEvaluationFunc() ) ); - condc.push_back( c ); - for( unsigned a=0; a<args.size(); a++ ){ - condc.push_back( args[a] ); - } - return NodeManager::currentNM()->mkNode( kind::APPLY_UF, condc ); -} - -Node CegConjecture::mkConditionalNode( Node v, std::vector< Node >& args, unsigned eindex ) { - std::map< Node, CandidateInfo >::iterator it = d_cinfo.find( v ); - if( it!=d_cinfo.end() ){ - Assert( eindex<=2 ); - Node en = eindex==0 ? it->second.d_csol_cond : it->second.d_csol_var[eindex-1]; - if( !en.isNull() ){ - Node ret = mkConditionalEvalNode( en, args ); - //consider template - std::map< unsigned, Node >::iterator itt = it->second.d_template.find( eindex ); - if( itt!=it->second.d_template.end() ){ - Assert( it->second.d_template_arg.find( eindex )!=it->second.d_template_arg.end() ); - TNode var = it->second.d_template_arg[eindex]; - TNode subs = ret; - Node rret = itt->second.substitute( var, subs ); - ret = rret; - } - return ret; - } - } - Assert( false ); - return Node::null(); -} - -Node CegConjecture::mkConditional( Node v, std::vector< Node >& args, bool pol ) { - Node ret = mkConditionalNode( v, args, 0 ); - if( !pol ){ - ret = ret.negate(); - } - return ret; -} - -Node CegConjecture::purifyConditionalEvaluations( Node n, std::map< Node, Node >& csol_active, std::map< Node, Node >& psubs, std::map< Node, Node >& visited ){ - std::map< Node, Node >::iterator itv = visited.find( n ); - if( itv!=visited.end() ){ - return itv->second; - }else{ - Node ret; - if( n.getKind()==APPLY_UF ){ - std::map< Node, Node >::iterator itc = csol_active.find( n[0] ); - if( itc!=csol_active.end() ){ - //purify it with a variable - ret = NodeManager::currentNM()->mkSkolem( "y", n.getType(), "purification variable for sygus conditional solution" ); - psubs[n] = ret; - } - } - if( ret.isNull() ){ - ret = n; - if( n.getNumChildren()>0 ){ - std::vector< Node > children; - if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){ - children.push_back( n.getOperator() ); - } - bool childChanged = false; - for( unsigned i=0; i<n.getNumChildren(); i++ ){ - Node nc = purifyConditionalEvaluations( n[i], csol_active, psubs, visited ); - childChanged = childChanged || nc!=n[i]; - children.push_back( nc ); - } - if( childChanged ){ - ret = NodeManager::currentNM()->mkNode( n.getKind(), children ); - } - } - } - visited[n] = ret; - return ret; } } @@ -717,119 +468,9 @@ void CegConjecture::doCegConjectureRefine( std::vector< Node >& lems ){ } } - std::map< Node, Node > csol_active; std::map< Node, std::vector< Node > > csol_ccond_nodes; std::map< Node, std::map< Node, bool > > csol_cpol; - if( options::sygusUnifCondSol() ){ - //previous non-ground conditional refinement lemmas must satisfy the current point - if( !isGround() ){ - Trace("cegqi-refine") << "doCegConjectureRefine : check for new refinements of previous lemmas..." << std::endl; - for( unsigned i=0; i<d_refinement_lemmas_ngr.size(); i++ ){ - Node prev_lem = d_refinement_lemmas_ngr[i]; - prev_lem = prev_lem.substitute( sk_vars.begin(), sk_vars.end(), sk_subs.begin(), sk_subs.end() ); - if( d_refinement_lemmas_reproc.find( prev_lem )==d_refinement_lemmas_reproc.end() ){ - d_refinement_lemmas_reproc[prev_lem] = true; - //do auxiliary variable substitution - std::vector< Node > subs; - for( unsigned ii=0; ii<d_refinement_lemmas_aux_vars[i].size(); ii++ ){ - subs.push_back( NodeManager::currentNM()->mkSkolem( "y", d_refinement_lemmas_aux_vars[i][ii].getType(), - "purification variable for non-ground sygus conditional solution" ) ); - } - prev_lem = prev_lem.substitute( d_refinement_lemmas_aux_vars[i].begin(), d_refinement_lemmas_aux_vars[i].end(), subs.begin(), subs.end() ); - prev_lem = Rewriter::rewrite( prev_lem ); - Trace("sygus-unif") << "...previous conditional refinement lemma with new counterexample : " << prev_lem << std::endl; - lems.push_back( prev_lem ); - } - } - if( !lems.empty() ){ - Trace("cegqi-refine") << "...added lemmas, abort further refinement." << std::endl; - d_ce_sk.clear(); - return; - } - } - Trace("cegqi-refine") << "doCegConjectureRefine : conditional solution refinement, expand active conditional nodes" << std::endl; - std::vector< Node > new_active_measure_sum; - for( unsigned i=0; i<d_candidates.size(); i++ ){ - Node v = d_candidates[i]; - Node ac = getActiveConditional( v ); - Assert( !ac.isNull() ); - //compute the contextual conditions - getContextConditionalNodes( v, ac, csol_ccond_nodes[v] ); - if( !csol_ccond_nodes[v].empty() ){ - //it will be conditionally evaluated, this is a placeholder - csol_active[v] = Node::null(); - } - Trace("sygus-unif") << "Active conditional for " << v << " is : " << ac << std::endl; - //if it is a conditional - bool is_active_conditional = false; - if( !d_cinfo[ac].d_csol_cond.isNull() ){ - int pstatus = getProgressStatus( ac ); - Assert( pstatus!=0 ); - if( pstatus==-1 ){ - //inject new progress point TODO? - Trace("sygus-unif") << "...progress status is " << pstatus << ", do not expand." << std::endl; - Assert( false ); - }else{ - is_active_conditional = true; - //expand this conditional - Trace("sygus-unif") << "****** For " << v << ", expanding an active conditional node : " << ac << std::endl; - d_cinfo[ac].d_csol_status = 0; //TODO: prefer some branches more than others based on the grammar? - Trace("sygus-unif") << "...expanded to " << d_cinfo[ac].d_csol_op << "( "; - Trace("sygus-unif") << d_cinfo[ac].d_csol_cond << ", " << d_cinfo[ac].d_csol_var[0] << ", "; - Trace("sygus-unif") << d_cinfo[ac].d_csol_var[1] << " )" << std::endl; - registerCandidateConditional( d_cinfo[ac].d_csol_var[1-d_cinfo[ac].d_csol_status] ); - //add to measure sum - Node acfc = getMeasureTermFactor( d_cinfo[ac].d_csol_cond ); - if( !acfc.isNull() ){ - new_active_measure_sum.push_back( acfc ); - } - Node acfv = getMeasureTermFactor( d_cinfo[ac].d_csol_var[d_cinfo[ac].d_csol_status] ); - if( !acfv.isNull() ){ - new_active_measure_sum.push_back( acfv ); - } - csol_active[v] = ac; - } - } - if( !is_active_conditional ){ - Trace("sygus-unif") << "* For " << v << ", its active node " << ac << " is not a conditional node." << std::endl; - //if we have not already included this in the measure, do so - if( d_cinfo[ac].d_csol_status==-1 ){ - Node acf = getMeasureTermFactor( ac ); - if( !acf.isNull() ){ - new_active_measure_sum.push_back( acf ); - } - d_cinfo[ac].d_csol_status = 2; - } - } - if( !csol_ccond_nodes[v].empty() ){ - Trace("sygus-unif") << "...it is nested under " << csol_ccond_nodes[v].size() << " other conditionals" << std::endl; - } - } - // must add to active measure - if( !new_active_measure_sum.empty() ){ - Node mcsum = new_active_measure_sum.size()==1 ? new_active_measure_sum[0] : NodeManager::currentNM()->mkNode( kind::PLUS, new_active_measure_sum ); - Node mclem = NodeManager::currentNM()->mkNode( kind::LEQ, mcsum, d_active_measure_term ); - Trace("cegqi-lemma") << "Cegqi::Lemma : Measure component lemma : " << mclem << std::endl; - d_qe->getOutputChannel().lemma( mclem ); - /* - for( unsigned i=0; i<new_active_measure_sum.size(); i++ ){ - Node mclem = NodeManager::currentNM()->mkNode( kind::LEQ, new_active_measure_sum[i], d_active_measure_term ); - Trace("cegqi-lemma") << "Cegqi::Lemma : Measure component lemma : " << mclem << std::endl; - d_qe->getOutputChannel().lemma( mclem ); - } - - Node new_active_measure = NodeManager::currentNM()->mkSkolem( "K", NodeManager::currentNM()->integerType() ); - new_active_measure_sum.push_back( new_active_measure ); - Node namlem = NodeManager::currentNM()->mkNode( kind::GEQ, new_active_measure, NodeManager::currentNM()->mkConst(Rational(0))); - Node ramlem = d_active_measure_term.eqNode( NodeManager::currentNM()->mkNode( kind::PLUS, new_active_measure_sum ) ); - namlem = NodeManager::currentNM()->mkNode( kind::AND, ramlem, namlem ); - Trace("cegqi-lemma") << "Cegqi::Lemma : Measure expansion : " << namlem << std::endl; - d_qe->getOutputChannel().lemma( namlem ); - d_active_measure_term = new_active_measure; - */ - } - } //for conditional evaluation std::map< Node, Node > psubs_visited; @@ -855,14 +496,7 @@ void CegConjecture::doCegConjectureRefine( std::vector< Node >& lems ){ } if( !c_disj.isNull() ){ //compute the body, inst_cond - if( options::sygusUnifCondSol() ){ - Trace("sygus-unif") << "Process " << c_disj << std::endl; - c_disj = purifyConditionalEvaluations( c_disj, csol_active, psubs, psubs_visited ); - Trace("sygus-unif") << "Purified to : " << c_disj << std::endl; - Trace("sygus-unif") << "...now with " << psubs.size() << " definitions." << std::endl; - }else{ - //standard CEGIS refinement : plug in values, assert that d_candidates must satisfy entire specification - } + //standard CEGIS refinement : plug in values, assert that d_candidates must satisfy entire specification lem_c.push_back( c_disj ); } } @@ -872,118 +506,10 @@ void CegConjecture::doCegConjectureRefine( std::vector< Node >& lems ){ std::vector< Node > psubs_cond_conc; std::map< Node, std::vector< Node > > psubs_apply; std::vector< Node > paux_vars; - if( options::sygusUnifCondSol() ){ - Trace("cegqi-refine") << "doCegConjectureRefine : add conditional assumptions for " << psubs.size() << " evaluations..." << std::endl; - for( std::map< Node, Node >::iterator itp = psubs.begin(); itp != psubs.end(); ++itp ){ - Assert( csol_active.find( itp->first[0] )!=csol_active.end() ); - paux_vars.push_back( itp->second ); - std::vector< Node > args; - for( unsigned a=1; a<itp->first.getNumChildren(); a++ ){ - args.push_back( itp->first[a] ); - } - Node ac = csol_active[itp->first[0]]; - Assert( d_cinfo.find( ac )!=d_cinfo.end() ); - Node c = d_cinfo[ac].d_csol_cond; - psubs_apply[ c ].push_back( itp->first ); - Trace("sygus-unif") << " process assumption " << itp->first << " == " << itp->second << ", with current condition " << c; - Trace("sygus-unif") << ", and " << csol_ccond_nodes[itp->first[0]].size() << " context conditionals." << std::endl; - std::vector< Node> assm; - if( !c.isNull() ){ - assm.push_back( mkConditional( ac, args, true ) ); - } - for( unsigned j=0; j<csol_ccond_nodes[itp->first[0]].size(); j++ ){ - Node acc = csol_ccond_nodes[itp->first[0]][j]; - bool pol = ( d_cinfo[acc].d_csol_status==1 ); - assm.push_back( mkConditional( acc, args, pol ) ); - } - Assert( !assm.empty() ); - Node c_ant = assm.size()==1 ? assm[0] : NodeManager::currentNM()->mkNode( kind::AND, assm ); - psubs_cond_ant.push_back( c_ant ); - // make the evaluation node - Node eret = mkConditionalNode( ac, args, d_cinfo[ac].d_csol_status+1 ); - Node c_conc = eret.eqNode( itp->second ); - psubs_cond_conc.push_back( c_conc ); - Trace("sygus-unif") << " ...made conditional correctness assumption : " << c_ant << " => " << c_conc << std::endl; - } - }else{ - Assert( psubs.empty() ); - } + Assert( psubs.empty() ); Node base_lem = lem_c.size()==1 ? lem_c[0] : NodeManager::currentNM()->mkNode( AND, lem_c ); - if( options::sygusUnifCondSol() ){ - Trace("sygus-unif-debug") << "We have base lemma : " << base_lem << std::endl; - //progress lemmas - Trace("cegqi-refine") << "doCegConjectureRefine : add progress lemmas..." << std::endl; - std::map< Node, bool > cprocessed; - for( std::map< Node, Node >::iterator itc = csol_active.begin(); itc !=csol_active.end(); ++itc ){ - Node x = itc->first; - Node ac = itc->second; - Assert( d_cinfo.find( ac )!=d_cinfo.end() ); - Node c = d_cinfo[ac].d_csol_cond; - if( !c.isNull() ){ - Trace("sygus-unif") << " process conditional " << c << " for " << x << ", which was applied " << psubs_apply[c].size() << " times." << std::endl; - //make the progress point - Assert( x.getType().isDatatype() ); - const Datatype& dx = ((DatatypeType)x.getType().toType()).getDatatype(); - Node sbvl = Node::fromExpr( dx.getSygusVarList() ); - std::vector< Node > prgr_pt; - for( unsigned a=0; a<sbvl.getNumChildren(); a++ ){ - prgr_pt.push_back( NodeManager::currentNM()->mkSkolem( "kp", sbvl[a].getType(), "progress point for sygus conditional" ) ); - } - Node pdlem; - if( !psubs_apply[c].empty() ){ - std::vector< Node > prgr_domain_d; - for( unsigned j=0; j<psubs_apply[c].size(); j++ ){ - std::vector< Node > prgr_domain; - for( unsigned a=1; a<psubs_apply[c][j].getNumChildren(); a++ ){ - Assert( a<=prgr_pt.size() ); - prgr_domain.push_back( prgr_pt[a-1].eqNode( psubs_apply[c][j][a] ) ); - } - if( !prgr_domain.empty() ){ - //the point is in the domain of this function application - Node pdc = prgr_domain.size()==1 ? prgr_domain[0] : NodeManager::currentNM()->mkNode( AND, prgr_domain ); - prgr_domain_d.push_back( pdc ); - } - } - if( !prgr_domain_d.empty() ){ - //the progress point is in the domain of some function application - pdlem = prgr_domain_d.size()==1 ? prgr_domain_d[0] : NodeManager::currentNM()->mkNode( OR, prgr_domain_d ); - pdlem = pdlem.substitute( sk_vars.begin(), sk_vars.end(), sk_subs.begin(), sk_subs.end() ); - Trace("sygus-unif") << "Progress domain point lemma is " << pdlem << std::endl; - lems.push_back( pdlem ); - } - } - //the condition holds for the point, if this is an active condition - Node cplem = mkConditional( ac, prgr_pt ); - if( !csol_ccond_nodes[x].empty() ){ - std::vector< Node > prgr_conj; - prgr_conj.push_back( cplem ); - // ...and not for its context - for( unsigned j=0; j<csol_ccond_nodes[x].size(); j++ ){ - Node acc = csol_ccond_nodes[x][j]; - bool pol = ( d_cinfo[acc].d_csol_status==1 ); - prgr_conj.push_back( mkConditional( acc, prgr_pt, pol ) ); - } - cplem = NodeManager::currentNM()->mkNode( kind::AND, prgr_conj ); - } - Assert( !d_cinfo[x].d_csol_progress_guard.isNull() ); - cplem = NodeManager::currentNM()->mkNode( kind::OR, d_cinfo[x].d_csol_progress_guard.negate(), cplem ); - Trace("sygus-unif") << "Progress lemma is " << cplem << std::endl; - lems.push_back( cplem ); - } - } - /* - if( !prgr_conj.empty() ){ - Node prgr_lem = prgr_conj.size()==1 ? prgr_conj[0] : NodeManager::currentNM()->mkNode( kind::AND, prgr_conj ); - prgr_lem = prgr_lem.substitute( sk_vars.begin(), sk_vars.end(), sk_subs.begin(), sk_subs.end() ); - prgr_lem = NodeManager::currentNM()->mkNode( OR, getGuard().negate(), prgr_lem ); - Trace("sygus-unif") << "Progress lemma is " << prgr_lem << std::endl; - lems.push_back( prgr_lem ); - } - */ - } - Trace("cegqi-refine") << "doCegConjectureRefine : construct and finalize lemmas..." << std::endl; Node lem = base_lem; @@ -992,37 +518,8 @@ void CegConjecture::doCegConjectureRefine( std::vector< Node >& lems ){ base_lem = Rewriter::rewrite( base_lem ); d_refinement_lemmas_base.push_back( base_lem ); - if( options::sygusUnifCondSol() ){ - //add the conditional evaluation - if( !psubs_cond_ant.empty() ){ - std::vector< Node > children; - children.push_back( base_lem ); - std::vector< Node > pav; - std::vector< Node > pcv; - for( unsigned i=0; i<psubs_cond_ant.size(); i++ ){ - children.push_back( NodeManager::currentNM()->mkNode( kind::OR, psubs_cond_ant[i].negate(), psubs_cond_conc[i] ) ); - Node pa = psubs_cond_ant[i].substitute( sk_vars.begin(), sk_vars.end(), sk_subs.begin(), sk_subs.end() ); - pav.push_back( pa ); - Node pc = psubs_cond_conc[i].substitute( sk_vars.begin(), sk_vars.end(), sk_subs.begin(), sk_subs.end() ); - pcv.push_back( pc ); - } - d_refinement_lemmas_ceval_ant.push_back( pav ); - d_refinement_lemmas_ceval_conc.push_back( pcv ); - lem = NodeManager::currentNM()->mkNode( AND, children ); - } - } - lem = NodeManager::currentNM()->mkNode( OR, getGuard().negate(), lem ); - if( options::sygusUnifCondSol() ){ - if( !isGround() ){ - //store the non-ground version of the lemma - lem = Rewriter::rewrite( lem ); - d_refinement_lemmas_ngr.push_back( lem ); - d_refinement_lemmas_aux_vars.push_back( paux_vars ); - } - } - lem = lem.substitute( sk_vars.begin(), sk_vars.end(), sk_subs.begin(), sk_subs.end() ); lem = Rewriter::rewrite( lem ); d_refinement_lemmas.push_back( lem ); @@ -1071,62 +568,6 @@ void CegConjecture::debugPrint( const char * c ) { } } -int CegConjecture::getProgressStatus( Node v ) { - Assert( options::sygusUnifCondSol() ); - std::map< Node, CandidateInfo >::iterator it = d_cinfo.find( v ); - if( it!=d_cinfo.end() ){ - if( !it->second.d_csol_cond.isNull() ){ - if( it->second.d_csol_status!=-1 ){ - Node plit = it->second.d_csol_progress_guard; - Assert( !plit.isNull() ); - //check SAT value of plit - bool value; - if( d_qe->getValuation().hasSatValue( plit, value ) ) { - if( !value ){ - return -1; - }else{ - return 1; - } - }else{ - return 0; - } - } - } - } - return -2; -} - -Node CegConjecture::getNextDecisionRequestConditional( Node v, unsigned& priority ) { - Assert( options::sygusUnifCondSol() ); - int pstatus = getProgressStatus( v ); - if( pstatus>=0 ){ - std::map< Node, CandidateInfo >::iterator it = d_cinfo.find( v ); - Assert( it!=d_cinfo.end() ); - if( pstatus==1 ){ - //active, recurse - Assert( it->second.d_csol_status==0 || it->second.d_csol_status==1 ); - return getNextDecisionRequestConditional( it->second.d_csol_var[1-it->second.d_csol_status], priority ); - }else if( pstatus==0 ){ - //needs decision - priority = 1; - return it->second.d_csol_progress_guard; - } - } - return Node::null(); -} - -Node CegConjecture::getNextDecisionRequest( unsigned& priority ) { - if( options::sygusUnifCondSol() ){ - for( unsigned i=0; i<d_candidates.size(); i++ ){ - Node lit = getNextDecisionRequestConditional( d_candidates[i], priority ); - if( !lit.isNull() ){ - return lit; - } - } - } - return Node::null(); -} - CegInstantiation::CegInstantiation( QuantifiersEngine * qe, context::Context* c ) : QuantifiersModule( qe ){ d_conj = new CegConjecture( qe, qe->getSatContext() ); d_last_inst_si = false; @@ -1174,6 +615,7 @@ void CegInstantiation::check( Theory::Effort e, unsigned quant_e ) { } void CegInstantiation::preRegisterQuantifier( Node q ) { +/* if( options::sygusDirectEval() ){ if( q.getNumChildren()==3 && q[2].getKind()==INST_PATTERN_LIST && q[2][0].getKind()==INST_PATTERN ){ //check whether it is an evaluation axiom @@ -1207,46 +649,15 @@ void CegInstantiation::preRegisterQuantifier( Node q ) { } } } - } + } + */ } void CegInstantiation::registerQuantifier( Node q ) { - if( d_quantEngine->getOwner( q )==this && d_eval_axioms.find( q )==d_eval_axioms.end() ){ + if( d_quantEngine->getOwner( q )==this ){ // && d_eval_axioms.find( q )==d_eval_axioms.end() ){ if( !d_conj->isAssigned() ){ Trace("cegqi") << "Register conjecture : " << q << std::endl; d_conj->assign( q ); - - //fairness - if( d_conj->getCegqiFairMode()!=CEGQI_FAIR_NONE ){ - std::vector< Node > mc; - if( options::sygusUnifCondSol() || - d_conj->getCegqiFairMode()==CEGQI_FAIR_DT_HEIGHT_PRED || d_conj->getCegqiFairMode()==CEGQI_FAIR_DT_SIZE_PRED ){ - //measure term is a fresh constant - mc.push_back( NodeManager::currentNM()->mkSkolem( "K", NodeManager::currentNM()->integerType() ) ); - }else{ - std::vector< Node > clist; - d_conj->getCandidateList( clist, true ); - for( unsigned j=0; j<clist.size(); j++ ){ - TypeNode tn = clist[j].getType(); - if( d_conj->getCegqiFairMode()==CEGQI_FAIR_DT_SIZE ){ - if( tn.isDatatype() ){ - mc.push_back( NodeManager::currentNM()->mkNode( DT_SIZE, clist[j] ) ); - } - }else if( d_conj->getCegqiFairMode()==CEGQI_FAIR_UF_DT_SIZE ){ - registerMeasuredType( tn ); - std::map< TypeNode, Node >::iterator it = d_uf_measure.find( tn ); - if( it!=d_uf_measure.end() ){ - mc.push_back( NodeManager::currentNM()->mkNode( APPLY_UF, it->second, clist[j] ) ); - } - } - } - } - if( !mc.empty() ){ - Node mt = mc.size()==1 ? mc[0] : NodeManager::currentNM()->mkNode( PLUS, mc ); - Trace("cegqi") << "Measure term is : " << mt << std::endl; - d_conj->setMeasureTerm( mt ); - } - } }else{ Assert( d_conj->d_quant==q ); } @@ -1259,10 +670,7 @@ void CegInstantiation::assertNode( Node n ) { } Node CegInstantiation::getNextDecisionRequest( unsigned& priority ) { - //enforce fairness if( d_conj->isAssigned() ){ - d_conj->initializeGuard(); - // std::vector< Node > req_dec; const CegConjectureSingleInv* ceg_si = d_conj->getCegConjectureSingleInv(); if( ! ceg_si->d_full_guard.isNull() ){ @@ -1283,32 +691,7 @@ Node CegInstantiation::getNextDecisionRequest( unsigned& priority ) { Trace("cegqi-debug2") << "CEGQI : " << req_dec[i] << " already has value " << value << std::endl; } } - - //ask the conjecture directly - Node lit = d_conj->getNextDecisionRequest( priority ); - if( !lit.isNull() ){ - return lit; - } - - if( d_conj->getCegqiFairMode()!=CEGQI_FAIR_NONE ){ - Node lit = d_conj->getFairnessLiteral( d_conj->getCurrentTermSize() ); - bool value; - if( d_quantEngine->getValuation().hasSatValue( lit, value ) ) { - if( !value ){ - d_conj->incrementCurrentTermSize(); - lit = d_conj->getFairnessLiteral( d_conj->getCurrentTermSize() ); - Trace("cegqi-debug") << "CEGQI : Decide on next lit : " << lit << "..." << std::endl; - priority = 1; - return lit; - } - }else{ - Trace("cegqi-debug") << "CEGQI : Decide on current lit : " << lit << "..." << std::endl; - priority = 1; - return lit; - } - } } - return Node::null(); } @@ -1319,11 +702,9 @@ void CegInstantiation::checkCegConjecture( CegConjecture * conj ) { conj->debugPrint("cegqi-engine-debug"); Trace("cegqi-engine-debug") << std::endl; } - if( conj->getCegqiFairMode()!=CEGQI_FAIR_NONE ){ - Trace("cegqi-engine") << " * Current term size : " << conj->getCurrentTermSize() << std::endl; - } if( !conj->needsRefinement() ){ + Trace("cegqi-engine-debug") << "Do conjecture check..." << std::endl; if( conj->d_syntax_guided ){ std::vector< Node > clems; conj->doCegConjectureSingleInvCheck( clems ); @@ -1345,25 +726,24 @@ void CegInstantiation::checkCegConjecture( CegConjecture * conj ) { if( options::sygusDirectEval() ){ bool addedEvalLemmas = false; if( options::sygusCRefEval() ){ - Trace("cegqi-debug") << "Do cref evaluation..." << std::endl; + Trace("cegqi-engine") << " *** Do conjecture refinement evaluation..." << std::endl; // see if any refinement lemma is refuted by evaluation std::vector< Node > cre_lems; getCRefEvaluationLemmas( conj, clist, model_values, cre_lems ); if( !cre_lems.empty() ){ - Trace("cegqi-engine") << " *** Do conjecture refinement evaluation..." << std::endl; for( unsigned j=0; j<cre_lems.size(); j++ ){ Node lem = cre_lems[j]; - Trace("cegqi-lemma") << "Cegqi::Lemma : cref evaluation : " << lem << std::endl; if( d_quantEngine->addLemma( lem ) ){ + Trace("cegqi-lemma") << "Cegqi::Lemma : cref evaluation : " << lem << std::endl; addedEvalLemmas = true; } } if( addedEvalLemmas ){ - return; + //return; } } } - Trace("cegqi-debug") << "Do direct evaluation..." << std::endl; + Trace("cegqi-engine") << " *** Do direct evaluation..." << std::endl; std::vector< Node > eager_terms; std::vector< Node > eager_vals; std::vector< Node > eager_exps; @@ -1373,15 +753,14 @@ void CegInstantiation::checkCegConjecture( CegConjecture * conj ) { } Trace("cegqi-debug") << "...produced " << eager_terms.size() << " eager evaluation lemmas." << std::endl; if( !eager_terms.empty() ){ - Trace("cegqi-engine") << " *** Do direct evaluation..." << std::endl; for( unsigned j=0; j<eager_terms.size(); j++ ){ Node lem = NodeManager::currentNM()->mkNode( kind::OR, eager_exps[j].negate(), eager_terms[j].eqNode( eager_vals[j] ) ); if( d_quantEngine->getTheoryEngine()->isTheoryEnabled(THEORY_BV) ){ //FIXME: hack to incorporate hacks from BV for division by zero lem = bv::TheoryBVRewriter::eliminateBVSDiv( lem ); } - Trace("cegqi-lemma") << "Cegqi::Lemma : evaluation : " << lem << std::endl; if( d_quantEngine->addLemma( lem ) ){ + Trace("cegqi-lemma") << "Cegqi::Lemma : evaluation : " << lem << std::endl; addedEvalLemmas = true; } } @@ -1390,25 +769,6 @@ void CegInstantiation::checkCegConjecture( CegConjecture * conj ) { return; } } - //check if we must apply fairness lemmas - if( conj->getCegqiFairMode()==CEGQI_FAIR_UF_DT_SIZE ){ - Trace("cegqi-debug") << "Get measure lemmas..." << std::endl; - std::vector< Node > lems; - for( unsigned j=0; j<clist.size(); j++ ){ - Trace("cegqi-debug") << " get measure lemmas for " << clist[j] << " -> " << model_values[j] << std::endl; - getMeasureLemmas( clist[j], model_values[j], lems ); - } - Trace("cegqi-debug") << "...produced " << lems.size() << " measure lemmas." << std::endl; - if( !lems.empty() ){ - Trace("cegqi-engine") << " *** Do measure refinement..." << std::endl; - for( unsigned j=0; j<lems.size(); j++ ){ - Trace("cegqi-lemma") << "Cegqi::Lemma : measure : " << lems[j] << std::endl; - d_quantEngine->addLemma( lems[j] ); - } - Trace("cegqi-engine") << " ...refine size." << std::endl; - return; - } - } Trace("cegqi-engine") << " *** Check candidate phase..." << std::endl; std::vector< Node > cclems; @@ -1417,12 +777,6 @@ void CegInstantiation::checkCegConjecture( CegConjecture * conj ) { for( unsigned i=0; i<cclems.size(); i++ ){ Node lem = cclems[i]; d_last_inst_si = false; - //eagerly unfold applications of evaluation function - if( options::sygusDirectEval() ){ - Trace("cegqi-eager") << "pre-unfold counterexample : " << lem << std::endl; - std::map< Node, Node > visited_n; - lem = getEagerUnfold( lem, visited_n ); - } Trace("cegqi-lemma") << "Cegqi::Lemma : counterexample : " << lem << std::endl; if( d_quantEngine->addLemma( lem ) ){ ++(d_statistics.d_cegqi_lemmas_ce); @@ -1482,308 +836,68 @@ void CegInstantiation::checkCegConjecture( CegConjecture * conj ) { } void CegInstantiation::getCRefEvaluationLemmas( CegConjecture * conj, std::vector< Node >& vs, std::vector< Node >& ms, std::vector< Node >& lems ) { + Trace("sygus-cref-eval") << "Cref eval : conjecture has " << conj->getNumRefinementLemmas() << " refinement lemmas." << std::endl; if( conj->getNumRefinementLemmas()>0 ){ Assert( vs.size()==ms.size() ); - std::map< Node, Node > vtm; - for( unsigned i=0; i<vs.size(); i++ ){ - vtm[vs[i]] = ms[i]; - } - /* - if( options::sygusUnifCondSol() ){ - // first, check progress lemmas TODO? - for( unsigned i=0; i<conj->getNumRefinementLemmas(); i++ ){ - Node plem = conj->getConditionalProgressLemma( i ); - std::vector< Node > pp; - conj-> - std::map< Node, Node > visitedp; - std::map< Node, std::vector< Node > > expp; - conj->getModelValues - } - } - */ + + Node neg_guard = conj->getGuard().negate(); for( unsigned i=0; i<conj->getNumRefinementLemmas(); i++ ){ Node lem; std::map< Node, Node > visited; std::map< Node, std::vector< Node > > exp; - if( options::sygusUnifCondSol() ){ - for( unsigned j=0; j<conj->getNumConditionalEvaluations( i ); j++ ){ - std::map< Node, Node > visitedc; - std::map< Node, std::vector< Node > > expc; - Node ce = conj->getConditionalEvaluationAntec( i, j ); - Node cee = crefEvaluate( ce, vtm, visitedc, expc ); - Trace("sygus-cref-eval") << "Check conditional evaluation condition : " << ce << ", evaluates to " << cee << std::endl; - if( !cee.isNull() && cee==d_quantEngine->getTermDatabase()->d_true ){ - Node conc = conj->getConditionalEvaluationConc( i, j ); - // the conditional holds, we will apply this as a substitution - for( unsigned r=0; r<2; r++ ){ - if( conc[r].isVar() ){ - Node v = conc[r]; - Node c = conc[1-r]; - Assert( exp.find( v )==exp.end() ); - visited[v] = c; - //exp[v].insert( exp[v].end(), expc[ce].begin(), expc[ce].end() ); - exp[v].push_back( ce ); - Trace("sygus-cref-eval") << " consider " << v << " -> " << c << " with expanation " << ce << std::endl; - break; - } - } - } - } - //if at least one conditional fires - if( !visited.empty() ){ - lem = conj->getRefinementBaseLemma( i ); - } - }else{ - lem = conj->getRefinementBaseLemma( i ); - } + lem = conj->getRefinementBaseLemma( i ); if( !lem.isNull() ){ - Trace("sygus-cref-eval") << "Check refinement lemma " << lem << " against current model." << std::endl; - Node elem = crefEvaluate( lem, vtm, visited, exp ); - Trace("sygus-cref-eval") << "...evaluated to " << elem << ", exp size = " << exp[lem].size() << std::endl; - if( !elem.isNull() && elem==d_quantEngine->getTermDatabase()->d_false ){ - elem = conj->getGuard().negate(); - Node cre_lem; - if( !exp[lem].empty() ){ - Node en = exp[lem].size()==1 ? exp[lem][0] : NodeManager::currentNM()->mkNode( kind::AND, exp[lem] ); - cre_lem = NodeManager::currentNM()->mkNode( kind::OR, en.negate(), elem ); - }else{ - cre_lem = elem; - } - if( std::find( lems.begin(), lems.end(), cre_lem )==lems.end() ){ - Trace("sygus-cref-eval") << "...produced lemma : " << cre_lem << std::endl; - lems.push_back( cre_lem ); + std::vector< Node > lem_conj; + //break into conjunctions + if( lem.getKind()==kind::AND ){ + for( unsigned i=0; i<lem.getNumChildren(); i++ ){ + lem_conj.push_back( lem[i] ); } + }else{ + lem_conj.push_back( lem ); } - } - } - } -} - -Node CegInstantiation::crefEvaluate( Node n, std::map< Node, Node >& vtm, std::map< Node, Node >& visited, std::map< Node, std::vector< Node > >& exp ){ - std::map< Node, Node >::iterator itv = visited.find( n ); - Node ret; - std::vector< Node > exp_c; - if( itv!=visited.end() ){ - if( !itv->second.isConst() ){ - //we stored a partially evaluated node, actually evaluate the result now - ret = crefEvaluate( itv->second, vtm, visited, exp ); - exp_c.push_back( itv->second ); - }else{ - return itv->second; - } - }else{ - if( n.getKind()==kind::APPLY_UF ){ - //it is an evaluation function - Trace("sygus-cref-eval-debug") << "Compute evaluation for : " << n << std::endl; - //unfold by one step - Node nn = d_quantEngine->getTermDatabaseSygus()->unfold( n, vtm, exp[n] ); - Trace("sygus-cref-eval-debug") << "...unfolded once to " << nn << std::endl; - Assert( nn!=n ); - //it is the result of evaluating the unfolding - ret = crefEvaluate( nn, vtm, visited, exp ); - //carry explanation - exp_c.push_back( nn ); - } - if( ret.isNull() ){ - if( n.getNumChildren()>0 ){ - std::vector< Node > children; - bool childChanged = false; - if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){ - children.push_back( n.getOperator() ); - } - for( unsigned i=0; i<n.getNumChildren(); i++ ){ - Node nc = crefEvaluate( n[i], vtm, visited, exp ); - childChanged = nc!=n[i] || childChanged; - children.push_back( nc ); - //Boolean short circuiting - if( n.getKind()==kind::AND ){ - if( nc==d_quantEngine->getTermDatabase()->d_false ){ - ret = nc; - exp_c.clear(); - } - }else if( n.getKind()==kind::OR ){ - if( nc==d_quantEngine->getTermDatabase()->d_true ){ - ret = nc; - exp_c.clear(); - } - }else if( n.getKind()==kind::ITE && i==0 ){ - int index = -1; - if( nc==d_quantEngine->getTermDatabase()->d_true ){ - index = 1; - }else if( nc==d_quantEngine->getTermDatabase()->d_false ){ - index = 2; + EvalSygusInvarianceTest vsit; + vsit.d_result = d_quantEngine->getTermDatabase()->d_false; + for( unsigned j=0; j<lem_conj.size(); j++ ){ + Node lemc = lem_conj[j]; + Trace("sygus-cref-eval") << "Check refinement lemma conjunct " << lemc << " against current model." << std::endl; + Trace("sygus-cref-eval2") << "Check refinement lemma conjunct " << lemc << " against current model." << std::endl; + Node cre_lem; + Node lemcs = lemc.substitute( vs.begin(), vs.end(), ms.begin(), ms.end() ); + Trace("sygus-cref-eval2") << "...under substitution it is : " << lemcs << std::endl; + Node lemcsu = d_quantEngine->getTermDatabaseSygus()->evaluateWithUnfolding( lemcs, vsit.d_visited ); + Trace("sygus-cref-eval2") << "...after unfolding is : " << lemcsu << std::endl; + if( lemcsu==d_quantEngine->getTermDatabase()->d_false ){ + std::vector< Node > msu; + std::vector< Node > mexp; + msu.insert( msu.end(), ms.begin(), ms.end() ); + for( unsigned k=0; k<vs.size(); k++ ){ + vsit.d_var = vs[k]; + vsit.d_update_nvn = msu[k]; + msu[k] = vs[k]; + // substitute for everything except this + vsit.d_conj = lemc.substitute( vs.begin(), vs.end(), msu.begin(), msu.end() ); + // get minimal explanation for this + Trace("sygus-cref-eval2-debug") << " compute min explain of : " << vs[k] << " = " << vsit.d_update_nvn << std::endl; + d_quantEngine->getTermDatabaseSygus()->getExplanationFor( vs[k], vsit.d_update_nvn, mexp, vsit ); + msu[k] = vsit.d_update_nvn; } - if( index!=-1 ){ - ret = crefEvaluate( n[index], vtm, visited, exp ); - exp_c.push_back( n[index] ); + if( !mexp.empty() ){ + Node en = mexp.size()==1 ? mexp[0] : NodeManager::currentNM()->mkNode( kind::AND, mexp ); + cre_lem = NodeManager::currentNM()->mkNode( kind::OR, en.negate(), neg_guard ); + }else{ + cre_lem = neg_guard; } } - //carry explanation - exp_c.push_back( n[i] ); - if( !ret.isNull() ){ - break; - } - } - if( ret.isNull() ){ - if( childChanged ){ - ret = NodeManager::currentNM()->mkNode( n.getKind(), children ); - ret = Rewriter::rewrite( ret ); - }else{ - ret = n; - } - } - }else{ - ret = n; - } - } - } - //carry explanation from children - for( unsigned i=0; i<exp_c.size(); i++ ){ - Node nn = exp_c[i]; - std::map< Node, std::vector< Node > >::iterator itx = exp.find( nn ); - if( itx!=exp.end() ){ - for( unsigned j=0; j<itx->second.size(); j++ ){ - if( std::find( exp[n].begin(), exp[n].end(), itx->second[j] )==exp[n].end() ){ - exp[n].push_back( itx->second[j] ); - } - } - } - } - Trace("sygus-cref-eval-debug") << "... evaluation of " << n << " is (" << ret.getKind() << ") " << ret << std::endl; - Trace("sygus-cref-eval-debug") << "...... exp size = " << exp[n].size() << std::endl; - Assert( ret.isNull() || ret.isConst() ); - visited[n] = ret; - return ret; -} - -void CegInstantiation::registerMeasuredType( TypeNode tn ) { - std::map< TypeNode, Node >::iterator it = d_uf_measure.find( tn ); - if( it==d_uf_measure.end() ){ - if( tn.isDatatype() ){ - TypeNode op_tn = NodeManager::currentNM()->mkFunctionType( tn, NodeManager::currentNM()->integerType() ); - Node op = NodeManager::currentNM()->mkSkolem( "tsize", op_tn, "was created by ceg instantiation to enforce fairness." ); - d_uf_measure[tn] = op; - } - } -} - -Node CegInstantiation::getSizeTerm( Node n, TypeNode tn, std::vector< Node >& lems ) { - std::map< Node, Node >::iterator itt = d_size_term.find( n ); - if( itt==d_size_term.end() ){ - registerMeasuredType( tn ); - Node sn = NodeManager::currentNM()->mkNode( APPLY_UF, d_uf_measure[tn], n ); - lems.push_back( NodeManager::currentNM()->mkNode( LEQ, NodeManager::currentNM()->mkConst( Rational(0) ), sn ) ); - d_size_term[n] = sn; - return sn; - }else{ - return itt->second; - } -} - -void CegInstantiation::getMeasureLemmas( Node n, Node v, std::vector< Node >& lems ) { - Trace("cegqi-lemma-debug") << "Get measure lemma " << n << " " << v << std::endl; - Assert( n.getType()==v.getType() ); - TypeNode tn = n.getType(); - if( tn.isDatatype() ){ - Assert( v.getKind()==APPLY_CONSTRUCTOR ); - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - int index = Datatype::indexOf( v.getOperator().toExpr() ); - std::map< int, Node >::iterator it = d_size_term_lemma[n].find( index ); - if( it==d_size_term_lemma[n].end() ){ - Node lhs = getSizeTerm( n, tn, lems ); - //add measure lemma - std::vector< Node > sumc; - for( unsigned j=0; j<dt[index].getNumArgs(); j++ ){ - TypeNode tnc = v[j].getType(); - if( tnc.isDatatype() ){ - Node seln = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[index][j].getSelector() ), n ); - sumc.push_back( getSizeTerm( seln, tnc, lems ) ); - } - } - Node rhs; - if( !sumc.empty() ){ - sumc.push_back( NodeManager::currentNM()->mkConst( Rational(1) ) ); - rhs = NodeManager::currentNM()->mkNode( PLUS, sumc ); - }else{ - rhs = NodeManager::currentNM()->mkConst( Rational(0) ); - } - Node lem = lhs.eqNode( rhs ); - Node cond = NodeManager::currentNM()->mkNode( APPLY_TESTER, Node::fromExpr( dt[index].getTester() ), n ); - lem = NodeManager::currentNM()->mkNode( OR, cond.negate(), lem ); - - d_size_term_lemma[n][index] = lem; - Trace("cegqi-lemma-debug") << "...constructed lemma " << lem << std::endl; - lems.push_back( lem ); - //return; - } - //get lemmas for children - for( unsigned i=0; i<v.getNumChildren(); i++ ){ - Node nn = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[index][i].getSelector() ), n ); - getMeasureLemmas( nn, v[i], lems ); - } - - } -} - -Node CegInstantiation::getEagerUnfold( Node n, std::map< Node, Node >& visited ) { - std::map< Node, Node >::iterator itv = visited.find( n ); - if( itv==visited.end() ){ - Trace("cegqi-eager-debug") << "getEagerUnfold " << n << std::endl; - Node ret; - if( n.getKind()==APPLY_UF ){ - TypeNode tn = n[0].getType(); - Trace("cegqi-eager-debug") << "check " << n[0].getType() << std::endl; - if( tn.isDatatype() ){ - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - if( dt.isSygus() ){ - Trace("cegqi-eager") << "Unfold eager : " << n << std::endl; - Node bTerm = d_quantEngine->getTermDatabaseSygus()->sygusToBuiltin( n[0], tn ); - Trace("cegqi-eager") << "Built-in term : " << bTerm << std::endl; - std::vector< Node > vars; - std::vector< Node > subs; - Node var_list = Node::fromExpr( dt.getSygusVarList() ); - Assert( var_list.getNumChildren()+1==n.getNumChildren() ); - for( unsigned j=0; j<var_list.getNumChildren(); j++ ){ - vars.push_back( var_list[j] ); - } - for( unsigned j=1; j<n.getNumChildren(); j++ ){ - Node nc = getEagerUnfold( n[j], visited ); - subs.push_back( nc ); - Assert( subs[j-1].getType()==var_list[j-1].getType() ); + if( !cre_lem.isNull() ){ + if( std::find( lems.begin(), lems.end(), cre_lem )==lems.end() ){ + Trace("sygus-cref-eval") << "...produced lemma : " << cre_lem << std::endl; + lems.push_back( cre_lem ); + } } - Assert( vars.size()==subs.size() ); - bTerm = bTerm.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() ); - Trace("cegqi-eager") << "Built-in term after subs : " << bTerm << std::endl; - Trace("cegqi-eager-debug") << "Types : " << bTerm.getType() << " " << n.getType() << std::endl; - Assert( n.getType()==bTerm.getType() ); - ret = bTerm; } } } - if( ret.isNull() ){ - if( n.getKind()!=FORALL ){ - bool childChanged = false; - std::vector< Node > children; - for( unsigned i=0; i<n.getNumChildren(); i++ ){ - Node nc = getEagerUnfold( n[i], visited ); - childChanged = childChanged || n[i]!=nc; - children.push_back( nc ); - } - if( childChanged ){ - if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){ - children.insert( children.begin(), n.getOperator() ); - } - ret = NodeManager::currentNM()->mkNode( n.getKind(), children ); - } - } - if( ret.isNull() ){ - ret = n; - } - } - visited[n] = ret; - return ret; - }else{ - return itv->second; } } @@ -1810,7 +924,9 @@ void CegInstantiation::printSynthSolution( std::ostream& out ) { if( d_last_inst_si ){ Assert( d_conj->getCegConjectureSingleInv() != NULL ); sol = d_conj->getSingleInvocationSolution( i, tn, status ); - sol = sol.getKind()==LAMBDA ? sol[1] : sol; + if( !sol.isNull() ){ + sol = sol.getKind()==LAMBDA ? sol[1] : sol; + } }else{ Node cprog = d_conj->getCandidate( i ); if( !d_conj->d_cinfo[cprog].d_inst.empty() ){ @@ -1826,8 +942,10 @@ void CegInstantiation::printSynthSolution( std::ostream& out ) { for( unsigned j=0; j<svl.getNumChildren(); j++ ){ subs.push_back( Node::fromExpr( svl[j] ) ); } - bool templIsPost = false; - Node templ; + //bool templIsPost = false; + const CegConjectureSingleInv* ceg_si = d_conj->getCegConjectureSingleInv(); + Node templ = ceg_si->getTemplate( prog ); + /* if( options::sygusInvTemplMode() == SYGUS_INV_TEMPL_MODE_PRE ){ const CegConjectureSingleInv* ceg_si = d_conj->getCegConjectureSingleInv(); if(ceg_si->d_trans_pre.find( prog ) != ceg_si->d_trans_pre.end()){ @@ -1841,8 +959,11 @@ void CegInstantiation::printSynthSolution( std::ostream& out ) { templIsPost = true; } } + */ Trace("cegqi-inv") << "Template is " << templ << std::endl; if( !templ.isNull() ){ + TNode templa = ceg_si->getTemplateArg( prog ); + Assert( !templa.isNull() ); std::vector<Node>& templ_vars = d_conj->getProgTempVars(prog); std::vector< Node > vars; vars.insert( vars.end(), templ_vars.begin(), templ_vars.end() ); @@ -1860,7 +981,9 @@ void CegInstantiation::printSynthSolution( std::ostream& out ) { Trace("cegqi-inv") << "Builtin version of solution is : " << sol << ", type : " << sol.getType() << std::endl; - sol = NodeManager::currentNM()->mkNode( templIsPost ? AND : OR, sol, templ ); + //sol = NodeManager::currentNM()->mkNode( templIsPost ? AND : OR, sol, templ ); + TNode tsol = sol; + sol = templ.substitute( templa, tsol ); } if( sol==sygus_sol ){ sol = sygus_sol; diff --git a/src/theory/quantifiers/ce_guided_instantiation.h b/src/theory/quantifiers/ce_guided_instantiation.h index 9eef7f070..c5c865ff9 100644 --- a/src/theory/quantifiers/ce_guided_instantiation.h +++ b/src/theory/quantifiers/ce_guided_instantiation.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,9 @@ #include "context/cdchunk_list.h" #include "context/cdhashmap.h" #include "options/quantifiers_modes.h" +#include "options/datatypes_modes.h" #include "theory/quantifiers/ce_guided_single_inv.h" +#include "theory/quantifiers/ce_guided_pbe.h" #include "theory/quantifiers_engine.h" namespace CVC4 { @@ -42,36 +44,13 @@ private: std::vector< std::vector< Node > > d_inner_vars_disj; /** current extential quantifeirs whose couterexamples we must refine */ std::vector< std::vector< Node > > d_ce_sk; - /** the cardinality literals */ - std::map< int, Node > d_lits; - /** current cardinality */ - context::CDO< int > d_curr_lit; - /** active measure term */ - Node d_active_measure_term; /** refinement lemmas */ std::vector< Node > d_refinement_lemmas; std::vector< Node > d_refinement_lemmas_base; - //std::vector< Node > d_refinement_lemmas_cprogress; - //std::vector< std::vector< Node > > d_refinement_lemmas_cprogress_pts; -private: //for condition solutions - std::vector< std::vector< Node > > d_refinement_lemmas_aux_vars; - std::vector< std::vector< Node > > d_refinement_lemmas_ceval_ant; - std::vector< std::vector< Node > > d_refinement_lemmas_ceval_conc; - std::vector< Node > d_refinement_lemmas_ngr; //non-ground version - std::map< Node, bool > d_refinement_lemmas_reproc; - /** get candidate list recursively for conditional solutions */ - void getConditionalCandidateList( std::vector< Node >& clist, Node curr, bool reqAdd ); - Node constructConditionalCandidate( std::map< Node, Node >& cmv, Node curr ); - Node getActiveConditional( Node curr ); - void getContextConditionalNodes( Node curr, Node x, std::vector< Node >& nodes ); - Node mkConditionalEvalNode( Node c, std::vector< Node >& args ); - Node mkConditionalNode( Node v, std::vector< Node >& args, unsigned eindex ); - Node mkConditional( Node v, std::vector< Node >& args, bool pol = true ); - Node purifyConditionalEvaluations( Node n, std::map< Node, Node >& csol_cond, std::map< Node, Node >& psubs, - std::map< Node, Node >& visited ); - /** register candidate conditional */ - void registerCandidateConditional( Node v ); - bool inferIteTemplate( unsigned k, Node n, std::map< Node, unsigned >& templ_var_index, std::map< unsigned, unsigned >& templ_injection ); + /** get embedding */ + Node convertToEmbedding( Node n, std::map< Node, Node >& synth_fun_vars, std::map< Node, Node >& visited ); + /** collect constants */ + void collectConstants( Node n, std::map< TypeNode, std::vector< Node > >& consts, std::map< Node, bool >& visited ); public: CegConjecture( QuantifiersEngine * qe, context::Context* c ); ~CegConjecture(); @@ -83,25 +62,12 @@ public: class CandidateInfo { public: - CandidateInfo() : d_csol_status(-1){} + CandidateInfo(){} /** list of terms we have instantiated candidates with */ std::vector< Node > d_inst; - /** conditional solutions */ - Node d_csol_op; - Node d_csol_cond; - Node d_csol_var[2]; - /** progress guard */ - Node d_csol_progress_guard; - /** solution status */ - int d_csol_status; - /** required for template solutions */ - std::map< unsigned, Node > d_template; - std::map< unsigned, Node > d_template_arg; }; std::map< Node, CandidateInfo > d_cinfo; - /** measure term */ - Node d_measure_term; /** measure sum size */ int d_measure_term_size; /** refine count */ @@ -113,7 +79,8 @@ public: bool needsRefinement(); void getCandidateList( std::vector< Node >& clist, bool forceOrig = false ); - bool constructCandidates( std::vector< Node >& clist, std::vector< Node >& model_values, std::vector< Node >& candidate_values ); + bool constructCandidates( std::vector< Node >& clist, std::vector< Node >& model_values, std::vector< Node >& candidate_values, + std::vector< Node >& lems ); void doCegConjectureSingleInvCheck(std::vector< Node >& lems); void doCegConjectureCheck(std::vector< Node >& lems, std::vector< Node >& model_values); @@ -146,28 +113,19 @@ public: private: /** single invocation utility */ CegConjectureSingleInv * d_ceg_si; + /** program by examples utility */ + CegConjecturePbe * d_ceg_pbe; public: //non-syntax guided (deprecated) /** guard */ bool d_syntax_guided; Node d_nsg_guard; public: - /** get current term size */ - int getCurrentTermSize() { return d_curr_lit.get(); } - /** increment current term size */ - void incrementCurrentTermSize() { d_curr_lit.set( d_curr_lit.get() + 1 ); } - /** set measure term */ - void setMeasureTerm( Node mt ); - /** get measure term */ - Node getMeasureTermFactor( Node v ); - Node getMeasureTerm() { return d_measure_term; } - /** allocate literal */ - Node getFairnessLiteral( int i ); /** get guard */ Node getGuard(); /** is ground */ bool isGround() { return d_inner_vars.empty(); } /** fairness */ - CegqiFairMode getCegqiFairMode(); + SygusFairMode getCegqiFairMode(); /** is single invocation */ bool isSingleInvocation() const; /** is single invocation */ @@ -176,8 +134,6 @@ public: bool needsCheck( std::vector< Node >& lem ); /** preregister conjecture */ void preregisterConjecture( Node q ); - /** initialize guard */ - void initializeGuard(); /** assign */ void assign( Node q ); /** is assigned */ @@ -192,23 +148,6 @@ public: Node getRefinementLemma( unsigned i ) { return d_refinement_lemmas[i]; } /** get refinement lemma */ Node getRefinementBaseLemma( unsigned i ) { return d_refinement_lemmas_base[i]; } - /** get num conditional evaluations */ - unsigned getNumConditionalEvaluations( unsigned i ) { return d_refinement_lemmas_ceval_ant[i].size(); } - /** get conditional evaluation */ - Node getConditionalEvaluationAntec( unsigned i, unsigned j ) { return d_refinement_lemmas_ceval_ant[i][j]; } - Node getConditionalEvaluationConc( unsigned i, unsigned j ) { return d_refinement_lemmas_ceval_conc[i][j]; } - /** get progress lemma */ - //Node getConditionalProgressLemma( unsigned i ) { return d_refinement_lemmas_cprogress[i]; } - /** get progress point */ - //void getConditionalProgressLemmaPoint( unsigned i, std::vector< Node >& pt ){ - // pt.insert( pt.end(), d_refinement_lemmas_cprogress_pts[i].begin(), d_refinement_lemmas_cprogress_pts[i].end() ); - //} -private: - Node getNextDecisionRequestConditional( Node v, unsigned& priority ); - // 1 : active, 0 : unknown, -1 : inactive, -2 : not applicable - int getProgressStatus( Node v ); -public: - Node getNextDecisionRequest( unsigned& priority ); }; @@ -221,26 +160,10 @@ private: /** last instantiation by single invocation module? */ bool d_last_inst_si; /** evaluation axioms */ - std::map< Node, bool > d_eval_axioms; -private: //for enforcing fairness - /** measure functions */ - std::map< TypeNode, Node > d_uf_measure; - /** register measured type */ - void registerMeasuredType( TypeNode tn ); - /** term -> size term */ - std::map< Node, Node > d_size_term; - /** get size term */ - Node getSizeTerm( Node n, TypeNode tn, std::vector< Node >& lems ); - /** term x constructor -> lemma */ - std::map< Node, std::map< int, Node > > d_size_term_lemma; - /** get measure lemmas */ - void getMeasureLemmas( Node n, Node v, std::vector< Node >& lems ); + //std::map< Node, bool > d_eval_axioms; private: //for direct evaluation /** get refinement evaluation */ void getCRefEvaluationLemmas( CegConjecture * conj, std::vector< Node >& vs, std::vector< Node >& ms, std::vector< Node >& lems ); - Node crefEvaluate( Node lem, std::map< Node, Node >& vtm, std::map< Node, Node >& visited, std::map< Node, std::vector< Node > >& exp ); - /** get eager unfolding */ - Node getEagerUnfold( Node n, std::map< Node, Node >& visited ); private: /** check conjecture */ void checkCegConjecture( CegConjecture * conj ); diff --git a/src/theory/quantifiers/ce_guided_pbe.cpp b/src/theory/quantifiers/ce_guided_pbe.cpp new file mode 100644 index 000000000..501e839db --- /dev/null +++ b/src/theory/quantifiers/ce_guided_pbe.cpp @@ -0,0 +1,1859 @@ +/********************* */ +/*! \file ce_guided_pbe.cpp + ** \verbatim + ** Top contributors (to current version): + ** Andrew Reynolds + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2016 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 utility for processing programming by examples synthesis conjectures + ** + **/ +#include "theory/quantifiers/ce_guided_pbe.h" + +#include "expr/datatype.h" +#include "options/quantifiers_options.h" +#include "theory/quantifiers/term_database_sygus.h" +#include "theory/datatypes/datatypes_rewriter.h" + +using namespace CVC4; +using namespace CVC4::kind; +using namespace CVC4::theory; +using namespace CVC4::theory::quantifiers; +using namespace std; + +namespace CVC4 { + +void indent( const char * c, int ind ) { + if( Trace.isOn(c) ){ + for( int i=0; i<ind; i++ ){ + Trace(c) << " "; + } + } +} +void print_val( const char * c, std::vector< Node >& vals, bool pol = true ){ + if( Trace.isOn(c) ){ + for( unsigned i=0; i<vals.size(); i++ ){ + //Trace(c) << ( pol ? vals[i] : !vals[i] ); + Trace(c) << ( ( pol ? vals[i].getConst<bool>() : !vals[i].getConst<bool>() ) ? "1" : "0" ); + } + } +} +void print_strat( const char * c, unsigned s ){ + switch(s){ + case CegConjecturePbe::strat_ITE:Trace(c) << "ITE";break; + case CegConjecturePbe::strat_CONCAT:Trace(c) << "CONCAT";break; + case CegConjecturePbe::strat_ID:Trace(c) << "ID";break; + default:Trace(c) << "strat_" << s;break; + } +} +void print_role( const char * c, unsigned r ){ + switch(r){ + case CegConjecturePbe::enum_io:Trace(c) << "IO";break; + case CegConjecturePbe::enum_ite_condition:Trace(c) << "CONDITION";break; + case CegConjecturePbe::enum_concat_term:Trace(c) << "CTERM";break; + case CegConjecturePbe::enum_any:Trace(c) << "ANY";break; + default:Trace(c) << "role_" << r;break; + } +} + +CegConjecturePbe::CegConjecturePbe(QuantifiersEngine* qe, CegConjecture* p) + : d_qe(qe), + d_parent(p){ + d_tds = d_qe->getTermDatabaseSygus(); + d_true = NodeManager::currentNM()->mkConst(true); + d_false = NodeManager::currentNM()->mkConst(false); + d_is_pbe = false; +} + +CegConjecturePbe::~CegConjecturePbe() { + +} + +//--------------------------------- collecting finite input/output domain information + +void CegConjecturePbe::collectExamples( Node n, std::map< Node, bool >& visited, bool hasPol, bool pol ) { + if( visited.find( n )==visited.end() ){ + visited[n] = true; + Node neval; + Node n_output; + if( n.getKind()==APPLY_UF && n.getNumChildren()>0 ){ + neval = n; + if( hasPol ){ + n_output = !pol ? d_true : d_false; + } + }else if( n.getKind()==EQUAL && hasPol && !pol ){ + for( unsigned r=0; r<2; r++ ){ + if( n[r].getKind()==APPLY_UF && n[r].getNumChildren()>0 ){ + neval = n[r]; + if( n[1-r].isConst() ){ + n_output = n[1-r]; + } + } + } + } + if( !neval.isNull() ){ + if( neval.getKind()==APPLY_UF && neval.getNumChildren()>0 ){ + // is it an evaluation function? + if( d_examples.find( neval[0] )!=d_examples.end() ){ + std::map< Node, bool >::iterator itx = d_examples_invalid.find( neval[0] ); + if( itx==d_examples_invalid.end() ){ + //collect example + bool success = true; + std::vector< Node > ex; + for( unsigned j=1; j<neval.getNumChildren(); j++ ){ + if( !neval[j].isConst() ){ + success = false; + break; + }else{ + ex.push_back( neval[j] ); + } + } + if( success ){ + d_examples[neval[0]].push_back( ex ); + d_examples_out[neval[0]].push_back( n_output ); + d_examples_term[neval[0]].push_back( neval ); + if( n_output.isNull() ){ + d_examples_out_invalid[neval[0]] = true; + }else{ + Assert( n_output.isConst() ); + } + //finished processing this node + return; + }else{ + d_examples_invalid[neval[0]] = true; + d_examples_out_invalid[neval[0]] = true; + } + } + } + } + } + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + bool newHasPol; + bool newPol; + QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol ); + collectExamples( n[i], visited, newHasPol, newPol ); + } + } +} + +void CegConjecturePbe::initialize( Node n, std::vector< Node >& candidates, std::vector< Node >& lemmas ) { + Trace("sygus-pbe") << "Initialize PBE : " << n << std::endl; + + for( unsigned i=0; i<candidates.size(); i++ ){ + Node v = candidates[i]; + d_examples[v].clear(); + d_examples_out[v].clear(); + d_examples_term[v].clear(); + } + + std::map< Node, bool > visited; + collectExamples( n, visited, true, true ); + + for( unsigned i=0; i<candidates.size(); i++ ){ + Node v = candidates[i]; + Trace("sygus-pbe") << " examples for " << v << " : "; + if( d_examples_invalid.find( v )!=d_examples_invalid.end() ){ + Trace("sygus-pbe") << "INVALID" << std::endl; + }else{ + Trace("sygus-pbe") << std::endl; + for( unsigned j=0; j<d_examples[v].size(); j++ ){ + Trace("sygus-pbe") << " "; + for( unsigned k=0; k<d_examples[v][j].size(); k++ ){ + Trace("sygus-pbe") << d_examples[v][j][k] << " "; + } + if( !d_examples_out[v][j].isNull() ){ + Trace("sygus-pbe") << " -> " << d_examples_out[v][j]; + } + Trace("sygus-pbe") << std::endl; + } + } + } + + //register candidates + if( options::sygusUnifCondSol() ){ + if( candidates.size()==1 ){// conditional solutions for multiple function conjectures TODO? + // collect a pool of types over which we will enumerate terms + Node c = candidates[0]; + //the candidate must be input/output examples + if( d_examples_out_invalid.find( c )==d_examples_out_invalid.end() ){ + Assert( d_examples.find( c )!=d_examples.end() ); + Trace("sygus-unif") << "It is input/output examples..." << std::endl; + TypeNode ctn = c.getType(); + d_cinfo[c].initialize( c ); + // collect the enumerator types / form the strategy + collectEnumeratorTypes( c, ctn, enum_io ); + // if we have non-trivial strategies, then use pbe + if( d_cinfo[c].isNonTrivial() ){ + // static learning of redundant constructors + staticLearnRedundantOps( c, lemmas ); + d_is_pbe = true; + } + } + } + } + if( !d_is_pbe ){ + Trace("sygus-unif") << "Do not do PBE optimizations, register..." << std::endl; + for( unsigned i=0; i<candidates.size(); i++ ){ + d_qe->getTermDatabaseSygus()->registerMeasuredTerm( candidates[i], candidates[i] ); + } + } +} + +bool CegConjecturePbe::getPbeExamples( Node v, std::vector< std::vector< Node > >& exs, + std::vector< Node >& exos, std::vector< Node >& exts ) { + std::map< Node, bool >::iterator itx = d_examples_invalid.find( v ); + if( itx==d_examples_invalid.end() ){ + Assert( d_examples.find( v )!=d_examples.end() ); + exs = d_examples[v]; + Assert( d_examples_out.find( v )!=d_examples_out.end() ); + exos = d_examples_out[v]; + Assert( d_examples_term.find( v )!=d_examples_term.end() ); + exts = d_examples_term[v]; + return true; + } + return false; +} + + +// ----------------------------- establishing enumeration types + + +void CegConjecturePbe::registerEnumerator( Node et, Node c, TypeNode tn, unsigned enum_role, bool inSearch ) { + Trace("sygus-unif-debug") << "...register " << et << " for " << ((DatatypeType)tn.toType()).getDatatype().getName(); + Trace("sygus-unif-debug") << ", role = "; + print_role( "sygus-unif-debug", enum_role ); + Trace("sygus-unif-debug") << ", in search = " << inSearch << std::endl; + d_einfo[et].d_parent_candidate = c; + d_einfo[et].d_role = enum_role; + // if we are actually enumerating this (could be a compound node in the strategy) + if( inSearch ){ + std::map< TypeNode, Node >::iterator itn = d_cinfo[c].d_search_enum.find( tn ); + if( itn==d_cinfo[c].d_search_enum.end() ){ + // use this for the search + d_cinfo[c].d_search_enum[tn] = et; + d_cinfo[c].d_esym_list.push_back( et ); + d_einfo[et].d_enum_slave.push_back( et ); + //register measured term with database + d_qe->getTermDatabaseSygus()->registerMeasuredTerm( et, c, true ); + d_einfo[et].d_active_guard = d_qe->getTermDatabaseSygus()->getActiveGuardForMeasureTerm( et ); + }else{ + Trace("sygus-unif-debug") << "Make " << et << " a slave of " << itn->second << std::endl; + d_einfo[itn->second].d_enum_slave.push_back( et ); + } + } +} + +void CegConjecturePbe::collectEnumeratorTypes( Node e, TypeNode tn, unsigned enum_role ) { + if( d_cinfo[e].d_tinfo.find( tn )==d_cinfo[e].d_tinfo.end() ){ + // register type + Trace("sygus-unif") << "Register enumerating type : " << tn << std::endl; + d_cinfo[e].initializeType( tn ); + } + if( d_cinfo[e].d_tinfo[tn].d_enum.find( enum_role )==d_cinfo[e].d_tinfo[tn].d_enum.end() ){ + + Node ee = NodeManager::currentNM()->mkSkolem( "ee", tn ); + d_cinfo[e].d_tinfo[tn].d_enum[enum_role] = ee; + Trace("sygus-unif-debug") << "...enumerator " << ee << " for " << ((DatatypeType)tn.toType()).getDatatype().getName() << ", role = "; + print_role( "sygus-unif-debug", enum_role ); + Trace("sygus-unif-debug") << std::endl; + // wait to register : may or may not actually be enumerating it + + if( enum_role==enum_io ){ + // look at information on how we will construct solutions for this type + Assert( tn.isDatatype() ); + const Datatype& dt = ((DatatypeType)tn.toType()).getDatatype(); + Assert( dt.isSygus() ); + std::map< Node, std::vector< TypeNode > > cop_to_child_types; + std::map< Node, std::map< unsigned, Node > > cop_to_child_templ; + std::map< Node, std::map< unsigned, Node > > cop_to_child_templ_arg; + std::map< Node, unsigned > cop_to_strat; + std::map< Node, unsigned > cop_to_cindex; + + for( unsigned r=0; r<2; r++ ){ + for( unsigned j=0; j<dt.getNumConstructors(); j++ ){ + bool success = false; + Node cop = Node::fromExpr( dt[j].getConstructor() ); + Node op = Node::fromExpr( dt[j].getSygusOp() ); + if( r==0 ){ + cop_to_cindex[cop] = j; + if( op.getKind() == kind::BUILTIN ){ + Kind sk = NodeManager::operatorToKind( op ); + if( sk==kind::ITE ){ + Trace("sygus-unif") << "...type " << dt.getName() << " has ITE, enumerate child types..." << std::endl; + // we can do unification + Assert( dt[j].getNumArgs()==3 ); + cop_to_strat[cop] = strat_ITE; + }else if( sk==kind::STRING_CONCAT ){ + if( dt[j].getNumArgs()==2 ) { + cop_to_strat[cop] = strat_CONCAT; + } + Trace("sygus-unif") << "...type " << dt.getName() << " has CONCAT, child types successful = " << success << std::endl; + } + if( cop_to_strat.find( cop )!=cop_to_strat.end() ){ + // add child types + for( unsigned k=0; k<dt[j].getNumArgs(); k++ ){ + TypeNode ct = TypeNode::fromType( dt[j][k].getRangeType() ); + Trace("sygus-unif") << " Child type " << k << " : " << ((DatatypeType)ct.toType()).getDatatype().getName() << std::endl; + cop_to_child_types[cop].push_back( ct ); + } + } + } + }else if( cop_to_strat.find( cop )==cop_to_strat.end() ){ + // could be a defined function (this is a hack for ICFP benchmarks) + std::vector< Node > utchildren; + utchildren.push_back( cop ); + std::vector< Node > sks; + std::vector< TypeNode > sktns; + for( unsigned k=0; k<dt[j].getNumArgs(); k++ ){ + Type t = dt[j][k].getRangeType(); + TypeNode ttn = TypeNode::fromType( t ); + Node kv = NodeManager::currentNM()->mkSkolem( "ut", ttn ); + sks.push_back( kv ); + sktns.push_back( ttn ); + utchildren.push_back( kv ); + } + Node ut = NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, utchildren ); + std::vector< Node > echildren; + echildren.push_back( Node::fromExpr( dt.getSygusEvaluationFunc() ) ); + echildren.push_back( ut ); + Node sbvl = Node::fromExpr( dt.getSygusVarList() ); + for( unsigned k=0; k<sbvl.getNumChildren(); k++ ){ + echildren.push_back( sbvl[k] ); + } + Node eut = NodeManager::currentNM()->mkNode( kind::APPLY_UF, echildren ); + Trace("sygus-unif-debug2") << "Test evaluation of " << eut << "..." << std::endl; + eut = d_qe->getTermDatabaseSygus()->unfold( eut ); + Trace("sygus-unif-debug2") << "...got " << eut << std::endl; + Trace("sygus-unif-debug2") << "Type : " << eut.getType() << std::endl; + + if( eut.getKind()==kind::ITE ){ + if( dt[j].getNumArgs()>=eut.getNumChildren() ){ + cop_to_strat[cop] = strat_ITE; + } + }else if( eut.getKind()==kind::STRING_CONCAT ){ + if( dt[j].getNumArgs()>=eut.getNumChildren() ){ + cop_to_strat[cop] = strat_CONCAT; + } + }else if( eut.getKind()==kind::APPLY_UF ){ + // identity operator? + if( dt[j].getNumArgs()==1 ){ + cop_to_strat[cop] = strat_ID; + } + } + + if( cop_to_strat.find( cop )!=cop_to_strat.end() ){ + std::map< unsigned, unsigned > templ_injection; + std::vector< Node > vs; + std::vector< Node > ss; + std::map< Node, unsigned > templ_var_index; + for( unsigned k=0; k<sks.size(); k++ ){ + Assert( sks[k].getType().isDatatype() ); + const Datatype& cdt = ((DatatypeType)sks[k].getType().toType()).getDatatype(); + echildren[0] = Node::fromExpr( cdt.getSygusEvaluationFunc() ); + echildren[1] = sks[k]; + Trace("sygus-unif-debug2") << "...set eval dt to " << sks[k] << std::endl; + Node esk = NodeManager::currentNM()->mkNode( kind::APPLY_UF, echildren ); + vs.push_back( esk ); + Node tvar = NodeManager::currentNM()->mkSkolem( "templ", esk.getType() ); + templ_var_index[tvar] = k; + Trace("sygus-unif-debug2") << "* template inference : looking for " << tvar << " for arg " << k << std::endl; + ss.push_back( tvar ); + Trace("sygus-unif-debug2") << "* substitute : " << esk << " -> " << tvar << std::endl; + } + eut = eut.substitute( vs.begin(), vs.end(), ss.begin(), ss.end() ); + Trace("sygus-unif-debug2") << "Defined constructor " << j << ", base term is " << eut << std::endl; + std::map< unsigned, Node > test_args; + if( cop_to_strat[cop] == strat_ID ){ + test_args[0] = eut; + }else{ + for( unsigned k=0; k<eut.getNumChildren(); k++ ){ + test_args[k] = eut[k]; + } + } + for( std::map< unsigned, Node >::iterator it = test_args.begin(); it != test_args.end(); ++it ){ + unsigned k = it->first; + Node eut_c = it->second; + //success if we can find a injection from args to sygus args + if( !inferTemplate( k, eut_c, templ_var_index, templ_injection ) ){ + Trace("sygus-unif-debug2") << "...failed to find injection (range)." << std::endl; + cop_to_strat.erase( cop ); + break; + } + if( templ_injection.find( k )==templ_injection.end() ){ + Trace("sygus-unif-debug2") << "...failed to find injection (domain)." << std::endl; + cop_to_strat.erase( cop ); + break; + } + } + if( cop_to_strat.find( cop )!=cop_to_strat.end() ){ + Trace("sygus-unif") << "...type " << dt.getName() << " has defined constructor matching strategy "; + Trace("sygus-unif") << cop_to_strat[cop] << ", enumerate child types..." << std::endl; + for( unsigned k=0; k<eut.getNumChildren(); k++ ){ + Assert( templ_injection.find( k )!=templ_injection.end() ); + unsigned sk_index = templ_injection[k]; + //also store the template information, if necessary + Node teut = eut[k]; + if( !teut.isVar() ){ + if( cop_to_strat[cop] == strat_ID ){ + Trace("sygus-unif-debug") << "...cannot use template with ID strategy." << std::endl; + cop_to_strat.erase( cop ); + }else{ + cop_to_child_templ[cop][k] = teut; + cop_to_child_templ_arg[cop][k] = ss[sk_index]; + Trace("sygus-unif") << " Arg " << k << " : template : " << teut << ", arg " << ss[sk_index] << std::endl; + } + }else{ + Assert( teut==ss[sk_index] ); + } + } + // collect children types + for( unsigned k=0; k<dt[j].getNumArgs(); k++ ){ + Trace("sygus-unif") << " Child type " << k << " : " << ((DatatypeType)sktns[k].toType()).getDatatype().getName() << std::endl; + cop_to_child_types[cop].push_back( sktns[k] ); + } + } + } + } + } + } + bool search_this = true; + for( std::map< Node, unsigned >::iterator itc = cop_to_strat.begin(); itc != cop_to_strat.end(); ++itc ){ + if( itc->second==strat_CONCAT || ( itc->second==strat_ID && dt.getNumConstructors()==1 ) ){ + search_this = false; + break; + } + } + Trace("sygus-unif-debug2") << "...this register..." << std::endl; + registerEnumerator( ee, e, tn, enum_role, search_this ); + + if( cop_to_child_types.empty() ){ + Trace("sygus-unif") << "...consider " << dt.getName() << " a basic type" << std::endl; + }else{ + for( std::map< Node, std::vector< TypeNode > >::iterator itct = cop_to_child_types.begin(); itct != cop_to_child_types.end(); ++itct ){ + Node cop = itct->first; + Assert( cop_to_strat.find( cop )!=cop_to_strat.end() ); + unsigned strat = cop_to_strat[cop]; + d_cinfo[e].d_tinfo[tn].d_strat[cop].d_this = strat; + Trace("sygus-unif-debug") << "Process strategy for operator : " << cop << " : "; + print_strat("sygus-unif-debug", strat ); + Trace("sygus-unif-debug") << std::endl; + + for( unsigned j=0; j<itct->second.size(); j++ ){ + //calculate if we should allocate a new enumerator : should be true if we have a new role + unsigned enum_role_c = enum_role; + if( strat==strat_ITE ){ + if( j==0 ){ + enum_role_c = enum_ite_condition; + }else{ + // role is the same as parent + } + }else if( strat==strat_CONCAT ){ + enum_role_c = enum_concat_term; + }else if( strat==strat_ID ){ + // role is the same as parent + } + + // register the child type + TypeNode ct = itct->second[j]; + d_cinfo[e].d_tinfo[tn].d_strat[cop].d_csol_cts.push_back( ct ); + + // make the enumerator + Node et; + if( cop_to_child_templ[cop].find( j )!=cop_to_child_templ[cop].end() ){ + // it is templated, allocate a fresh variable + et = NodeManager::currentNM()->mkSkolem( "et", ct ); + Trace("sygus-unif-debug") << "...enumerate " << et << " of type " << ((DatatypeType)ct.toType()).getDatatype().getName(); + Trace("sygus-unif-debug") << " for arg " << j << " of " << ((DatatypeType)tn.toType()).getDatatype().getName() << std::endl; + registerEnumerator( et, e, ct, enum_role_c, true ); + d_einfo[et].d_template = cop_to_child_templ[cop][j]; + d_einfo[et].d_template_arg = cop_to_child_templ_arg[cop][j]; + Assert( !d_einfo[et].d_template.isNull() ); + Assert( !d_einfo[et].d_template_arg.isNull() ); + }else{ + Trace("sygus-unif-debug") << "...child type enumerate " << ((DatatypeType)ct.toType()).getDatatype().getName() << ", role = "; + print_role( "sygus-unif-debug", enum_role_c ); + Trace("sygus-unif-debug") << std::endl; + collectEnumeratorTypes( e, ct, enum_role_c ); + // otherwise use the previous + Assert( d_cinfo[e].d_tinfo[ct].d_enum.find( enum_role_c )!=d_cinfo[e].d_tinfo[ct].d_enum.end() ); + et = d_cinfo[e].d_tinfo[ct].d_enum[enum_role_c]; + } + Trace("sygus-unif-debug") << "Register child enumerator " << et << ", arg " << j << " of " << cop << ", role = "; + print_role( "sygus-unif-debug", enum_role_c ); + Trace("sygus-unif-debug") << std::endl; + Assert( !et.isNull() ); + d_cinfo[e].d_tinfo[tn].d_strat[cop].d_cenum.push_back( et ); + // need to make this take into account template + //Assert( et.getType()==e.getType() || d_einfo[et].d_role!=enum_io ); + } + Trace("sygus-unif") << "Initialized strategy "; + print_strat( "sygus-unif", strat ); + Trace("sygus-unif") << " for " << ((DatatypeType)tn.toType()).getDatatype().getName() << ", operator " << cop; + Trace("sygus-unif") << ", #children = " << d_cinfo[e].d_tinfo[tn].d_strat[cop].d_cenum.size() << std::endl; + Assert( d_cinfo[e].d_tinfo[tn].d_strat[cop].d_cenum.size()==d_cinfo[e].d_tinfo[tn].d_strat[cop].d_csol_cts.size() ); + } + } + }else{ + Trace("sygus-unif-debug") << "...this register (non-io)" << std::endl; + registerEnumerator( ee, e, tn, enum_role, true ); + } + } +} + +bool CegConjecturePbe::inferTemplate( unsigned k, Node n, std::map< Node, unsigned >& templ_var_index, std::map< unsigned, unsigned >& templ_injection ){ + if( n.getNumChildren()==0 ){ + std::map< Node, unsigned >::iterator itt = templ_var_index.find( n ); + if( itt!=templ_var_index.end() ){ + unsigned kk = itt->second; + std::map< unsigned, unsigned >::iterator itti = templ_injection.find( k ); + if( itti==templ_injection.end() ){ + Trace("sygus-unif-debug") << "...set template injection " << k << " -> " << kk << std::endl; + templ_injection[k] = kk; + }else if( itti->second!=kk ){ + return false; + } + } + return true; + }else{ + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + if( !inferTemplate( k, n[i], templ_var_index, templ_injection ) ){ + return false; + } + } + } + return true; +} + +void CegConjecturePbe::staticLearnRedundantOps( Node c, std::vector< Node >& lemmas ) { + for( unsigned i=0; i<d_cinfo[c].d_esym_list.size(); i++ ){ + Node e = d_cinfo[c].d_esym_list[i]; + std::map< Node, EnumInfo >::iterator itn = d_einfo.find( e ); + Assert( itn!=d_einfo.end() ); + // see if there is anything we can eliminate + Trace("sygus-unif") << "* Search enumerator #" << i << " : type " << ((DatatypeType)e.getType().toType()).getDatatype().getName() << " : "; + Trace("sygus-unif") << e << " has " << itn->second.d_enum_slave.size() << " slaves:" << std::endl; + for( unsigned j=0; j<itn->second.d_enum_slave.size(); j++ ){ + Node es = itn->second.d_enum_slave[j]; + std::map< Node, EnumInfo >::iterator itns = d_einfo.find( es ); + Assert( itns!=d_einfo.end() ); + Trace("sygus-unif") << " " << es << ", role = "; + print_role( "sygus-unif", itns->second.d_role ); + Trace("sygus-unif") << std::endl; + } + } + Trace("sygus-unif") << std::endl; + Trace("sygus-unif") << "Strategy for candidate " << c << " is : " << std::endl; + std::map< Node, bool > visited; + std::vector< Node > redundant; + staticLearnRedundantOps( c, d_cinfo[c].getRootEnumerator(), visited, redundant, lemmas, 0 ); + for( unsigned i=0; i<lemmas.size(); i++ ){ + Trace("sygus-unif") << "...can exclude based on : " << lemmas[i] << std::endl; + } +} + +void CegConjecturePbe::staticLearnRedundantOps( Node c, Node e, std::map< Node, bool >& visited, std::vector< Node >& redundant, + std::vector< Node >& lemmas, int ind ) { + + std::map< Node, EnumInfo >::iterator itn = d_einfo.find( e ); + Assert( itn!=d_einfo.end() ); + if( visited.find( e )==visited.end() ){ + visited[e] = true; + + indent("sygus-unif", ind); + Trace("sygus-unif") << e << " : role : "; + print_role("sygus-unif", itn->second.d_role); + Trace("sygus-unif") << " : "; + + if( itn->second.isTemplated() ){ + Trace("sygus-unif") << "basic, templated : \\ " << itn->second.d_template_arg << ". " << itn->second.d_template << std::endl; + }else{ + TypeNode etn = e.getType(); + std::map< TypeNode, EnumTypeInfo >::iterator itt = d_cinfo[c].d_tinfo.find( etn ); + Assert( itt!=d_cinfo[c].d_tinfo.end() ); + if( itt->second.d_strat.empty() ){ + Trace("sygus-unif") << "basic" << std::endl; + }else{ + Trace("sygus-unif") << "compound" << std::endl; + // various strategies + for( std::map< Node, EnumTypeInfoStrat >::iterator itts = itt->second.d_strat.begin(); itts!=itt->second.d_strat.end(); ++itts ){ + indent("sygus-unif", ind+1); + Trace("sygus-unif") << "Strategy : "; + unsigned strat = itts->second.d_this; + print_strat("sygus-unif", strat); + Trace("sygus-unif") << std::endl; + for( unsigned i=0; i<itts->second.d_cenum.size(); i++ ){ + std::vector< Node > redundant_c; + bool no_repeat_op = false; + // do not repeat operators that the strategy uses + if( itts->second.d_csol_cts[i]==etn ){ + if( strat==strat_ITE && i!=0 ){ + no_repeat_op = true; + }else if( strat==strat_CONCAT || strat==strat_ID ){ + no_repeat_op = true; + } + } + if( no_repeat_op ){ + redundant_c.push_back( itts->first ); + } + //do not use standard Boolean connectives in ITE conditions + if( strat==strat_ITE && i==0 && itts->second.d_csol_cts[1]==itts->second.d_csol_cts[2] ){ + TypeNode ctn = itts->second.d_csol_cts[0]; + const Datatype& cdt = ((DatatypeType)ctn.toType()).getDatatype(); + for( unsigned j=0; j<cdt.getNumConstructors(); j++ ){ + Kind ck = d_tds->getConsNumKind( ctn, j ); + if( ck!=UNDEFINED_KIND && TermDb::isBoolConnective( ck ) ){ + bool typeCorrect = true; + for( unsigned k=0; k<cdt[j].getNumArgs(); k++ ){ + if( d_tds->getArgType( cdt[j], k )!=ctn ){ + typeCorrect = false; + break; + } + } + if( typeCorrect ){ + Trace("sygus-unif-debug") << "Exclude Boolean connective in ITE conditional : " << ck << " in conditional type " << cdt.getName() << std::endl; + Node exc_cons = Node::fromExpr( cdt[j].getConstructor() ); + if( std::find( redundant_c.begin(), redundant_c.end(), exc_cons )==redundant_c.end() ){ + redundant_c.push_back( exc_cons ); + } + } + } + } + } + // recurse + staticLearnRedundantOps( c, itts->second.d_cenum[i], visited, redundant_c, lemmas, ind+2 ); + } + } + } + } + }else{ + indent("sygus-unif", ind); + Trace("sygus-unif") << e << std::endl; + } + if( !redundant.empty() ){ + // TODO : if this becomes more general, must get master enumerator here + if( itn->second.d_enum_slave.size()==1 ){ + for( unsigned i=0; i<redundant.size(); i++ ){ + int cindex = Datatype::indexOf( redundant[i].toExpr() ); + Assert( cindex!=-1 ); + const Datatype& dt = Datatype::datatypeOf( redundant[i].toExpr() ); + Node tst = datatypes::DatatypesRewriter::mkTester( e, cindex, dt ).negate(); + if( std::find( lemmas.begin(), lemmas.end(), tst )==lemmas.end() ){ + lemmas.push_back( tst ); + } + } + } + } +} + + +// ------------------------------------------- solution construction from enumeration + +void CegConjecturePbe::getCandidateList( std::vector< Node >& candidates, std::vector< Node >& clist ) { + for( unsigned i=0; i<candidates.size(); i++ ){ + Node v = candidates[i]; + std::map< Node, CandidateInfo >::iterator it = d_cinfo.find( v ); + if( it!=d_cinfo.end() ){ + for( unsigned j=0; j<it->second.d_esym_list.size(); j++ ){ + Node e = it->second.d_esym_list[j]; + std::map< Node, EnumInfo >::iterator it = d_einfo.find( e ); + Assert( it != d_einfo.end() ); + if( getGuardStatus( it->second.d_active_guard )==1 ){ + clist.push_back( e ); + } + } + } + } +} + +bool CegConjecturePbe::constructCandidates( std::vector< Node >& enums, std::vector< Node >& enum_values, + std::vector< Node >& candidates, std::vector< Node >& candidate_values, + std::vector< Node >& lems ) { + Assert( enums.size()==enum_values.size() ); + if( !enums.empty() ){ + unsigned min_term_size = 0; + std::vector< unsigned > enum_consider; + Trace("sygus-pbe-enum") << "Register new enumerated values : " << std::endl; + for( unsigned i=0; i<enums.size(); i++ ){ + Trace("sygus-pbe-enum") << " " << enums[i] << " -> " << enum_values[i] << std::endl; + unsigned sz = d_tds->getSygusTermSize( enum_values[i] ); + if( i==0 || sz<min_term_size ){ + enum_consider.clear(); + min_term_size = sz; + enum_consider.push_back( i ); + }else if( sz==min_term_size ){ + enum_consider.push_back( i ); + } + } + // only consider the enumerators that are at minimum size (for fairness) + Trace("sygus-pbe-enum") << "...register " << enum_consider.size() << " / " << enums.size() << std::endl; + for( unsigned i=0; i<enum_consider.size(); i++ ){ + unsigned j = enum_consider[i]; + addEnumeratedValue( enums[j], enum_values[j], lems ); + } + } + for( unsigned i=0; i<candidates.size(); i++ ){ + Node c = candidates[i]; + //build decision tree for candidate + Node vc = constructSolution( c ); + if( vc.isNull() ){ + return false; + }else{ + candidate_values.push_back( vc ); + } + } + return true; +} + +void CegConjecturePbe::addEnumeratedValue( Node x, Node v, std::vector< Node >& lems ) { + std::map< Node, EnumInfo >::iterator it = d_einfo.find( x ); + Assert( it != d_einfo.end() ); + if( getGuardStatus( it->second.d_active_guard )==1 ){ + Assert( std::find( it->second.d_enum_vals.begin(), it->second.d_enum_vals.end(), v )==it->second.d_enum_vals.end() ); + Node c = it->second.d_parent_candidate; + Node exp_exc; + if( d_examples_out_invalid.find( c )==d_examples_out_invalid.end() ){ + std::map< Node, CandidateInfo >::iterator itc = d_cinfo.find( c ); + Assert( itc != d_cinfo.end() ); + TypeNode xtn = x.getType(); + Node bv = d_tds->sygusToBuiltin( v, xtn ); + std::map< Node, std::vector< std::vector< Node > > >::iterator itx = d_examples.find( c ); + std::map< Node, std::vector< Node > >::iterator itxo = d_examples_out.find( c ); + Assert( itx!=d_examples.end() ); + Assert( itxo!=d_examples_out.end() ); + Assert( itx->second.size()==itxo->second.size() ); + // notify all slaves + Assert( !it->second.d_enum_slave.empty() ); + //explanation for why this value should be excluded + for( unsigned s=0; s<it->second.d_enum_slave.size(); s++ ){ + Node xs = it->second.d_enum_slave[s]; + std::map< Node, EnumInfo >::iterator itv = d_einfo.find( xs ); + Assert( itv!=d_einfo.end() ); + Trace("sygus-pbe-enum") << "Process " << xs << " from " << s << std::endl; + //bool prevIsCover = false; + if( itv->second.d_role==enum_io ){ + Trace("sygus-pbe-enum") << " IO-Eval of "; + //prevIsCover = itv->second.isFeasible(); + }else{ + Trace("sygus-pbe-enum") << "Evaluation of "; + } + Trace("sygus-pbe-enum") << xs << " : "; + //evaluate all input/output examples + std::vector< Node > results; + Node templ = itv->second.d_template; + TNode templ_var = itv->second.d_template_arg; + std::map< Node, bool > cond_vals; + for( unsigned j=0; j<itx->second.size(); j++ ){ + Node res = d_tds->evaluateBuiltin( xtn, bv, itx->second[j] ); + Trace("sygus-pbe-enum-debug") << "...got res = " << res << " from " << bv << std::endl; + Assert( res.isConst() ); + if( !templ.isNull() ){ + TNode tres = res; + res = templ.substitute( templ_var, res ); + res = Rewriter::rewrite( res ); + Assert( res.isConst() ); + } + Node resb; + if( itv->second.d_role==enum_io ){ + Node out = itxo->second[j]; + Assert( out.isConst() ); + resb = res==out ? d_true : d_false; + }else{ + resb = res; + } + cond_vals[resb] = true; + results.push_back( resb ); + if( Trace.isOn("sygus-pbe-enum") ){ + if( resb.getType().isBoolean() ){ + Trace("sygus-pbe-enum") << ( resb==d_true ? "1" : "0" ); + }else{ + Trace("sygus-pbe-enum") << "?"; + } + } + } + bool keep = false; + if( itv->second.d_role==enum_io ){ + if( cond_vals.find( d_true )!=cond_vals.end() || cond_vals.empty() ){ // latter is the degenerate case of no examples + //check subsumbed/subsuming + std::vector< Node > subsume; + if( cond_vals.find( d_false )==cond_vals.end() ){ + // it is the entire solution, we are done + Trace("sygus-pbe-enum") << " ...success, full solution added to PBE pool : " << d_tds->sygusToBuiltin( v ) << std::endl; + if( !itv->second.isSolved() ){ + itv->second.setSolved( v ); + // it subsumes everything + itv->second.d_term_trie.clear(); + itv->second.d_term_trie.addTerm( this, v, results, true, subsume ); + } + keep = true; + }else{ + Node val = itv->second.d_term_trie.addTerm( this, v, results, true, subsume ); + if( val==v ){ + Trace("sygus-pbe-enum") << " ...success"; + if( !subsume.empty() ){ + itv->second.d_enum_subsume.insert( itv->second.d_enum_subsume.end(), subsume.begin(), subsume.end() ); + Trace("sygus-pbe-enum") << " and subsumed " << subsume.size() << " terms"; + } + Trace("sygus-pbe-enum") << "! add to PBE pool : " << d_tds->sygusToBuiltin( v ) << std::endl; + keep = true; + }else{ + Assert( subsume.empty() ); + Trace("sygus-pbe-enum") << " ...fail : subsumed" << std::endl; + } + } + }else{ + Trace("sygus-pbe-enum") << " ...fail : it does not satisfy examples." << std::endl; + } + }else{ + // is it excluded for domain-specific reason? + std::vector< Node > exp_exc_vec; + if( getExplanationForEnumeratorExclude( c, x, v, results, it->second, exp_exc_vec ) ){ + Assert( !exp_exc_vec.empty() ); + exp_exc = exp_exc_vec.size()==1 ? exp_exc_vec[0] : NodeManager::currentNM()->mkNode( kind::AND, exp_exc_vec ); + Trace("sygus-pbe-enum") << " ...fail : term is excluded (domain-specific)" << std::endl; + }else{ + //if( cond_vals.size()!=2 ){ + // // must discriminate + // Trace("sygus-pbe-enum") << " ...fail : conditional is constant." << std::endl; + // keep = false; + //} + // must be unique up to examples + Node val = itv->second.d_term_trie.addCond( this, v, results, true ); + if( val==v ){ + Trace("sygus-pbe-enum") << " ...success! add to PBE pool : " << d_tds->sygusToBuiltin( v ) << std::endl; + keep = true; + }else{ + Trace("sygus-pbe-enum") << " ...fail : term is not unique" << std::endl; + } + itc->second.d_cond_count++; + } + } + if( keep ){ + // notify the parent to retry the build of PBE + itc->second.d_check_sol = true; + itv->second.addEnumValue( this, v, results ); + /* + if( Trace.isOn("sygus-pbe-enum") ){ + if( itv->second.d_role==enum_io ){ + if( !prevIsCover && itv->second.isFeasible() ){ + Trace("sygus-pbe-enum") << "...PBE : success : Evaluation of " << xs << " now covers all examples." << std::endl; + } + } + } + */ + } + } + }else{ + Trace("sygus-pbe-enum-debug") << " ...examples do not have output." << std::endl; + } + //exclude this value on subsequent iterations + Node g = it->second.d_active_guard; + if( exp_exc.isNull() ){ + // if we did not already explain why this should be excluded, use default + exp_exc = d_tds->getExplanationForConstantEquality( x, v ); + } + Node exlem = NodeManager::currentNM()->mkNode( kind::OR, g.negate(), exp_exc.negate() ); + Trace("sygus-pbe-enum-lemma") << "CegConjecturePbe : enumeration exclude lemma : " << exlem << std::endl; + lems.push_back( exlem ); + }else{ + Trace("sygus-pbe-enum-debug") << " ...guard is inactive." << std::endl; + } +} + + + +class NegContainsSygusInvarianceTest : public quantifiers::SygusInvarianceTest { +public: + NegContainsSygusInvarianceTest(){} + ~NegContainsSygusInvarianceTest(){} + Node d_ar; + std::vector< Node > d_exo; + std::vector< unsigned > d_neg_con_indices; + + void init( quantifiers::TermDbSygus * tds, Node ar, std::vector< Node >& exo, std::vector< unsigned >& ncind ) { + if( tds->hasPbeExamples( ar ) ){ + Assert( tds->getNumPbeExamples( ar )==exo.size() ); + d_ar = ar; + d_exo.insert( d_exo.end(), exo.begin(), exo.end() ); + d_neg_con_indices.insert( d_neg_con_indices.end(), ncind.begin(), ncind.end() ); + } + } +protected: + bool invariant( quantifiers::TermDbSygus * tds, Node nvn, Node x ){ + if( !d_ar.isNull() ){ + TypeNode tn = nvn.getType(); + Node nbv = tds->sygusToBuiltin( nvn, tn ); + Node nbvr = tds->extendedRewrite( nbv ); + // if for any of the examples, it is not contained, then we can exclude + for( unsigned i=0; i<d_neg_con_indices.size(); i++ ){ + unsigned ii = d_neg_con_indices[i]; + Assert( ii<d_exo.size() ); + Node nbvre = tds->evaluateBuiltin( tn, nbvr, d_ar, ii ); + Node out = d_exo[ii]; + Node cont = NodeManager::currentNM()->mkNode( kind::STRING_STRCTN, out, nbvre ); + Node contr = Rewriter::rewrite( cont ); + if( contr==tds->d_false ){ + if( Trace.isOn("sygus-pbe-cterm") ){ + Trace("sygus-pbe-cterm") << "PBE-cterm : enumerator : do not consider "; + Trace("sygus-pbe-cterm") << nbv << " for any " << tds->sygusToBuiltin( x ) << " since " << std::endl; + Trace("sygus-pbe-cterm") << " PBE-cterm : for input example : "; + std::vector< Node > ex; + tds->getPbeExample( d_ar, ii, ex ); + for( unsigned j=0; j<ex.size(); j++ ){ + Trace("sygus-pbe-cterm") << ex[j] << " "; + } + Trace("sygus-pbe-cterm") << std::endl; + Trace("sygus-pbe-cterm") << " PBE-cterm : this rewrites to : " << nbvre << std::endl; + Trace("sygus-pbe-cterm") << " PBE-cterm : and is not in output : " << out << std::endl; + } + return true; + } + } + } + return false; + } +}; + + +bool CegConjecturePbe::getExplanationForEnumeratorExclude( Node c, Node x, Node v, std::vector< Node >& results, EnumInfo& ei, std::vector< Node >& exp ) { + if( ei.d_enum_slave.size()==1 ){ + // this check whether the example evaluates to something that is larger than the output + // if so, then this term is never useful when using a concatenation strategy + if( ei.d_role==enum_concat_term ){ + if( Trace.isOn("sygus-pbe-cterm-debug") ){ + Trace("sygus-pbe-enum") << std::endl; + } + + // check if all examples had longer length that the output + std::map< Node, std::vector< Node > >::iterator itxo = d_examples_out.find( c ); + Assert( itxo!=d_examples_out.end() ); + Assert( itxo->second.size()==results.size() ); + Trace("sygus-pbe-cterm-debug") << "Check enumerator exclusion for " << x << " -> " << d_tds->sygusToBuiltin( v ) << " based on containment." << std::endl; + std::vector< unsigned > cmp_indices; + for( unsigned i=0; i<results.size(); i++ ){ + Assert( results[i].isConst() ); + Assert( itxo->second[i].isConst() ); + /* + unsigned vlen = results[i].getConst<String>().size(); + unsigned xlen = itxo->second[i].getConst<String>().size(); + Trace("sygus-pbe-cterm-debug") << " " << results[i] << " <> " << itxo->second[i]; + int index = vlen>xlen ? 1 : ( vlen<xlen ? -1 : 0 ); + Trace("sygus-pbe-cterm-debug") << "..." << index << std::endl; + cmp_indices[index].push_back( i ); + */ + Trace("sygus-pbe-cterm-debug") << " " << results[i] << " <> " << itxo->second[i]; + Node cont = NodeManager::currentNM()->mkNode( kind::STRING_STRCTN, itxo->second[i], results[i] ); + Node contr = Rewriter::rewrite( cont ); + if( contr==d_false ){ + cmp_indices.push_back( i ); + Trace("sygus-pbe-cterm-debug") << "...not contained." << std::endl; + }else{ + Trace("sygus-pbe-cterm-debug") << "...contained." << std::endl; + } + } + // TODO : stronger requirement if we incorporate ITE + CONCAT mixed strategy : must be longer than *all* examples + if( !cmp_indices.empty() ){ + //set up the inclusion set + NegContainsSygusInvarianceTest ncset; + ncset.init( d_tds, c, itxo->second, cmp_indices ); + d_tds->getExplanationFor( x, v, exp, ncset ); + Trace("sygus-pbe-cterm") << "PBE-cterm : enumerator exclude " << d_tds->sygusToBuiltin( v ) << " due to negative containment." << std::endl; + return true; + } + } + } + return false; +} + + + +void CegConjecturePbe::EnumInfo::addEnumValue( CegConjecturePbe * pbe, Node v, std::vector< Node >& results ) { + d_enum_val_to_index[v] = d_enum_vals.size(); + d_enum_vals.push_back( v ); + d_enum_vals_res.push_back( results ); + /* + if( d_role==enum_io ){ + // compute + if( d_enum_total.empty() ){ + d_enum_total = results; + }else if( !d_enum_total_true ){ + d_enum_total_true = true; + Assert( d_enum_total.size()==results.size() ); + for( unsigned i=0; i<results.size(); i++ ){ + if( d_enum_total[i]==pbe->d_true || results[i]==pbe->d_true ){ + d_enum_total[i] = pbe->d_true; + }else{ + d_enum_total[i] = pbe->d_false; + d_enum_total_true = false; + } + } + } + } + */ +} + +void CegConjecturePbe::EnumInfo::setSolved( Node slv ) { + d_enum_solved = slv; + //d_enum_total_true = true; +} + +void CegConjecturePbe::CandidateInfo::initialize( Node c ) { + d_this_candidate = c; + d_root = c.getType(); +} + +void CegConjecturePbe::CandidateInfo::initializeType( TypeNode tn ) { + d_tinfo[tn].d_this_type = tn; + d_tinfo[tn].d_parent = this; +} + +Node CegConjecturePbe::CandidateInfo::getRootEnumerator() { + std::map< unsigned, Node >::iterator it = d_tinfo[d_root].d_enum.find( enum_io ); + Assert( it!=d_tinfo[d_root].d_enum.end() ); + return it->second; +} + +bool CegConjecturePbe::CandidateInfo::isNonTrivial() { + //TODO + return true; +} + +// status : 0 : exact, -1 : vals is subset, 1 : vals is superset +Node CegConjecturePbe::SubsumeTrie::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 ) { + if( index==vals.size() ){ + if( status==0 ){ + // set the term if checkExistsOnly = false + if( d_term.isNull() && !checkExistsOnly ){ + d_term = t; + } + }else if( status==1 ){ + Assert( checkSubsume ); + // found a subsumed term + if( !d_term.isNull() ){ + subsumed.push_back( d_term ); + if( !checkExistsOnly ){ + // remove it if checkExistsOnly = false + d_term = Node::null(); + } + } + }else{ + Assert( !checkExistsOnly && checkSubsume ); + } + return d_term; + }else{ + // the current value + Assert( pol || ( vals[index].isConst() && vals[index].getType().isBoolean() ) ); + Node cv = pol ? vals[index] : ( vals[index]==pbe->d_true ? pbe->d_false : pbe->d_true ); + // if checkExistsOnly = false, check if the current value is subsumed if checkSubsume = true, if so, don't add + if( !checkExistsOnly && checkSubsume ){ + std::vector< bool > check_subsumed_by; + if( status==0 ){ + if( cv==pbe->d_false ){ + check_subsumed_by.push_back( spol ); + } + }else if( status==-1 ){ + check_subsumed_by.push_back( spol ); + if( cv==pbe->d_false ){ + check_subsumed_by.push_back( !spol ); + } + } + // check for subsumed nodes + for( unsigned i=0; i<check_subsumed_by.size(); i++ ){ + Node csval = check_subsumed_by[i] ? pbe->d_true : pbe->d_false; + // check if subsumed + std::map< Node, SubsumeTrie >::iterator itc = d_children.find( csval ); + if( itc!=d_children.end() ){ + unsigned next_index = f ? f->next( index ) : index+1; + Node ret = itc->second.addTermInternal( pbe, t, vals, pol, subsumed, spol, f, next_index, -1, checkExistsOnly, checkSubsume ); + // ret subsumes t + if( !ret.isNull() ){ + return ret; + } + } + } + } + Node ret; + std::vector< bool > check_subsume; + if( status==0 ){ + unsigned next_index = f ? f->next( index ) : index+1; + if( checkExistsOnly ){ + std::map< Node, SubsumeTrie >::iterator itc = d_children.find( cv ); + if( itc!=d_children.end() ){ + ret = itc->second.addTermInternal( pbe, t, vals, pol, subsumed, spol, f, next_index, 0, checkExistsOnly, checkSubsume ); + } + }else{ + Assert( spol ); + ret = d_children[cv].addTermInternal( pbe, t, vals, pol, subsumed, spol, f, next_index, 0, checkExistsOnly, checkSubsume ); + if( ret!=t ){ + // we were subsumed by ret, return + return ret; + } + } + if( checkSubsume ){ + // check for subsuming + if( cv==pbe->d_true ){ + check_subsume.push_back( !spol ); + } + } + }else if( status==1 ){ + Assert( checkSubsume ); + check_subsume.push_back( !spol ); + if( cv==pbe->d_true ){ + check_subsume.push_back( spol ); + } + } + if( checkSubsume ){ + // check for subsumed terms + for( unsigned i=0; i<check_subsume.size(); i++ ){ + Node csval = check_subsume[i] ? pbe->d_true : pbe->d_false; + std::map< Node, SubsumeTrie >::iterator itc = d_children.find( csval ); + if( itc!=d_children.end() ){ + unsigned next_index = f ? f->next( index ) : index+1; + itc->second.addTermInternal( pbe, t, vals, pol, subsumed, spol, f, next_index, 1, checkExistsOnly, checkSubsume ); + // clean up + if( itc->second.isEmpty() ){ + Assert( !checkExistsOnly ); + d_children.erase( csval ); + } + } + } + } + return ret; + } +} + +Node CegConjecturePbe::SubsumeTrie::addTerm( CegConjecturePbe * pbe, Node t, std::vector< Node >& vals, bool pol, std::vector< Node >& subsumed, IndexFilter * f ) { + unsigned start_index = f ? f->start() : 0; + return addTermInternal( pbe, t, vals, pol, subsumed, true, f, start_index, 0, false, true ); +} + +Node CegConjecturePbe::SubsumeTrie::addCond( CegConjecturePbe * pbe, Node c, std::vector< Node >& vals, bool pol, IndexFilter * f ) { + unsigned start_index = f ? f->start() : 0; + std::vector< Node > subsumed; + return addTermInternal( pbe, c, vals, pol, subsumed, true, f, start_index, 0, false, false ); +} + +void CegConjecturePbe::SubsumeTrie::getSubsumed( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol, std::vector< Node >& subsumed, IndexFilter * f ){ + unsigned start_index = f ? f->start() : 0; + addTermInternal( pbe, Node::null(), vals, pol, subsumed, true, f, start_index, 1, true, true ); +} + +void CegConjecturePbe::SubsumeTrie::getSubsumedBy( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol, std::vector< Node >& subsumed_by, IndexFilter * f ){ + // flip polarities + unsigned start_index = f ? f->start() : 0; + addTermInternal( pbe, Node::null(), vals, !pol, subsumed_by, false, f, start_index, 1, true, true ); +} + +void CegConjecturePbe::SubsumeTrie::getLeavesInternal( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol, std::map< int, std::vector< Node > >& v, + IndexFilter * f, unsigned index, int status ) { + if( index==vals.size() ){ + Assert( !d_term.isNull() ); + Assert( std::find( v[status].begin(), v[status].end(), d_term )==v[status].end() ); + v[status].push_back( d_term ); + }else{ + Assert( vals[index].isConst() && vals[index].getType().isBoolean() ); + // filter should be for cv + Assert( f==NULL || vals[index]==( pol ? pbe->d_true : pbe->d_false ) ); + for( std::map< Node, SubsumeTrie >::iterator it = d_children.begin(); it != d_children.end(); ++it ){ + int new_status = status; + // if the current value is true + if( vals[index]==( pol ? pbe->d_true : pbe->d_false ) ){ + if( status!=0 ){ + new_status = ( it->first == pbe->d_true ? 1 : -1 ); + if( status!=-2 && new_status!=status ){ + new_status = 0; + } + } + } + unsigned next_index = f ? f->next( index ) : index+1; + it->second.getLeavesInternal( pbe, vals, pol, v, f, next_index, new_status ); + } + } +} + +void CegConjecturePbe::SubsumeTrie::getLeaves( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol, std::map< int, std::vector< Node > >& v, IndexFilter * f ) { + unsigned start_index = f ? f->start() : 0; + getLeavesInternal( pbe, vals, pol, v, f, start_index, -2 ); +} + +void CegConjecturePbe::IndexFilter::mk( std::vector< Node >& vals, bool pol ) { + Trace("sygus-pbe-debug") << "Make for : "; + print_val( "sygus-pbe-debug", vals, pol ); + Trace("sygus-pbe-debug") << std::endl; + Node poln = NodeManager::currentNM()->mkConst( pol ); + + unsigned curr_index = 0; + while( curr_index<vals.size() && vals[curr_index]!=poln ){ + curr_index++; + } + d_next[0] = curr_index; + Trace("sygus-pbe-debug") << "0 -> " << curr_index << std::endl; + unsigned i = curr_index; + while( i<vals.size() ){ + while( i<vals.size() && vals[i]!=poln ){ + i++; + } + i++; + d_next[curr_index+1] = i; + Trace("sygus-pbe-debug") << curr_index+1 << " -> " << i << std::endl; + curr_index = i; + } + + // verify it is correct + unsigned j = start(); + for( unsigned k=0; k<j; k++ ){ + AlwaysAssert( vals[k]!=poln ); + } + Trace("sygus-pbe-debug") << "...start : " << j << std::endl; + unsigned counter = 0; + while( j<vals.size() ){ + Trace("sygus-pbe-debug") << "...at : " << j << std::endl; + AlwaysAssert( vals[j]==poln ); + unsigned jj = next( j ); + AlwaysAssert( jj>j ); + for( unsigned k=(j+1); k<jj; k++ ){ + AlwaysAssert( vals[k]!=poln ); + } + AlwaysAssert( counter<=vals.size() ); + counter++; + j = jj; + } + + +} + +unsigned CegConjecturePbe::IndexFilter::start() { + std::map< unsigned, unsigned >::iterator it = d_next.find( 0 ); + if( it==d_next.end() ){ + return 0; + }else{ + return it->second; + } +} + +unsigned CegConjecturePbe::IndexFilter::next( unsigned i ) { + std::map< unsigned, unsigned >::iterator it = d_next.find( i+1 ); + if( it==d_next.end() ){ + return i+1; + }else{ + return it->second; + } +} + +bool CegConjecturePbe::IndexFilter::isEq( std::vector< Node >& vals, Node v ) { + unsigned index = start(); + while( index<vals.size() ){ + if( vals[index]!=v ){ + return false; + } + index = next( index ); + } + return true; +} + +Node CegConjecturePbe::constructSolution( Node c ){ + std::map< Node, CandidateInfo >::iterator itc = d_cinfo.find( c ); + Assert( itc!=d_cinfo.end() ); + if( !itc->second.d_solution.isNull() ){ + // already has a solution + return itc->second.d_solution; + }else{ + // only check if an enumerator updated + if( itc->second.d_check_sol ){ + Trace("sygus-pbe") << "Construct solution, #iterations = " << itc->second.d_cond_count << std::endl; + itc->second.d_check_sol = false; + // try multiple times if we have done multiple conditions, due to non-determinism + Node vc; + for( unsigned i=0; i<=itc->second.d_cond_count; i++ ){ + Trace("sygus-pbe-dt") << "ConstructPBE for candidate: " << c << std::endl; + Node e = itc->second.getRootEnumerator(); + UnifContext x; + x.initialize( this, c ); + Node vcc = constructSolution( c, e, x, 1 ); + if( !vcc.isNull() ){ + if( vc.isNull() || ( !vc.isNull() && d_tds->getSygusTermSize( vcc )<d_tds->getSygusTermSize( vc ) ) ){ + Trace("sygus-pbe") << "**** PBE SOLVED : " << c << " = " << vcc << std::endl; + Trace("sygus-pbe") << "...solved at iteration " << i << std::endl; + vc = vcc; + } + } + } + if( !vc.isNull() ){ + itc->second.d_solution = vc; + return vc; + } + Trace("sygus-pbe") << "...failed to solve." << std::endl; + } + return Node::null(); + } +} + +Node CegConjecturePbe::constructBestSolvedTerm( std::vector< Node >& solved, UnifContext& x ){ + Assert( !solved.empty() ); + // TODO + return solved[0]; +} + +Node CegConjecturePbe::constructBestStringSolvedTerm( std::vector< Node >& solved, UnifContext& x ) { + Assert( !solved.empty() ); + // TODO + return solved[0]; +} + +Node CegConjecturePbe::constructBestSolvedConditional( std::vector< Node >& solved, UnifContext& x ){ + Assert( !solved.empty() ); + // TODO + return solved[0]; +} + +Node CegConjecturePbe::constructBestConditional( std::vector< Node >& conds, UnifContext& x ) { + Assert( !conds.empty() ); + // TODO + double r = (double)(rand())/((double)(RAND_MAX)); + unsigned cindex = r*conds.size(); + if( cindex>conds.size() ){ + cindex = conds.size() - 1; + } + return conds[cindex]; +} + +Node CegConjecturePbe::constructBestStringToConcat( std::vector< Node > strs, + std::map< Node, unsigned > total_inc, + std::map< Node, std::vector< unsigned > > incr, + UnifContext& x ) { + Assert( !strs.empty() ); + // TODO + double r = (double)(rand())/((double)(RAND_MAX)); + unsigned cindex = r*strs.size(); + if( cindex>strs.size() ){ + cindex = strs.size() - 1; + } + return strs[cindex]; +} + +Node CegConjecturePbe::constructSolution( Node c, Node e, UnifContext& x, int ind ) { + indent("sygus-pbe-dt-debug", ind); + Trace("sygus-pbe-dt-debug") << "ConstructPBE: enum: " << e << " in context "; + print_val("sygus-pbe-dt-debug", x.d_vals); + Trace("sygus-pbe-dt-debug") << std::endl; + std::map< Node, EnumInfo >::iterator itn = d_einfo.find( e ); + Assert( itn!=d_einfo.end() ); + Node ret_dt; + if( itn->second.d_role==enum_any ){ + indent("sygus-pbe-dt", ind); + ret_dt = constructBestSolvedTerm( itn->second.d_enum_vals, x ); + Trace("sygus-pbe-dt") << "return PBE: success : use any " << d_tds->sygusToBuiltin( ret_dt ) << std::endl; + Assert( !ret_dt.isNull() ); + }else if( itn->second.d_role==enum_io && !x.isReturnValueModified() && itn->second.isSolved() ){ + // this type has a complete solution + ret_dt = itn->second.getSolved(); + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "return PBE: success : solved " << d_tds->sygusToBuiltin( ret_dt ) << std::endl; + Assert( !ret_dt.isNull() ); + }else{ + TypeNode etn = e.getType(); + std::map< TypeNode, EnumTypeInfo >::iterator itt = d_cinfo[c].d_tinfo.find( etn ); + Assert( itt!=d_cinfo[c].d_tinfo.end() ); + if( d_tds->sygusToBuiltinType( e.getType() ).isString() ){ + // check if a current value that closes all examples + + // get the term enumerator for this type + bool success = true; + std::map< Node, EnumInfo >::iterator itet; + if( itn->second.d_role==enum_concat_term ){ + itet = itn; + }else{ + std::map< unsigned, Node >::iterator itnt = itt->second.d_enum.find( enum_concat_term ); + if( itnt != itt->second.d_enum.end() ){ + Node et = itnt->second; + itet = d_einfo.find( et ); + }else{ + success = false; + } + } + if( success ){ + Assert( itet!=d_einfo.end() ); + + // get the current examples + std::map< Node, std::vector< Node > >::iterator itx = d_examples_out.find( c ); + Assert( itx!=d_examples_out.end() ); + std::vector< CVC4::String > ex_vals; + x.getCurrentStrings( this, itx->second, ex_vals ); + Assert( itn->second.d_enum_vals.size()==itn->second.d_enum_vals_res.size() ); + + // test each example in the term enumerator for the type + std::vector< Node > str_solved; + for( unsigned i=0; i<itet->second.d_enum_vals.size(); i++ ){ + if( x.isStringSolved( this, ex_vals, itet->second.d_enum_vals_res[i] ) ){ + str_solved.push_back( itet->second.d_enum_vals[i] ); + } + } + if( !str_solved.empty() ){ + ret_dt = constructBestStringSolvedTerm( str_solved, x ); + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "return PBE: success : string solved " << d_tds->sygusToBuiltin( ret_dt ) << std::endl; + }else{ + indent("sygus-pbe-dt-debug", ind); + Trace("sygus-pbe-dt-debug") << " ...not currently string solved." << std::endl; + } + } + }else if( itn->second.d_role==enum_io && !x.isReturnValueModified() ){ + // it has an enumerated value that is conditionally correct under the current assumptions + std::vector< Node > subsumed_by; + itn->second.d_term_trie.getSubsumedBy( this, x.d_vals, true, subsumed_by ); + if( !subsumed_by.empty() ){ + ret_dt = constructBestSolvedTerm( subsumed_by, x ); + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "return PBE: success : conditionally solved" << d_tds->sygusToBuiltin( ret_dt ) << std::endl; + }else{ + indent("sygus-pbe-dt-debug", ind); + Trace("sygus-pbe-dt-debug") << " ...not currently conditionally solved." << std::endl; + } + } + if( ret_dt.isNull() ){ + if( !itn->second.isTemplated() ){ + // try to construct a compound solution, if strategies are available + + // do various strategies + for( std::map< Node, EnumTypeInfoStrat >::iterator itts = itt->second.d_strat.begin(); itts!=itt->second.d_strat.end(); ++itts ){ + std::map< unsigned, Node > dt_children_cons; + unsigned strat = itts->second.d_this; + + bool success = true; + + // for ITE + std::map< unsigned, Node > look_ahead_solved_children; + Node split_cond_enum; + int split_cond_res_index = -1; + + //for CONCAT + Node incr_val; + int incr_type = 0; + std::map< Node, std::vector< unsigned > > incr; + + // construct the child order + std::vector< unsigned > corder; + if( strat==strat_CONCAT ){ + for( unsigned r=0; r<2; r++ ){ + unsigned sc = r==0 ? 0 : itts->second.d_cenum.size()-1; + Node ce = itts->second.d_cenum[sc]; + if( ce.getType()==etn ){ + // prefer simple recursion (self type) + Assert( d_einfo.find( ce )!=d_einfo.end() ); + Assert( d_einfo[ce].d_role==enum_concat_term ); + corder.push_back( sc ); + unsigned inc = r==0 ? 1 : -1; + unsigned scc = sc + inc; + while( scc>=0 && scc<itts->second.d_cenum.size() ){ + corder.push_back( scc ); + scc = scc + inc; + } + break; + } + } + }else{ + for( unsigned sc=0; sc<itts->second.d_cenum.size(); sc++ ){ + corder.push_back( sc ); + } + } + Assert( corder.size()==itts->second.d_cenum.size() ); + + + for( unsigned scc=0; scc<corder.size(); scc++ ){ + unsigned sc = corder[scc]; + Node rec_c; + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "construct PBE child #" << sc << "..." << std::endl; + std::map< unsigned, Node >::iterator itla = look_ahead_solved_children.find( sc ); + if( itla!=look_ahead_solved_children.end() ){ + rec_c = itla->second; + indent("sygus-pbe-dt-debug", ind+1); + Trace("sygus-pbe-dt-debug") << "ConstructPBE: look ahead solved : " << d_tds->sygusToBuiltin( rec_c ) << std::endl; + }else{ + // get the child enumerator + Node ce = itts->second.d_cenum[sc]; + if( strat==strat_ITE && scc==0 ){ + Assert( itts->second.d_cenum.size()==3 ); // for now, fix to 3 child ITEs + // choose a condition + + // register the condition enumerator + std::map< Node, EnumInfo >::iterator itnc = d_einfo.find( ce ); + Assert( itnc!=d_einfo.end() ); + // only used if the return value is not modified + if( !x.isReturnValueModified() ){ + if( x.d_uinfo.find( ce )==x.d_uinfo.end() ){ + Trace("sygus-pbe-dt-debug2") << " reg : PBE: Look for direct solutions for conditional enumerator " << ce << " ... " << std::endl; + x.d_uinfo[ce].d_status = 0; + Assert( itnc->second.d_enum_vals.size()==itnc->second.d_enum_vals_res.size() ); + for( unsigned i=1; i<=2; i++ ){ + Node te = itts->second.d_cenum[i]; + std::map< Node, EnumInfo >::iterator itnt = d_einfo.find( te ); + Assert( itnt!=d_einfo.end() ); + bool branch_pol = ( i==1 ); + // for each condition, get terms that satisfy it in this branch + for( unsigned k=0; k<itnc->second.d_enum_vals.size(); k++ ){ + Node cond = itnc->second.d_enum_vals[k]; + std::vector< Node > solved; + itnt->second.d_term_trie.getSubsumedBy( this, itnc->second.d_enum_vals_res[k], branch_pol, solved ); + Trace("sygus-pbe-dt-debug2") << " reg : PBE: " << d_tds->sygusToBuiltin( cond ) << " has " << solved.size() << " solutions in branch " << i << std::endl; + if( !solved.empty() ){ + Node slv = constructBestSolvedTerm( solved, x ); + Trace("sygus-pbe-dt-debug") << " reg : PBE: ..." << d_tds->sygusToBuiltin( slv ) << " is a solution under branch " << i; + Trace("sygus-pbe-dt-debug") << " of condition " << d_tds->sygusToBuiltin( cond ) << std::endl; + x.d_uinfo[ce].d_look_ahead_sols[cond][i] = slv; + } + } + } + } + } + + // get the conditionals in the current context : they must be distinguishable + std::map< int, std::vector< Node > > possible_cond; + std::map< Node, int > solved_cond; //stores branch + itnc->second.d_term_trie.getLeaves( this, x.d_vals, true, possible_cond ); + + std::map< int, std::vector< Node > >::iterator itpc = possible_cond.find( 0 ); + if( itpc!=possible_cond.end() ){ + indent("sygus-pbe-dt-debug", ind); + Trace("sygus-pbe-dt-debug") << "PBE : We have " << itpc->second.size() << " distinguishable conditionals:" << std::endl; + for( unsigned k=0; k<itpc->second.size(); k++ ){ + indent("sygus-pbe-dt-debug", ind+1); + Trace("sygus-pbe-dt-debug") << d_tds->sygusToBuiltin( itpc->second[k] ) << std::endl; + } + + + // static look ahead conditional : choose conditionals that have solved terms in at least one branch + // only applicable if we have not modified the return value + std::map< int, std::vector< Node > > solved_cond; + if( !x.isReturnValueModified() ){ + Assert( x.d_uinfo.find( ce )!=x.d_uinfo.end() ); + int solve_max = 0; + for( unsigned k=0; k<itpc->second.size(); k++ ){ + Node cond = itpc->second[k]; + std::map< Node, std::map< unsigned, Node > >::iterator itla = x.d_uinfo[ce].d_look_ahead_sols.find( cond ); + if( itla!=x.d_uinfo[ce].d_look_ahead_sols.end() ){ + int nsolved = itla->second.size(); + solve_max = nsolved > solve_max ? nsolved : solve_max; + solved_cond[nsolved].push_back( cond ); + } + } + int n = solve_max; + while( n>0 ){ + if( !solved_cond[n].empty() ){ + rec_c = constructBestSolvedConditional( solved_cond[n], x ); + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "PBE: ITE strategy : choose solved conditional " << d_tds->sygusToBuiltin( rec_c ) << " with " << n << " solved children..." << std::endl; + std::map< Node, std::map< unsigned, Node > >::iterator itla = x.d_uinfo[ce].d_look_ahead_sols.find( rec_c ); + Assert( itla!=x.d_uinfo[ce].d_look_ahead_sols.end() ); + for( std::map< unsigned, Node >::iterator itla2 = itla->second.begin(); itla2 != itla->second.end(); ++itla2 ){ + look_ahead_solved_children[ itla2->first ] = itla2->second; + } + break; + } + n--; + } + } + + // dynamic look ahead conditional : compute if there are any solved terms in this branch TODO + if( ind>0 ){ + + } + + // otherwise, guess a conditional + if( rec_c.isNull() ){ + rec_c = constructBestConditional( itpc->second, x ); + Assert( !rec_c.isNull() ); + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "PBE: ITE strategy : choose random conditional " << d_tds->sygusToBuiltin( rec_c ) << std::endl; + } + }else{ + // TODO : degenerate case where children have different types + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "return PBE: failed ITE strategy, cannot find a distinguishable condition" << std::endl; + } + if( !rec_c.isNull() ){ + Assert( itnc->second.d_enum_val_to_index.find( rec_c )!=itnc->second.d_enum_val_to_index.end() ); + split_cond_res_index = itnc->second.d_enum_val_to_index[rec_c]; + split_cond_enum = ce; + Assert( split_cond_res_index>=0 ); + Assert( split_cond_res_index<(int)itnc->second.d_enum_vals_res.size() ); + } + }else if( strat==strat_CONCAT && scc==0 ){ + std::map< Node, EnumInfo >::iterator itsc = d_einfo.find( ce ); + Assert( itsc!=d_einfo.end() ); + // ensured by the child order we set above + Assert( itsc->second.d_role==enum_concat_term ); + // check if each return value is a prefix/suffix of all open examples + incr_type = sc==0 ? -1 : 1; + if( x.d_has_string_pos==0 || x.d_has_string_pos==incr_type ){ + bool isPrefix = incr_type==-1; + std::map< Node, unsigned > total_inc; + std::vector< Node > inc_strs; + std::map< Node, std::vector< Node > >::iterator itx = d_examples_out.find( c ); + Assert( itx!=d_examples_out.end() ); + // make the value of the examples + std::vector< CVC4::String > ex_vals; + x.getCurrentStrings( this, itx->second, ex_vals ); + + // check if there is a value for which is a prefix/suffix of all active examples + Assert( itsc->second.d_enum_vals.size()==itsc->second.d_enum_vals_res.size() ); + + for( unsigned i=0; i<itsc->second.d_enum_vals.size(); i++ ){ + Node val_t = itsc->second.d_enum_vals[i]; + indent("sygus-pbe-dt-debug", ind); + Trace("sygus-pbe-dt-debug") << "increment string values : " << val_t << " : "; + Assert( itsc->second.d_enum_vals_res[i].size()==itx->second.size() ); + unsigned tot = 0; + bool exsuccess = x.getStringIncrement( this, isPrefix, ex_vals, itsc->second.d_enum_vals_res[i], incr[val_t], tot ); + if( tot==0 ){ + exsuccess = false; + } + if( !exsuccess ){ + incr.erase( val_t ); + Trace("sygus-pbe-dt-debug") << "...fail" << std::endl; + }else{ + total_inc[ val_t ] = tot; + inc_strs.push_back( val_t ); + Trace("sygus-pbe-dt-debug") << "...success, total increment = " << tot << std::endl; + } + } + + if( !incr.empty() ){ + rec_c = constructBestStringToConcat( inc_strs, total_inc, incr, x ); + incr_val = rec_c; + Assert( !rec_c.isNull() ); + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "PBE: CONCAT strategy : choose " << ( isPrefix ? "pre" : "suf" ) << "fix value " << d_tds->sygusToBuiltin( rec_c ) << std::endl; + }else{ + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "PBE: failed CONCAT strategy, no values are " << ( isPrefix ? "pre" : "suf" ) << "fix of all examples." << std::endl; + } + }else{ + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "PBE: failed CONCAT strategy, prefix/suffix mismatch." << std::endl; + } + }else{ + // a standard term + + // store previous values + std::vector< Node > prev; + std::vector< unsigned > prev_str_pos; + int prev_has_str_pos = false; + // update the context + bool ret = false; + if( strat==strat_ITE ){ + std::map< Node, EnumInfo >::iterator itnc = d_einfo.find( split_cond_enum ); + Assert( itnc!=d_einfo.end() ); + Assert( split_cond_res_index>=0 ); + Assert( split_cond_res_index<(int)itnc->second.d_enum_vals_res.size() ); + prev = x.d_vals; + ret = x.updateContext( this, itnc->second.d_enum_vals_res[split_cond_res_index], sc==1 ); + }else if( strat==strat_CONCAT ){ + prev_str_pos = x.d_str_pos; + prev_has_str_pos = x.d_has_string_pos; + Assert( incr.find( incr_val )!=incr.end() ); + ret = x.updateStringPosition( this, incr[incr_val] ); + x.d_has_string_pos = incr_type; + }else if( strat==strat_ID ){ + ret = true; + } + // must have updated the context + AlwaysAssert( ret ); + // recurse + rec_c = constructSolution( c, ce, x, ind+1 ); + if( !rec_c.isNull() ){ + //revert context + if( strat==strat_ITE ){ + x.d_vals = prev; + }else if( strat==strat_CONCAT ){ + x.d_str_pos = prev_str_pos; + x.d_has_string_pos = prev_has_str_pos; + } + } + } + } + if( !rec_c.isNull() ){ + dt_children_cons[sc] = rec_c; + }else{ + success = false; + break; + } + } + if( success ){ + std::vector< Node > dt_children; + Assert( !itts->first.isNull() ); + dt_children.push_back( itts->first ); + for( unsigned sc=0; sc<itts->second.d_cenum.size(); sc++ ){ + std::map< unsigned, Node >::iterator itdc = dt_children_cons.find( sc ); + Assert( itdc!=dt_children_cons.end() ); + dt_children.push_back( itdc->second ); + } + ret_dt = NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, dt_children ); + indent("sygus-pbe-dt-debug", ind); + Trace("sygus-pbe-dt-debug") << "PBE: success : constructed for strategy "; + print_strat( "sygus-pbe-dt-debug", strat ); + Trace("sygus-pbe-dt-debug") << std::endl; + break; + }else{ + indent("sygus-pbe-dt-debug", ind); + Trace("sygus-pbe-dt-debug") << "PBE: failed for strategy "; + print_strat( "sygus-pbe-dt-debug", strat ); + Trace("sygus-pbe-dt-debug") << std::endl; + } + } + if( ret_dt.isNull() ){ + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "return PBE: fail : all strategies failed " << std::endl; + } + }else{ + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "return PBE: fail : non-basic" << std::endl; + } + } + } + if( !ret_dt.isNull() ){ + Assert( ret_dt.getType()==e.getType() ); + } + indent("sygus-pbe-dt", ind); + Trace("sygus-pbe-dt") << "ConstructPBE: returned " << ret_dt << std::endl; + return ret_dt; +} + +bool CegConjecturePbe::UnifContext::updateContext( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol ) { + Assert( d_vals.size()==vals.size() ); + bool changed = false; + Node poln = pol ? pbe->d_true : pbe->d_false; + for( unsigned i=0; i<vals.size(); i++ ){ + if( vals[i]!=poln ){ + if( d_vals[i]==pbe->d_true ){ + d_vals[i] = pbe->d_false; + changed = true; + } + } + } + return changed; +} + +bool CegConjecturePbe::UnifContext::updateStringPosition( CegConjecturePbe * pbe, std::vector< unsigned >& pos ) { + Assert( pos.size()==d_str_pos.size() ); + bool changed = false; + for( unsigned i=0; i<pos.size(); i++ ){ + if( pos[i]>0 ){ + d_str_pos[i] += pos[i]; + changed = true; + } + } + return changed; +} + +bool CegConjecturePbe::UnifContext::isReturnValueModified() { + if( d_has_string_pos!=0 ){ + return true; + } + return false; +} + +void CegConjecturePbe::UnifContext::initialize( CegConjecturePbe * pbe, Node c ) { + Assert( d_vals.empty() ); + Assert( d_str_pos.empty() ); + + // initialize with #examples + Assert( pbe->d_examples.find( c )!=pbe->d_examples.end() ); + unsigned sz = pbe->d_examples[c].size(); + for( unsigned i=0; i<sz; i++ ){ + d_vals.push_back( pbe->d_true ); + } + + if( !pbe->d_examples_out[c].empty() ){ + // output type of the examples + TypeNode exotn = pbe->d_examples_out[c][0].getType(); + + if( exotn.isString() ){ + for( unsigned i=0; i<sz; i++ ){ + d_str_pos.push_back( 0 ); + } + } + } +} + + +void CegConjecturePbe::UnifContext::getCurrentStrings( CegConjecturePbe * pbe, std::vector< Node >& vals, std::vector< CVC4::String >& ex_vals ) { + bool isPrefix = d_has_string_pos==-1; + CVC4::String dummy; + for( unsigned i=0; i<vals.size(); i++ ){ + if( d_vals[i]==pbe->d_true ){ + Assert( vals[i].isConst() ); + unsigned pos_value = d_str_pos[i]; + if( pos_value>0 ){ + Assert( d_has_string_pos!=0 ); + CVC4::String s = vals[i].getConst<String>(); + Assert( pos_value<=s.size() ); + ex_vals.push_back( isPrefix ? s.suffix( s.size()-pos_value ) : + s.prefix( s.size()-pos_value ) ); + }else{ + ex_vals.push_back( vals[i].getConst<String>() ); + } + }else{ + // irrelevant, add dummy + ex_vals.push_back( dummy ); + } + } +} + +bool CegConjecturePbe::UnifContext::getStringIncrement( CegConjecturePbe * pbe, bool isPrefix, std::vector< CVC4::String >& ex_vals, std::vector< Node >& vals, std::vector< unsigned >& inc, unsigned& tot ) { + for( unsigned j=0; j<vals.size(); j++ ){ + unsigned ival = 0; + if( d_vals[j]==pbe->d_true ){ + // example is active in this context + Assert( vals[j].isConst() ); + CVC4::String mystr = vals[j].getConst<String>(); + ival = mystr.size(); + if( mystr.size()<=ex_vals[j].size() ){ + if( !( isPrefix ? ex_vals[j].strncmp(mystr, ival) : ex_vals[j].rstrncmp(mystr, ival) ) ){ + Trace("sygus-pbe-dt-debug") << "X"; + return false; + } + }else{ + Trace("sygus-pbe-dt-debug") << "X"; + return false; + } + } + Trace("sygus-pbe-dt-debug") << ival; + tot += ival; + inc.push_back( ival ); + } + return true; +} +bool CegConjecturePbe::UnifContext::isStringSolved( CegConjecturePbe * pbe, std::vector< CVC4::String >& ex_vals, std::vector< Node >& vals ) { + for( unsigned j=0; j<vals.size(); j++ ){ + if( d_vals[j]==pbe->d_true ){ + // example is active in this context + Assert( vals[j].isConst() ); + CVC4::String mystr = vals[j].getConst<String>(); + if( ex_vals[j]!=mystr ){ + return false; + } + } + } + return true; +} + +int CegConjecturePbe::getGuardStatus( Node g ) { + bool value; + if( d_qe->getValuation().hasSatValue( g, value ) ) { + if( value ){ + return 1; + }else{ + return -1; + } + }else{ + return 0; + } +} + +} diff --git a/src/theory/quantifiers/ce_guided_pbe.h b/src/theory/quantifiers/ce_guided_pbe.h new file mode 100644 index 000000000..f40f29b2a --- /dev/null +++ b/src/theory/quantifiers/ce_guided_pbe.h @@ -0,0 +1,273 @@ +/********************* */ +/*! \file ce_guided_pbe.h + ** \verbatim + ** Top contributors (to current version): + ** Andrew Reynolds + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2016 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 utility for processing programming by examples synthesis conjectures + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__THEORY__QUANTIFIERS__CE_GUIDED_PBE_H +#define __CVC4__THEORY__QUANTIFIERS__CE_GUIDED_PBE_H + +#include "context/cdhashmap.h" +#include "context/cdchunk_list.h" +#include "theory/quantifiers_engine.h" + +namespace CVC4 { +namespace theory { +namespace quantifiers { + +class CegConjecture; +class CegConjecturePbe; +class CegEntailmentInfer; + +class CegConjecturePbe { +private: + QuantifiersEngine* d_qe; + quantifiers::TermDbSygus * d_tds; + CegConjecture* d_parent; + + std::map< Node, bool > d_examples_invalid; + std::map< Node, bool > d_examples_out_invalid; + std::map< Node, std::vector< std::vector< Node > > > d_examples; + std::map< Node, std::vector< Node > > d_examples_out; + std::map< Node, std::vector< Node > > d_examples_term; + + void collectExamples( Node n, std::map< Node, bool >& visited, bool hasPol, bool pol ); + bool d_is_pbe; +public: + Node d_true; + Node d_false; + enum { + enum_io, + enum_ite_condition, + enum_concat_term, + enum_any, + }; + enum { + strat_ITE, + strat_CONCAT, + strat_ID, + }; +public: + CegConjecturePbe( QuantifiersEngine * qe, CegConjecture * p ); + ~CegConjecturePbe(); + + void initialize( Node n, std::vector< Node >& candidates, std::vector< Node >& lemmas ); + bool getPbeExamples( Node v, std::vector< std::vector< Node > >& exs, + std::vector< Node >& exos, std::vector< Node >& exts); + bool isPbe() { return d_is_pbe; } +private: // for 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 ); + + /** register candidate conditional */ + bool inferTemplate( unsigned k, Node n, std::map< Node, unsigned >& templ_var_index, std::map< unsigned, unsigned >& templ_injection ); + /** get guard status */ + int getGuardStatus( Node g ); +public: + class IndexFilter { + public: + IndexFilter(){} + void mk( std::vector< Node >& vals, bool pol = true ); + std::map< unsigned, unsigned > d_next; + unsigned start(); + unsigned next( unsigned i ); + void clear() { d_next.clear(); } + bool isEq( std::vector< Node >& vs, Node v ); + }; +private: + // subsumption trie + class SubsumeTrie { + private: + 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 ); + public: + SubsumeTrie(){} + Node d_term; + std::map< Node, SubsumeTrie > d_children; + // adds term to the trie, removes based on subsumption + Node addTerm( CegConjecturePbe * pbe, Node t, std::vector< Node >& vals, bool pol, std::vector< Node >& subsumed, IndexFilter * f = NULL ); + // adds condition to the trie (does not do subsumption) + Node addCond( CegConjecturePbe * pbe, Node c, std::vector< Node >& vals, bool pol, IndexFilter * f = NULL ); + // returns the set of terms that are subsets of vals + void getSubsumed( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol, std::vector< Node >& subsumed, IndexFilter * f = NULL ); + // returns the set of terms that are supersets of vals + void getSubsumedBy( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol, std::vector< Node >& subsumed_by, IndexFilter * f = NULL ); + private: + void getLeavesInternal( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol, std::map< int, std::vector< Node > >& v, IndexFilter * f, + unsigned index, int status ); + public: + // v[-1,1,0] -> children always false, always true, both + void getLeaves( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol, std::map< int, std::vector< Node > >& v, IndexFilter * f = NULL ); + public: + bool isEmpty() { return d_term.isNull() && d_children.empty(); } + void clear() { + d_term = Node::null(); + d_children.clear(); + } + }; + + class EnumInfo { + private: + /** an OR of all in d_enum_res */ + //std::vector< Node > d_enum_total; + //bool d_enum_total_true; + Node d_enum_solved; + public: + EnumInfo() : d_role( enum_io ){} + Node d_parent_candidate; + + // for template + Node d_template; + Node d_template_arg; + + // TODO : make private + unsigned d_role; + + Node d_active_guard; + std::vector< Node > d_enum_slave; + /** values we have enumerated */ + std::vector< Node > d_enum_vals; + /** this either stores the values of f( I ) for inputs + or the value of f( I ) = O if d_role==enum_io + */ + std::vector< std::vector< Node > > d_enum_vals_res; + std::vector< Node > d_enum_subsume; + std::map< Node, unsigned > d_enum_val_to_index; + SubsumeTrie d_term_trie; + public: + bool isTemplated() { return !d_template.isNull(); } + 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; } + }; + std::map< Node, EnumInfo > d_einfo; +private: + class CandidateInfo; + class EnumTypeInfoStrat { + public: + unsigned d_this; + /** conditional solutions */ + std::vector< TypeNode > d_csol_cts; + std::vector< Node > d_cenum; + }; + class EnumTypeInfo { + public: + EnumTypeInfo() : d_parent( NULL ){} + CandidateInfo * d_parent; + // role -> _ + std::map< unsigned, Node > d_enum; + TypeNode d_this_type; + // strategies for enum_io role + std::map< Node, EnumTypeInfoStrat > d_strat; + bool isSolved( CegConjecturePbe * pbe ); + }; + class CandidateInfo { + public: + CandidateInfo() : d_check_sol( false ), d_cond_count( 0 ){} + Node d_this_candidate; + TypeNode d_root; + std::map< TypeNode, EnumTypeInfo > d_tinfo; + std::vector< Node > d_esym_list; + // role -> sygus type -> enumerator + std::map< TypeNode, Node > d_search_enum; + bool d_check_sol; + unsigned d_cond_count; + Node d_solution; + void initialize( Node c ); + void initializeType( TypeNode tn ); + Node getRootEnumerator(); + bool isNonTrivial(); + }; + // candidate -> sygus type -> info + std::map< Node, CandidateInfo > d_cinfo; + + /** 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 ); + +private: + // filtering verion + /* + class FilterSubsumeTrie { + public: + SubsumeTrie d_trie; + IndexFilter d_filter; + Node addTerm( Node t, std::vector< bool >& vals, std::vector< Node >& subsumed, bool checkExistsOnly = false ){ + return d_trie.addTerm( t, vals, subsumed, &d_filter, d_filter.start(), checkExistsOnly ); + } + }; + */ + class UnifContext { + public: + UnifContext() : d_has_string_pos(0) {} + //IndexFilter d_filter; + // the value of the context conditional + std::vector< Node > d_vals; + // update the examples + bool updateContext( CegConjecturePbe * pbe, std::vector< Node >& vals, bool pol ); + // the position in the strings + std::vector< unsigned > d_str_pos; + // 0 : pos not modified, 1 : pos indicates suffix incremented, -1 : pos indicates prefix incremented + int d_has_string_pos; + // update the string examples + bool updateStringPosition( CegConjecturePbe * pbe, std::vector< unsigned >& pos ); + // is return value modified + bool isReturnValueModified(); + class UEnumInfo { + public: + UEnumInfo() : d_status(-1){} + int d_status; + // enum val -> polarity -> solved + std::map< Node, std::map< unsigned, Node > > d_look_ahead_sols; + }; + // enumerator -> info + std::map< Node, UEnumInfo > d_uinfo; + void initialize( CegConjecturePbe * pbe, Node c ); + void getCurrentStrings( CegConjecturePbe * pbe, std::vector< Node >& vals, std::vector< CVC4::String >& ex_vals ); + bool getStringIncrement( CegConjecturePbe * pbe, bool isPrefix, std::vector< CVC4::String >& ex_vals, + std::vector< Node >& vals, std::vector< unsigned >& inc, unsigned& tot ); + bool isStringSolved( CegConjecturePbe * pbe, std::vector< CVC4::String >& ex_vals, std::vector< Node >& vals ); + }; + /** construct solution */ + Node constructSolution( Node c ); + Node constructSolution( Node c, Node e, UnifContext& x, int ind ); + Node constructBestSolvedTerm( std::vector< Node >& solved, UnifContext& x ); + Node constructBestStringSolvedTerm( std::vector< Node >& solved, UnifContext& x ); + Node constructBestSolvedConditional( std::vector< Node >& solved, UnifContext& x ); + Node constructBestConditional( std::vector< Node >& conds, UnifContext& x ); + Node constructBestStringToConcat( std::vector< Node > strs, + std::map< Node, unsigned > total_inc, + std::map< Node, std::vector< unsigned > > incr, + UnifContext& x ); + void getStringIncrement( bool isPrefix, Node c, Node v, + std::map< Node, unsigned > total_inc, + std::map< Node, std::vector< unsigned > > incr ); +public: + void registerCandidates( std::vector< Node >& candidates ); + void getCandidateList( std::vector< Node >& candidates, std::vector< Node >& clist ); + // lems and candidate values are outputs + bool constructCandidates( std::vector< Node >& enums, std::vector< Node >& enum_values, + std::vector< Node >& candidates, std::vector< Node >& candidate_values, + std::vector< Node >& lems ); +}; + + +}/* namespace CVC4::theory::quantifiers */ +}/* namespace CVC4::theory */ +}/* namespace CVC4 */ + +#endif diff --git a/src/theory/quantifiers/ce_guided_single_inv.cpp b/src/theory/quantifiers/ce_guided_single_inv.cpp index 33dfa19bc..f25d42284 100644 --- a/src/theory/quantifiers/ce_guided_single_inv.cpp +++ b/src/theory/quantifiers/ce_guided_single_inv.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,7 @@ #include "theory/quantifiers/ce_guided_single_inv_ei.h" #include "theory/quantifiers/first_order_model.h" #include "theory/quantifiers/quant_util.h" -#include "theory/quantifiers/term_database.h" +#include "theory/quantifiers/term_database_sygus.h" #include "theory/quantifiers/trigger.h" #include "theory/theory_engine.h" @@ -174,8 +174,16 @@ void CegConjectureSingleInv::initialize( Node q ) { qq = removeDeepEmbedding( qq, progs, types, type_valid, visited ); Trace("cegqi-si-debug") << "- Remove deep embedding, got : " << qq << ", type valid = " << type_valid << std::endl; if( type_valid==0 ){ + std::vector< Node > prog_funcs; + for( unsigned j=0; j<progs.size(); j++ ){ + std::map< Node, Node >::iterator itns = d_nsi_op_map.find( progs[j] ); + if( itns != d_nsi_op_map.end() ){ + prog_funcs.push_back( itns->second ); + } + } + //process the single invocation-ness of the property - d_sip->init( types, qq ); + d_sip->init( prog_funcs, qq ); Trace("cegqi-si") << "- Partitioned to single invocation parts : " << std::endl; d_sip->debugPrint( "cegqi-si" ); //map from program to bound variables @@ -193,9 +201,12 @@ void CegConjectureSingleInv::initialize( Node q ) { Trace("cegqi-si") << " " << pv << ", " << inv << " is associated with program " << prog << std::endl; d_prog_to_sol_index[prog] = order_vars.size(); order_vars.push_back( pv ); + }else{ + Trace("cegqi-si") << " " << prog << " has no fo var." << std::endl; } }else{ //does not mention the function + Trace("cegqi-si") << " " << prog << " is not mentioned." << std::endl; } } //reorder the variables @@ -215,64 +226,71 @@ void CegConjectureSingleInv::initialize( Node q ) { singleInvocation = true; }else if( options::sygusInvTemplMode() != SYGUS_INV_TEMPL_MODE_NONE ){ //if we are doing invariant templates, then construct the template - std::map< Node, bool > has_inv; - std::map< Node, std::vector< Node > > inv_pre_post[2]; - for( unsigned i=0; i<d_sip->d_conjuncts[2].size(); i++ ){ - std::vector< Node > disjuncts; - Node func; - int pol = -1; - Trace("cegqi-inv") << "INV process " << d_sip->d_conjuncts[2][i] << std::endl; - d_sip->extractInvariant( d_sip->d_conjuncts[2][i], func, pol, disjuncts ); - if( pol>=0 ){ - Assert( d_nsi_op_map_to_prog.find( func )!=d_nsi_op_map_to_prog.end() ); - Node prog = d_nsi_op_map_to_prog[func]; - Trace("cegqi-inv") << "..." << ( pol==0 ? "pre" : "post" ) << "-condition for " << prog << "." << std::endl; - Node c = disjuncts.empty() ? d_qe->getTermDatabase()->d_false : ( disjuncts.size()==1 ? disjuncts[0] : NodeManager::currentNM()->mkNode( OR, disjuncts ) ); - c = pol==0 ? TermDb::simpleNegate( c ) : c; - Trace("cegqi-inv-debug") << "...extracted : " << c << std::endl; - inv_pre_post[pol][prog].push_back( c ); - has_inv[prog] = true; - }else{ - Trace("cegqi-inv") << "...no status." << std::endl; - } - } - - Trace("cegqi-inv") << "Constructing invariant templates..." << std::endl; - //now, contruct the template for the invariant(s) + Trace("cegqi-si") << "- Do transition inference..." << std::endl; + d_ti[q].process( qq ); + Trace("cegqi-inv") << std::endl; std::map< Node, Node > prog_templ; - for( std::map< Node, bool >::iterator iti = has_inv.begin(); iti != has_inv.end(); ++iti ){ - Node prog = iti->first; - Trace("cegqi-inv") << "...for " << prog << "..." << std::endl; - Trace("cegqi-inv") << " args : "; - for( unsigned j=0; j<d_sip->d_si_vars.size(); j++ ){ - std::stringstream ss; - ss << "i_" << j; - Node v = NodeManager::currentNM()->mkBoundVar( ss.str(), d_sip->d_si_vars[j].getType() ); - d_prog_templ_vars[prog].push_back( v ); - Trace("cegqi-inv") << v << " "; - } - Trace("cegqi-inv") << std::endl; - Node pre = inv_pre_post[0][prog].empty() ? NodeManager::currentNM()->mkConst( false ) : - ( inv_pre_post[0][prog].size()==1 ? inv_pre_post[0][prog][0] : NodeManager::currentNM()->mkNode( OR, inv_pre_post[0][prog] ) ); - d_trans_pre[prog] = pre.substitute( d_sip->d_si_vars.begin(), d_sip->d_si_vars.end(), d_prog_templ_vars[prog].begin(), d_prog_templ_vars[prog].end() ); - Node post = inv_pre_post[1][prog].empty() ? NodeManager::currentNM()->mkConst( true ) : - ( inv_pre_post[1][prog].size()==1 ? inv_pre_post[1][prog][0] : NodeManager::currentNM()->mkNode( AND, inv_pre_post[1][prog] ) ); - d_trans_post[prog] = post.substitute( d_sip->d_si_vars.begin(), d_sip->d_si_vars.end(), d_prog_templ_vars[prog].begin(), d_prog_templ_vars[prog].end() ); + if( !d_ti[q].d_func.isNull() ){ + // map the program back via non-single invocation map + Assert( d_nsi_op_map_to_prog.find( d_ti[q].d_func )!=d_nsi_op_map_to_prog.end() ); + Node prog = d_nsi_op_map_to_prog[d_ti[q].d_func]; + Assert( d_prog_templ_vars[prog].empty() ); + d_prog_templ_vars[prog].insert( d_prog_templ_vars[prog].end(), d_ti[q].d_vars.begin(), d_ti[q].d_vars.end() ); + d_trans_pre[prog] = d_ti[q].getComponent( 1 ); + d_trans_post[prog] = d_ti[q].getComponent( -1 ); Trace("cegqi-inv") << " precondition : " << d_trans_pre[prog] << std::endl; Trace("cegqi-inv") << " postcondition : " << d_trans_post[prog] << std::endl; Node invariant = single_inv_app_map[prog]; invariant = invariant.substitute( d_sip->d_si_vars.begin(), d_sip->d_si_vars.end(), d_prog_templ_vars[prog].begin(), d_prog_templ_vars[prog].end() ); Trace("cegqi-inv") << " invariant : " << invariant << std::endl; + //construct template - Node templ; - if( options::sygusInvTemplMode() == SYGUS_INV_TEMPL_MODE_PRE ){ - //templ = NodeManager::currentNM()->mkNode( AND, NodeManager::currentNM()->mkNode( OR, d_trans_pre[prog], invariant ), d_trans_post[prog] ); - templ = NodeManager::currentNM()->mkNode( OR, d_trans_pre[prog], invariant ); - }else{ - Assert( options::sygusInvTemplMode() == SYGUS_INV_TEMPL_MODE_POST ); - //templ = NodeManager::currentNM()->mkNode( OR, d_trans_pre[prog], NodeManager::currentNM()->mkNode( AND, d_trans_post[prog], invariant ) ); - templ = NodeManager::currentNM()->mkNode( AND, d_trans_post[prog], invariant ); + d_templ_arg[prog] = NodeManager::currentNM()->mkSkolem( "I", invariant.getType() ); + if( options::sygusInvAutoUnfold() ){ + if( d_ti[q].isComplete() ){ + Trace("cegqi-inv-auto-unfold") << "Automatic deterministic unfolding... " << std::endl; + // auto-unfold + DetTrace dt; + int init_dt = d_ti[q].initializeTrace( dt ); + if( init_dt==0 ){ + Trace("cegqi-inv-auto-unfold") << " Init : "; + dt.print("cegqi-inv-auto-unfold"); + Trace("cegqi-inv-auto-unfold") << std::endl; + unsigned counter = 0; + unsigned status = 0; + while( counter<100 && status==0 ){ + status = d_ti[q].incrementTrace( dt ); + counter++; + Trace("cegqi-inv-auto-unfold") << " #" << counter << " : "; + dt.print("cegqi-inv-auto-unfold"); + Trace("cegqi-inv-auto-unfold") << "...status = " << status << std::endl; + } + if( status==1 ){ + // we have a trivial invariant + d_templ[prog] = d_ti[q].constructFormulaTrace( dt ); + Trace("cegqi-inv") << "By finite deterministic terminating trace, a solution invariant is : " << std::endl; + Trace("cegqi-inv") << " " << d_templ[prog] << std::endl; + // FIXME : this should be uncessary + d_templ[prog] = NodeManager::currentNM()->mkNode( AND, d_templ[prog], d_templ_arg[prog] ); + } + }else{ + Trace("cegqi-inv-auto-unfold") << "...failed initialize." << std::endl; + } + } + } + if( d_templ[prog].isNull() ){ + if( options::sygusInvTemplMode() == SYGUS_INV_TEMPL_MODE_PRE ){ + //d_templ[prog] = NodeManager::currentNM()->mkNode( AND, NodeManager::currentNM()->mkNode( OR, d_trans_pre[prog], invariant ), d_trans_post[prog] ); + d_templ[prog] = NodeManager::currentNM()->mkNode( OR, d_trans_pre[prog], d_templ_arg[prog] ); + }else{ + Assert( options::sygusInvTemplMode() == SYGUS_INV_TEMPL_MODE_POST ); + //d_templ[prog] = NodeManager::currentNM()->mkNode( OR, d_trans_pre[prog], NodeManager::currentNM()->mkNode( AND, d_trans_post[prog], invariant ) ); + d_templ[prog] = NodeManager::currentNM()->mkNode( AND, d_trans_post[prog], d_templ_arg[prog] ); + } } + TNode iv = d_templ_arg[prog]; + TNode is = invariant; + Node templ = d_templ[prog].substitute( iv, is ); visited.clear(); templ = addDeepEmbedding( templ, visited ); Trace("cegqi-inv") << " template : " << templ << std::endl; @@ -447,7 +465,7 @@ Node CegConjectureSingleInv::removeDeepEmbedding( Node n, std::vector< Node >& p op = it->second; } children[0] = d_nsi_op_map[n[0]]; - ret = NodeManager::currentNM()->mkNode( APPLY_UF, children ); + ret = children.size()>1 ? NodeManager::currentNM()->mkNode( APPLY_UF, children ) : children[0]; } } if( ret.isNull() ){ @@ -591,6 +609,7 @@ bool CegConjectureSingleInv::addLemma( Node n ) { bool CegConjectureSingleInv::check( std::vector< Node >& lems ) { if( !d_single_inv.isNull() ) { + Trace("cegqi-si-debug") << "CegConjectureSingleInv::check..." << std::endl; if( !d_ns_guard.isNull() ){ //if partially single invocation, check if we have constructed a candidate by refutation bool value; @@ -636,6 +655,7 @@ bool CegConjectureSingleInv::check( std::vector< Node >& lems ) { Trace("cegqi-lemma") << "Cegqi::Lemma : verification, refinement lemma : " << inst << std::endl; d_qe->addLemma( finst_lem ); */ + Trace("cegqi-si-debug") << "CegConjectureSingleInv::check returned verification lemma (nsi)..." << std::endl; return true; }else{ //currently trying to construct candidate by refutation (by d_cinst->check below) @@ -650,9 +670,12 @@ bool CegConjectureSingleInv::check( std::vector< Node >& lems ) { //construct d_single_inv d_single_inv = Node::null(); initializeNextSiConjecture(); + Trace("cegqi-si-debug") << "CegConjectureSingleInv::check initialized next si conjecture..." << std::endl; return true; } + Trace("cegqi-si-debug") << "CegConjectureSingleInv::check consulting ceg instantiation..." << std::endl; d_curr_lemmas.clear(); + Assert( d_cinst!=NULL ); //call check for instantiator d_cinst->check(); //add lemmas @@ -667,6 +690,7 @@ bool CegConjectureSingleInv::check( std::vector< Node >& lems ) { } return !lems.empty(); }else{ + // not single invocation return false; } } @@ -706,15 +730,13 @@ struct sortSiInstanceIndices { Node CegConjectureSingleInv::postProcessSolution( Node n ){ - /* ////remove boolean ITE (not allowed for sygus comp 2015) - if( n.getKind()==ITE && n.getType().isBoolean() ){ - Node n1 = postProcessSolution( n[1] ); - Node n2 = postProcessSolution( n[2] ); - return NodeManager::currentNM()->mkNode( OR, NodeManager::currentNM()->mkNode( AND, n[0], n1 ), - NodeManager::currentNM()->mkNode( AND, n[0].negate(), n2 ) ); - }else{ - */ + //if( n.getKind()==ITE && n.getType().isBoolean() ){ + // Node n1 = postProcessSolution( n[1] ); + // Node n2 = postProcessSolution( n[2] ); + // return NodeManager::currentNM()->mkNode( OR, NodeManager::currentNM()->mkNode( AND, n[0], n1 ), + // NodeManager::currentNM()->mkNode( AND, n[0].negate(), n2 ) ); + //}else{ bool childChanged = false; Kind k = n.getKind(); if( n.getKind()==INTS_DIVISION_TOTAL ){ @@ -738,6 +760,7 @@ Node CegConjectureSingleInv::postProcessSolution( Node n ){ }else{ return n; } + //} } @@ -817,7 +840,6 @@ Node CegConjectureSingleInv::getSolution( unsigned sol_index, TypeNode stn, int& Node CegConjectureSingleInv::reconstructToSyntax( Node s, TypeNode stn, int& reconstructed, bool rconsSygus ) { d_solution = s; const Datatype& dt = ((DatatypeType)(stn).toType()).getDatatype(); - Trace("csi-sol") << "Reconstruct to syntax " << s << ", allow all = " << dt.getSygusAllowAll() << " " << stn << ", reconstruct = " << rconsSygus << std::endl; //reconstruct the solution into sygus if necessary reconstructed = 0; @@ -866,6 +888,8 @@ Node CegConjectureSingleInv::reconstructToSyntax( Node s, TypeNode stn, int& rec Node sol; if( reconstructed==1 ){ sol = d_sygus_solution; + }else if( reconstructed==-1 ){ + return Node::null(); }else{ sol = d_solution; } @@ -895,20 +919,21 @@ bool SingleInvocationPartition::init( Node n ) { //first, get types of arguments for functions std::vector< TypeNode > typs; std::map< Node, bool > visited; + std::vector< Node > funcs; if( inferArgTypes( n, typs, visited ) ){ - return init( typs, n ); + return init( funcs, typs, n, false ); }else{ Trace("si-prt") << "Could not infer argument types." << std::endl; return false; } } +// gets the argument type list for the first APPLY_UF we see bool SingleInvocationPartition::inferArgTypes( Node n, std::vector< TypeNode >& typs, std::map< Node, bool >& visited ) { if( visited.find( n )==visited.end() ){ visited[n] = true; if( n.getKind()!=FORALL ){ - //if( TermDb::hasBoundVarAttr( n ) ){ - if( n.getKind()==d_checkKind ){ + if( n.getKind()==APPLY_UF ){ for( unsigned i=0; i<n.getNumChildren(); i++ ){ typs.push_back( n[i].getType() ); } @@ -920,16 +945,41 @@ bool SingleInvocationPartition::inferArgTypes( Node n, std::vector< TypeNode >& } } } - //} } } return false; } -bool SingleInvocationPartition::init( std::vector< TypeNode >& typs, Node n ){ +bool SingleInvocationPartition::init( std::vector< Node >& funcs, Node n ) { + Trace("si-prt") << "Initialize with " << funcs.size() << " input functions..." << std::endl; + std::vector< TypeNode > typs; + if( !funcs.empty() ){ + TypeNode tn0 = funcs[0].getType(); + for( unsigned i=1; i<funcs.size(); i++ ){ + if( funcs[i].getType()!=tn0 ){ + // can't anti-skolemize functions of different sort + Trace("si-prt") << "...type mismatch" << std::endl; + return false; + } + } + if( tn0.getNumChildren()>1 ){ + for( unsigned j=0; j<tn0.getNumChildren()-1; j++ ){ + typs.push_back( tn0[j] ); + } + } + } + Trace("si-prt") << "#types = " << typs.size() << std::endl; + return init( funcs, typs, n, true ); +} + +bool SingleInvocationPartition::init( std::vector< Node >& funcs, std::vector< TypeNode >& typs, Node n, bool has_funcs ){ Assert( d_arg_types.empty() ); + Assert( d_input_funcs.empty() ); Assert( d_si_vars.empty() ); + d_has_input_funcs = has_funcs; d_arg_types.insert( d_arg_types.end(), typs.begin(), typs.end() ); + d_input_funcs.insert( d_input_funcs.end(), funcs.begin(), funcs.end() ); + Trace("si-prt") << "Initialize..." << std::endl; for( unsigned j=0; j<d_arg_types.size(); j++ ){ std::stringstream ss; ss << "s_" << j; @@ -968,7 +1018,9 @@ void SingleInvocationPartition::process( Node n ) { if( processConjunct( cr, visited, args, terms, subs ) ){ for( unsigned j=0; j<terms.size(); j++ ){ si_terms.push_back( subs[j] ); - si_subs.push_back( d_func_fo_var[subs[j].getOperator()] ); + Node op = subs[j].hasOperator() ? subs[j].getOperator() : subs[j]; + Assert( d_func_fo_var.find( op )!=d_func_fo_var.end() ); + si_subs.push_back( d_func_fo_var[op] ); } std::map< Node, Node > subs_map; std::map< Node, Node > subs_map_rev; @@ -1090,9 +1142,21 @@ bool SingleInvocationPartition::processConjunct( Node n, std::map< Node, bool >& } } if( ret ){ - if( n.getKind()==d_checkKind ){ + Node f; + bool success = false; + if( d_has_input_funcs ){ + f = n.hasOperator() ? n.getOperator() : n; + if( std::find( d_input_funcs.begin(), d_input_funcs.end(), f )!=d_input_funcs.end() ){ + success = true; + } + }else{ + if( n.getKind()==kind::APPLY_UF ){ + f = n.getOperator(); + success = true; + } + } + if( success ){ if( std::find( terms.begin(), terms.end(), n )==terms.end() ){ - Node f = n.getOperator(); //check if it matches the type requirement if( isAntiSkolemizableType( f ) ){ if( args.empty() ){ @@ -1134,7 +1198,7 @@ bool SingleInvocationPartition::isAntiSkolemizableType( Node f ) { }else{ TypeNode tn = f.getType(); bool ret = false; - if( tn.getNumChildren()==d_arg_types.size()+1 ){ + if( tn.getNumChildren()==d_arg_types.size()+1 || ( d_arg_types.empty() && tn.getNumChildren()==0 ) ){ ret = true; std::vector< Node > children; children.push_back( f ); @@ -1147,12 +1211,23 @@ bool SingleInvocationPartition::isAntiSkolemizableType( Node f ) { } } if( ret ){ - Node t = NodeManager::currentNM()->mkNode( d_checkKind, children ); + Node t; + if( children.size()>1 ){ + t = NodeManager::currentNM()->mkNode( kind::APPLY_UF, children ); + }else{ + t = children[0]; + } d_func_inv[f] = t; d_inv_to_func[t] = f; std::stringstream ss; ss << "F_" << f; - Node v = NodeManager::currentNM()->mkBoundVar( ss.str(), tn.getRangeType() ); + TypeNode rt; + if( d_arg_types.empty() ){ + rt = tn; + }else{ + rt = tn.getRangeType(); + } + Node v = NodeManager::currentNM()->mkBoundVar( ss.str(), rt ); d_func_fo_var[f] = v; d_fo_var_to_func[v] = f; d_func_vars.push_back( v ); @@ -1181,8 +1256,21 @@ Node SingleInvocationPartition::getSpecificationInst( Node n, std::map< Node, No childChanged = childChanged || ( nn!=n[i] ); } Node ret; - if( n.getKind()==d_checkKind ){ - std::map< Node, Node >::iterator itl = lam.find( n.getOperator() ); + Node f; + bool success = false; + if( d_has_input_funcs ){ + f = n.hasOperator() ? n.getOperator() : n; + if( std::find( d_input_funcs.begin(), d_input_funcs.end(), f )!=d_input_funcs.end() ){ + success = true; + } + }else{ + if( n.getKind()==APPLY_UF ){ + f = n.getOperator(); + success = true; + } + } + if( success ){ + std::map< Node, Node >::iterator itl = lam.find( f ); if( itl!=lam.end() ){ Assert( itl->second[0].getNumChildren()==children.size() ); std::vector< Node > terms; @@ -1214,55 +1302,6 @@ Node SingleInvocationPartition::getSpecificationInst( int index, std::map< Node, return getSpecificationInst( conj, lam, visited ); } -void SingleInvocationPartition::extractInvariant( Node n, Node& func, int& pol, std::vector< Node >& disjuncts ) { - std::map< Node, bool > visited; - extractInvariant2( n, func, pol, disjuncts, true, visited ); -} - -void SingleInvocationPartition::extractInvariant2( Node n, Node& func, int& pol, std::vector< Node >& disjuncts, bool hasPol, std::map< Node, bool >& visited ) { - if( visited.find( n )==visited.end() && pol!=-2 ){ - Trace("cegqi-inv-debug2") << "Extract : " << n << " " << hasPol << ", pol = " << pol << std::endl; - visited[n] = true; - if( n.getKind()==OR && hasPol ){ - for( unsigned i=0; i<n.getNumChildren(); i++ ){ - extractInvariant2( n[i], func, pol, disjuncts, true, visited ); - } - }else{ - if( hasPol ){ - bool lit_pol = n.getKind()!=NOT; - Node lit = n.getKind()==NOT ? n[0] : n; - std::map< Node, Node >::iterator it = d_inv_to_func.find( lit ); - if( it!=d_inv_to_func.end() ){ - if( pol==-1 ){ - pol = lit_pol ? 0 : 1; - func = it->second; - }else{ - //mixing multiple invariants - pol = -2; - } - return; - }else{ - disjuncts.push_back( n ); - } - } - //if another part mentions UF or a free variable, then fail - if( n.getKind()==APPLY_UF ){ - Node op = n.getOperator(); - if( d_funcs.find( op )!=d_funcs.end() ){ - pol = -2; - return; - } - }else if( n.getKind()==BOUND_VARIABLE && std::find( d_si_vars.begin(), d_si_vars.end(), n )==d_si_vars.end() ){ - pol = -2; - return; - } - for( unsigned i=0; i<n.getNumChildren(); i++ ){ - extractInvariant2( n[i], func, pol, disjuncts, false, visited ); - } - } - } -} - void SingleInvocationPartition::debugPrint( const char * c ) { Trace(c) << "Single invocation variables : "; for( unsigned i=0; i<d_si_vars.size(); i++ ){ @@ -1288,4 +1327,391 @@ void SingleInvocationPartition::debugPrint( const char * c ) { Trace(c) << std::endl; } + +bool DetTrace::DetTraceTrie::add( Node loc, std::vector< Node >& val, unsigned index ){ + if( index==val.size() ){ + if( d_children.empty() ){ + d_children[loc].clear(); + return true; + }else{ + return false; + } + }else{ + return d_children[val[index]].add( loc, val, index+1 ); + } } + +Node DetTrace::DetTraceTrie::constructFormula( std::vector< Node >& vars, unsigned index ){ + if( index==vars.size() ){ + return NodeManager::currentNM()->mkConst( true ); + }else{ + std::vector< Node > disj; + for( std::map< Node, DetTraceTrie >::iterator it = d_children.begin(); it != d_children.end(); ++it ){ + Node eq = vars[index].eqNode( it->first ); + if( index<vars.size()-1 ){ + Node conc = it->second.constructFormula( vars, index+1 ); + disj.push_back( NodeManager::currentNM()->mkNode( kind::AND, eq, conc ) ); + }else{ + disj.push_back( eq ); + } + } + Assert( !disj.empty() ); + return disj.size()==1 ? disj[0] : NodeManager::currentNM()->mkNode( kind::OR, disj ); + } +} + +bool DetTrace::increment( Node loc, std::vector< Node >& vals ){ + if( d_trie.add( loc, vals ) ){ + for( unsigned i=0; i<vals.size(); i++ ){ + d_curr[i] = vals[i]; + } + return true; + }else{ + return false; + } +} + +Node DetTrace::constructFormula( std::vector< Node >& vars ) { + return d_trie.constructFormula( vars ); +} + + +void DetTrace::print( const char* c ) { + for( unsigned i=0; i<d_curr.size(); i++ ){ + Trace(c) << d_curr[i] << " "; + } +} + +void TransitionInference::initialize( Node f, std::vector< Node >& vars ) { + Assert( d_vars.empty() ); + d_func = f; + d_vars.insert( d_vars.end(), vars.begin(), vars.end() ); +} + + +void TransitionInference::getConstantSubstitution( std::vector< Node >& vars, std::vector< Node >& disjuncts, std::vector< Node >& const_var, std::vector< Node >& const_subs, bool reqPol ) { + for( unsigned j=0; j<disjuncts.size(); j++ ){ + Node sn; + if( !const_var.empty() ){ + sn = disjuncts[j].substitute( const_var.begin(), const_var.end(), const_subs.begin(), const_subs.end() ); + sn = Rewriter::rewrite( sn ); + }else{ + sn = disjuncts[j]; + } + bool slit_pol = sn.getKind()!=NOT; + Node slit = sn.getKind()==NOT ? sn[0] : sn; + if( slit.getKind()==EQUAL && slit_pol==reqPol ){ + // check if it is a variable equality + TNode v; + Node s; + for( unsigned r=0; r<2; r++ ){ + if( std::find( vars.begin(), vars.end(), slit[r] )!=vars.end() ){ + if( !TermDb::containsTerm( slit[1-r], slit[r] ) ){ + v = slit[r]; + s = slit[1-r]; + break; + } + } + } + if( v.isNull() ){ + //solve for var + std::map< Node, Node > msum; + if( QuantArith::getMonomialSumLit( slit, msum ) ){ + for( std::map< Node, Node >::iterator itm = msum.begin(); itm != msum.end(); ++itm ){ + if( std::find( vars.begin(), vars.end(), itm->first )!=vars.end() ){ + Node veq_c; + Node val; + int ires = QuantArith::isolate( itm->first, msum, veq_c, val, EQUAL ); + if( ires!=0 && veq_c.isNull() && !TermDb::containsTerm( val, itm->first ) ){ + v = itm->first; + s = val; + } + } + } + } + } + if( !v.isNull() ){ + TNode ts = s; + for( unsigned k=0; k<const_subs.size(); k++ ){ + const_subs[k] = Rewriter::rewrite( const_subs[k].substitute( v, ts ) ); + } + Trace("cegqi-inv-debug2") << "...substitution : " << v << " -> " << s << std::endl; + const_var.push_back( v ); + const_subs.push_back( s ); + } + } + } +} + +void TransitionInference::process( Node n ) { + d_complete = true; + std::vector< Node > n_check; + if( n.getKind()==AND ){ + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + n_check.push_back( n[i] ); + } + }else{ + n_check.push_back( n ); + } + for( unsigned i=0; i<n_check.size(); i++ ){ + Node nn = n_check[i]; + std::map< Node, bool > visited; + std::map< bool, Node > terms; + std::vector< Node > disjuncts; + Trace("cegqi-inv") << "TransitionInference : Process disjunct : " << nn << std::endl; + if( processDisjunct( nn, terms, disjuncts, visited, true ) ){ + if( !terms.empty() ){ + Node norm_args; + int comp_num; + std::map< bool, Node >::iterator itt = terms.find( false ); + if( itt!=terms.end() ){ + norm_args = itt->second; + if( terms.find( true )!=terms.end() ){ + comp_num = 0; + }else{ + comp_num = -1; + } + }else{ + norm_args = terms[true]; + comp_num = 1; + } + std::vector< Node > subs; + for( unsigned j=0; j<norm_args.getNumChildren(); j++ ){ + subs.push_back( norm_args[j] ); + } + Trace("cegqi-inv-debug2") << " normalize based on " << norm_args << std::endl; + Assert( d_vars.size()==subs.size() ); + for( unsigned j=0; j<disjuncts.size(); j++ ){ + disjuncts[j] = Rewriter::rewrite( disjuncts[j].substitute( subs.begin(), subs.end(), d_vars.begin(), d_vars.end() ) ); + Trace("cegqi-inv-debug2") << " ..." << disjuncts[j] << std::endl; + } + std::vector< Node > const_var; + std::vector< Node > const_subs; + if( comp_num==0 ){ + //transition + Assert( terms.find( true )!=terms.end() ); + Node next = terms[true]; + next = Rewriter::rewrite( next.substitute( subs.begin(), subs.end(), d_vars.begin(), d_vars.end() ) ); + Trace("cegqi-inv-debug") << "transition next predicate : " << next << std::endl; + // normalize the other direction + std::vector< Node > rvars; + for( unsigned i=0; i<next.getNumChildren(); i++ ){ + rvars.push_back( next[i] ); + } + if( d_prime_vars.size()<next.getNumChildren() ){ + for( unsigned i=0; i<next.getNumChildren(); i++ ){ + Node v = NodeManager::currentNM()->mkSkolem( "ir", next[i].getType(), "template inference rev argument" ); + d_prime_vars.push_back( v ); + } + } + Trace("cegqi-inv-debug2") << " normalize based on " << next << std::endl; + Assert( d_vars.size()==subs.size() ); + for( unsigned j=0; j<disjuncts.size(); j++ ){ + disjuncts[j] = Rewriter::rewrite( disjuncts[j].substitute( rvars.begin(), rvars.end(), d_prime_vars.begin(), d_prime_vars.end() ) ); + Trace("cegqi-inv-debug2") << " ..." << disjuncts[j] << std::endl; + } + getConstantSubstitution( d_prime_vars, disjuncts, const_var, const_subs, false ); + }else{ + getConstantSubstitution( d_vars, disjuncts, const_var, const_subs, false ); + } + Node res; + if( disjuncts.empty() ){ + res = NodeManager::currentNM()->mkConst( false ); + }else if( disjuncts.size()==1 ){ + res = disjuncts[0]; + }else{ + res = NodeManager::currentNM()->mkNode( kind::OR, disjuncts ); + } + if( !res.hasBoundVar() ){ + Trace("cegqi-inv") << "*** inferred " << ( comp_num==1 ? "pre" : ( comp_num==-1 ? "post" : "trans" ) ) << "-condition : " << res << std::endl; + d_com[comp_num].d_conjuncts.push_back( res ); + if( !const_var.empty() ){ + bool has_const_eq = const_var.size()==d_vars.size(); + Trace("cegqi-inv") << " with constant substitution, complete = " << has_const_eq << " : " << std::endl; + for( unsigned i=0; i<const_var.size(); i++ ){ + Trace("cegqi-inv") << " " << const_var[i] << " -> " << const_subs[i] << std::endl; + if( has_const_eq ){ + d_com[comp_num].d_const_eq[res][const_var[i]] = const_subs[i]; + } + } + Trace("cegqi-inv") << "...size = " << const_var.size() << ", #vars = " << d_vars.size() << std::endl; + } + }else{ + Trace("cegqi-inv-debug2") << "...failed, free variable." << std::endl; + d_complete = false; + } + } + }else{ + d_complete = false; + } + } + + // finalize the components + for( int i=-1; i<=1; i++ ){ + Node ret; + if( d_com[i].d_conjuncts.empty() ){ + ret = NodeManager::currentNM()->mkConst( true ); + }else if( d_com[i].d_conjuncts.size()==1 ){ + ret = d_com[i].d_conjuncts[0]; + }else{ + ret = NodeManager::currentNM()->mkNode( kind::AND, d_com[i].d_conjuncts ); + } + if( i==0 || i==1 ){ + // pre-condition and transition are negated + ret = TermDb::simpleNegate( ret ); + } + d_com[i].d_this = ret; + } +} + +bool TransitionInference::processDisjunct( Node n, std::map< bool, Node >& terms, std::vector< Node >& disjuncts, + std::map< Node, bool >& visited, bool topLevel ) { + if( visited.find( n )==visited.end() ){ + visited[n] = true; + bool childTopLevel = n.getKind()==OR && topLevel; + //if another part mentions UF or a free variable, then fail + bool lit_pol = n.getKind()!=NOT; + Node lit = n.getKind()==NOT ? n[0] : n; + if( lit.getKind()==APPLY_UF ){ + Node op = lit.getOperator(); + if( d_func.isNull() ){ + d_func = op; + Trace("cegqi-inv-debug") << "Use " << op << " with args "; + for( unsigned i=0; i<lit.getNumChildren(); i++ ){ + Node v = NodeManager::currentNM()->mkSkolem( "i", lit[i].getType(), "template inference argument" ); + d_vars.push_back( v ); + Trace("cegqi-inv-debug") << v << " "; + } + Trace("cegqi-inv-debug") << std::endl; + } + if( op!=d_func ){ + Trace("cegqi-inv-debug") << "...failed, free function : " << n << std::endl; + return false; + }else if( topLevel ){ + if( terms.find( lit_pol )==terms.end() ){ + terms[lit_pol] = lit; + return true; + }else{ + Trace("cegqi-inv-debug") << "...failed, repeated inv-app : " << lit << std::endl; + return false; + } + }else{ + Trace("cegqi-inv-debug") << "...failed, non-entailed inv-app : " << lit << std::endl; + return false; + } + }else if( topLevel && !childTopLevel ){ + disjuncts.push_back( n ); + } + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + if( !processDisjunct( n[i], terms, disjuncts, visited, childTopLevel ) ){ + return false; + } + } + } + return true; +} + +Node TransitionInference::getComponent( int i ) { + return d_com[i].d_this; +} + +int TransitionInference::initializeTrace( DetTrace& dt, Node loc, bool fwd ) { + int index = fwd ? 1 : -1; + Assert( d_com[index].has( loc ) ); + std::map< Node, std::map< Node, Node > >::iterator it = d_com[index].d_const_eq.find( loc ); + if( it!=d_com[index].d_const_eq.end() ){ + std::vector< Node > next; + for( unsigned i=0; i<d_vars.size(); i++ ){ + Node v = d_vars[i]; + Assert( it->second.find( v )!=it->second.end() ); + next.push_back( it->second[v] ); + dt.d_curr.push_back( it->second[v] ); + } + Trace("cegqi-inv-debug2") << "dtrace : initial increment" << std::endl; + bool ret = dt.increment( loc, next ); + AlwaysAssert( ret ); + return 0; + } + return -1; +} + +int TransitionInference::incrementTrace( DetTrace& dt, Node loc, bool fwd ) { + Assert( d_com[0].has( loc ) ); + // check if it satisfies the pre/post condition + int check_index = fwd ? -1 : 1; + Node cc = getComponent( check_index ); + Assert( !cc.isNull() ); + Node ccr = Rewriter::rewrite( cc.substitute( d_vars.begin(), d_vars.end(), dt.d_curr.begin(), dt.d_curr.end() ) ); + if( ccr.isConst() ){ + if( ccr.getConst<bool>()==( fwd ? false : true ) ){ + Trace("cegqi-inv-debug2") << "dtrace : counterexample" << std::endl; + return 2; + } + } + + + // terminates? + Node c = getComponent( 0 ); + Assert( !c.isNull() ); + + Assert( d_vars.size()==dt.d_curr.size() ); + Node cr = Rewriter::rewrite( c.substitute( d_vars.begin(), d_vars.end(), dt.d_curr.begin(), dt.d_curr.end() ) ); + if( cr.isConst() ){ + if( !cr.getConst<bool>() ){ + Trace("cegqi-inv-debug2") << "dtrace : terminated" << std::endl; + return 1; + }else{ + return -1; + } + } + if( fwd ){ + std::map< Node, std::map< Node, Node > >::iterator it = d_com[0].d_const_eq.find( loc ); + if( it!=d_com[0].d_const_eq.end() ){ + std::vector< Node > next; + for( unsigned i=0; i<d_prime_vars.size(); i++ ){ + Node pv = d_prime_vars[i]; + Assert( it->second.find( pv )!=it->second.end() ); + Node pvs = it->second[pv]; + Assert( d_vars.size()==dt.d_curr.size() ); + Node pvsr = Rewriter::rewrite( pvs.substitute( d_vars.begin(), d_vars.end(), dt.d_curr.begin(), dt.d_curr.end() ) ); + next.push_back( pvsr ); + } + if( dt.increment( loc, next ) ){ + Trace("cegqi-inv-debug2") << "dtrace : success increment" << std::endl; + return 0; + }else{ + // looped + Trace("cegqi-inv-debug2") << "dtrace : looped" << std::endl; + return 1; + } + } + }else{ + //TODO + } + return -1; +} + +int TransitionInference::initializeTrace( DetTrace& dt, bool fwd ) { + Trace("cegqi-inv-debug2") << "Initialize trace" << std::endl; + int index = fwd ? 1 : -1; + if( d_com[index].d_conjuncts.size()==1 ){ + return initializeTrace( dt, d_com[index].d_conjuncts[0], fwd ); + }else{ + return -1; + } +} + +int TransitionInference::incrementTrace( DetTrace& dt, bool fwd ) { + if( d_com[0].d_conjuncts.size()==1 ){ + return incrementTrace( dt, d_com[0].d_conjuncts[0], fwd ); + }else{ + return -1; + } +} + +Node TransitionInference::constructFormulaTrace( DetTrace& dt ) { + return dt.constructFormula( d_vars ); +} + +} //namespace CVC4 + diff --git a/src/theory/quantifiers/ce_guided_single_inv.h b/src/theory/quantifiers/ce_guided_single_inv.h index 449ab7189..e22d5fb53 100644 --- a/src/theory/quantifiers/ce_guided_single_inv.h +++ b/src/theory/quantifiers/ce_guided_single_inv.h @@ -2,9 +2,9 @@ /*! \file ce_guided_single_inv.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King, Clark Barrett + ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -44,6 +44,58 @@ public: class SingleInvocationPartition; +class DetTrace { +private: + class DetTraceTrie { + public: + std::map< Node, DetTraceTrie > d_children; + bool add( Node loc, std::vector< Node >& val, unsigned index = 0 ); + void clear() { d_children.clear(); } + Node constructFormula( std::vector< Node >& vars, unsigned index = 0 ); + }; + DetTraceTrie d_trie; +public: + std::vector< Node > d_curr; + bool increment( Node loc, std::vector< Node >& vals ); + Node constructFormula( std::vector< Node >& vars ); + void print( const char* c ); +}; + +class TransitionInference { +private: + bool processDisjunct( Node n, std::map< bool, Node >& terms, std::vector< Node >& disjuncts, std::map< Node, bool >& visited, bool topLevel ); + void getConstantSubstitution( std::vector< Node >& vars, std::vector< Node >& disjuncts, std::vector< Node >& const_var, std::vector< Node >& const_subs, bool reqPol ); + bool d_complete; +public: + TransitionInference() : d_complete( false ) {} + std::vector< Node > d_vars; + std::vector< Node > d_prime_vars; + Node d_func; + + class Component { + public: + Component(){} + Node d_this; + std::vector< Node > d_conjuncts; + std::map< Node, std::map< Node, Node > > d_const_eq; + bool has( Node c ) { return std::find( d_conjuncts.begin(), d_conjuncts.end(), c )!=d_conjuncts.end(); } + }; + std::map< int, Component > d_com; + + void initialize( Node f, std::vector< Node >& vars ); + void process( Node n ); + Node getComponent( int i ); + bool isComplete() { return d_complete; } + + // 0 : success, 1 : terminated, 2 : counterexample, -1 : invalid + int initializeTrace( DetTrace& dt, Node loc, bool fwd = true ); + int incrementTrace( DetTrace& dt, Node loc, bool fwd = true ); + int initializeTrace( DetTrace& dt, bool fwd = true ); + int incrementTrace( DetTrace& dt, bool fwd = true ); + Node constructFormulaTrace( DetTrace& dt ); +}; + + class CegConjectureSingleInv { private: friend class CegqiOutputSingleInv; @@ -72,6 +124,7 @@ class CegConjectureSingleInv { QuantifiersEngine* d_qe; CegConjecture* d_parent; SingleInvocationPartition* d_sip; + std::map< Node, TransitionInference > d_ti; CegConjectureSingleInvSol* d_sol; CegEntailmentInfer* d_ei; // the instantiator @@ -130,6 +183,8 @@ class CegConjectureSingleInv { std::map< Node, Node > d_trans_pre; std::map< Node, Node > d_trans_post; std::map< Node, std::vector< Node > > d_prog_templ_vars; + std::map< Node, Node > d_templ; + std::map< Node, Node > d_templ_arg; //the non-single invocation portion of the quantified formula std::map< Node, Node > d_nsi_op_map; std::map< Node, Node > d_nsi_op_map_to_prog; @@ -170,6 +225,22 @@ class CegConjectureSingleInv { std::map<Node, Node>::const_iterator location = d_trans_post.find(prog); return location->second; } + Node getTemplate(Node prog) const { + std::map<Node, Node>::const_iterator tmpl = d_templ.find(prog); + if( tmpl!=d_templ.end() ){ + return tmpl->second; + }else{ + return Node::null(); + } + } + Node getTemplateArg(Node prog) const { + std::map<Node, Node>::const_iterator tmpla = d_templ_arg.find(prog); + if( tmpla != d_templ_arg.end() ){ + return tmpla->second; + }else{ + return Node::null(); + } + } }; @@ -178,21 +249,22 @@ class CegConjectureSingleInv { // "d_arg_types", and all invocations are in the same order across all // functions class SingleInvocationPartition { - private: +private: + bool d_has_input_funcs; + std::vector< Node > d_input_funcs; //options - Kind d_checkKind; bool inferArgTypes( Node n, std::vector< TypeNode >& typs, std::map< Node, bool >& visited ); void process( Node n ); bool collectConjuncts( Node n, bool pol, std::vector< Node >& conj ); bool processConjunct( Node n, std::map< Node, bool >& visited, std::vector< Node >& args, std::vector< Node >& terms, std::vector< Node >& subs ); Node getSpecificationInst( Node n, std::map< Node, Node >& lam, std::map< Node, Node >& visited ); - void extractInvariant2( Node n, Node& func, int& pol, std::vector< Node >& disjuncts, bool hasPol, std::map< Node, bool >& visited ); + bool init( std::vector< Node >& funcs, std::vector< TypeNode >& typs, Node n, bool has_funcs ); public: - SingleInvocationPartition( Kind checkKind = kind::APPLY_UF ) : d_checkKind( checkKind ){} + SingleInvocationPartition() : d_has_input_funcs( false ){} ~SingleInvocationPartition(){} bool init( Node n ); - bool init( std::vector< TypeNode >& typs, Node n ); + bool init( std::vector< Node >& funcs, Node n ); //outputs (everything is with bound var) std::vector< TypeNode > d_arg_types; @@ -216,14 +288,13 @@ public: Node getSpecificationInst( int index, std::map< Node, Node >& lam ); - void extractInvariant( Node n, Node& func, int& pol, std::vector< Node >& disjuncts ); - bool isPurelySingleInvocation() { return d_conjuncts[1].empty(); } bool isNonGroundSingleInvocation() { return d_conjuncts[3].size()==d_conjuncts[1].size(); } void debugPrint( const char * c ); }; + }/* namespace CVC4::theory::quantifiers */ }/* namespace CVC4::theory */ }/* namespace CVC4 */ diff --git a/src/theory/quantifiers/ce_guided_single_inv_ei.cpp b/src/theory/quantifiers/ce_guided_single_inv_ei.cpp index 6394fca3d..1d0dc7bd4 100644 --- a/src/theory/quantifiers/ce_guided_single_inv_ei.cpp +++ b/src/theory/quantifiers/ce_guided_single_inv_ei.cpp @@ -2,9 +2,9 @@ /*! \file ce_guided_single_inv_ei.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/ce_guided_single_inv_ei.h b/src/theory/quantifiers/ce_guided_single_inv_ei.h index 42e0b0820..9964d32f2 100644 --- a/src/theory/quantifiers/ce_guided_single_inv_ei.h +++ b/src/theory/quantifiers/ce_guided_single_inv_ei.h @@ -2,9 +2,9 @@ /*! \file ce_guided_single_inv_ei.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/ce_guided_single_inv_sol.cpp b/src/theory/quantifiers/ce_guided_single_inv_sol.cpp index 8ecd32ab1..1eafe1a93 100644 --- a/src/theory/quantifiers/ce_guided_single_inv_sol.cpp +++ b/src/theory/quantifiers/ce_guided_single_inv_sol.cpp @@ -2,9 +2,9 @@ /*! \file ce_guided_single_inv_sol.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,7 @@ #include "theory/quantifiers/ce_guided_single_inv.h" #include "theory/quantifiers/first_order_model.h" #include "theory/quantifiers/quant_util.h" -#include "theory/quantifiers/term_database.h" +#include "theory/quantifiers/term_database_sygus.h" #include "theory/quantifiers/trigger.h" #include "theory/theory_engine.h" @@ -383,7 +383,7 @@ Node CegConjectureSingleInvSol::simplifySolutionNode( Node sol, TypeNode stn, st d_qe->getTermDatabaseSygus()->registerSygusType( stn ); std::map< int, TypeNode > stnc; if( !stn.isNull() ){ - int karg = d_qe->getTermDatabaseSygus()->getKindArg( stn, sol.getKind() ); + int karg = d_qe->getTermDatabaseSygus()->getKindConsNum( stn, sol.getKind() ); if( karg!=-1 ){ const Datatype& dt = ((DatatypeType)(stn).toType()).getDatatype(); if( dt[karg].getNumArgs()==sol.getNumChildren() ){ @@ -714,8 +714,10 @@ Node CegConjectureSingleInvSol::reconstructSolution( Node sol, TypeNode stn, int } }while( !active.empty() ); - //if solution is null, we ran out of elements, return the original solution - return sol; + // we ran out of elements, return null + reconstructed = -1; + Warning() << CommandFailure("Cannot get synth function: reconstruction to syntax failed."); + return Node::null(); // return sol; } } @@ -741,14 +743,14 @@ int CegConjectureSingleInvSol::collectReconstructNodes( Node t, TypeNode stn, in Node min_t = d_qe->getTermDatabaseSygus()->minimizeBuiltinTerm( t ); Trace("csi-rcons-debug") << "Minimized term is : " << min_t << std::endl; //check if op is in syntax sort - carg = d_qe->getTermDatabaseSygus()->getOpArg( stn, min_t ); + carg = d_qe->getTermDatabaseSygus()->getOpConsNum( stn, min_t ); if( carg!=-1 ){ Trace("csi-rcons-debug") << " Type has operator." << std::endl; d_reconstruct[id] = NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, Node::fromExpr( dt[carg].getConstructor() ) ); status = 0; }else{ //check if kind is in syntax sort - karg = d_qe->getTermDatabaseSygus()->getKindArg( stn, min_t.getKind() ); + karg = d_qe->getTermDatabaseSygus()->getKindConsNum( stn, min_t.getKind() ); if( karg!=-1 ){ //collect the children of min_t std::vector< Node > tchildren; @@ -880,7 +882,7 @@ int CegConjectureSingleInvSol::collectReconstructNodes( Node t, TypeNode stn, in } //get decompositions for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ - Kind k = d_qe->getTermDatabaseSygus()->getArgKind( stn, i ); + Kind k = d_qe->getTermDatabaseSygus()->getConsNumKind( stn, i ); getEquivalentTerms( k, min_t, equiv ); } //assign ids to terms diff --git a/src/theory/quantifiers/ce_guided_single_inv_sol.h b/src/theory/quantifiers/ce_guided_single_inv_sol.h index cb6f6bc41..61ade265f 100644 --- a/src/theory/quantifiers/ce_guided_single_inv_sol.h +++ b/src/theory/quantifiers/ce_guided_single_inv_sol.h @@ -2,9 +2,9 @@ /*! \file ce_guided_single_inv_sol.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/ceg_instantiator.cpp b/src/theory/quantifiers/ceg_instantiator.cpp index 1543b2ebd..05e86c9e8 100644 --- a/src/theory/quantifiers/ceg_instantiator.cpp +++ b/src/theory/quantifiers/ceg_instantiator.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -502,6 +502,14 @@ Node CegInstantiator::applySubstitution( TypeNode tn, Node n, std::vector< Node } } } + if( Trace.isOn("cegqi-si-apply-subs-debug") ){ + Trace("cegqi-si-apply-subs-debug") << "req_coeff = " << req_coeff << " " << tn << std::endl; + for( unsigned i=0; i<subs.size(); i++ ){ + Trace("cegqi-si-apply-subs-debug") << " " << vars[i] << " -> " << subs[i] << " types : " << vars[i].getType() << " -> " << subs[i].getType() << std::endl; + Assert( subs[i].getType().isSubtypeOf( vars[i].getType() ) ); + } + } + if( !req_coeff ){ Node nret = n.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() ); if( n!=nret ){ @@ -515,8 +523,12 @@ Node CegInstantiator::applySubstitution( TypeNode tn, Node n, std::vector< Node std::vector< Node > nsubs; for( unsigned i=0; i<vars.size(); i++ ){ if( !coeff[i].isNull() ){ + Assert( vars[i].getType().isInteger() ); Assert( coeff[i].isConst() ); - nsubs.push_back( Rewriter::rewrite( NodeManager::currentNM()->mkNode( MULT, subs[i], NodeManager::currentNM()->mkConst( Rational(1)/coeff[i].getConst<Rational>() ) ) )); + Node nn =NodeManager::currentNM()->mkNode( MULT, subs[i], NodeManager::currentNM()->mkConst( Rational(1)/coeff[i].getConst<Rational>() ) ); + nn = NodeManager::currentNM()->mkNode( kind::TO_INTEGER, nn ); + nn = Rewriter::rewrite( nn ); + nsubs.push_back( nn ); }else{ nsubs.push_back( subs[i] ); } diff --git a/src/theory/quantifiers/ceg_instantiator.h b/src/theory/quantifiers/ceg_instantiator.h index f9a711704..aed1be3a4 100644 --- a/src/theory/quantifiers/ceg_instantiator.h +++ b/src/theory/quantifiers/ceg_instantiator.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/ceg_t_instantiator.cpp b/src/theory/quantifiers/ceg_t_instantiator.cpp index 3282872d6..cd541a2a6 100644 --- a/src/theory/quantifiers/ceg_t_instantiator.cpp +++ b/src/theory/quantifiers/ceg_t_instantiator.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -688,7 +688,7 @@ Node DtInstantiator::solve_dt( Node v, Node a, Node b, Node sa, Node sb ) { TypeNode tn = a.getType(); const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); for( unsigned i=0; i<a.getNumChildren(); i++ ){ - Node nn = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[cindex][i].getSelector() ), sb ); + Node nn = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[cindex].getSelectorInternal( tn.toType(), i ) ), sb ); Node s = solve_dt( v, a[i], Node::null(), sa[i], nn ); if( !s.isNull() ){ return s; @@ -720,7 +720,7 @@ bool DtInstantiator::processEqualTerms( CegInstantiator * ci, SolvedForm& sf, No unsigned cindex = Datatype::indexOf( n.getOperator().toExpr() ); //now must solve for selectors applied to pv for( unsigned j=0; j<dt[cindex].getNumArgs(); j++ ){ - Node c = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[cindex][j].getSelector() ), pv ); + Node c = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[cindex].getSelectorInternal( d_type.toType(), j ) ), pv ); ci->pushStackVariable( c ); children.push_back( c ); } diff --git a/src/theory/quantifiers/ceg_t_instantiator.h b/src/theory/quantifiers/ceg_t_instantiator.h index 2df7946d5..787c2547a 100644 --- a/src/theory/quantifiers/ceg_t_instantiator.h +++ b/src/theory/quantifiers/ceg_t_instantiator.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/conjecture_generator.cpp b/src/theory/quantifiers/conjecture_generator.cpp index a0c607e0e..c25c52243 100644 --- a/src/theory/quantifiers/conjecture_generator.cpp +++ b/src/theory/quantifiers/conjecture_generator.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Clark Barrett, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/conjecture_generator.h b/src/theory/quantifiers/conjecture_generator.h index c89d0f2ee..e4246e2ab 100644 --- a/src/theory/quantifiers/conjecture_generator.h +++ b/src/theory/quantifiers/conjecture_generator.h @@ -2,9 +2,9 @@ /*! \file conjecture_generator.h ** \verbatim ** Top contributors (to current version): - ** Clark Barrett, Tim King, Andrew Reynolds + ** Clark Barrett, Paul Meng, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/equality_infer.cpp b/src/theory/quantifiers/equality_infer.cpp index 5190025ee..66ca38e8c 100644 --- a/src/theory/quantifiers/equality_infer.cpp +++ b/src/theory/quantifiers/equality_infer.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/equality_infer.h b/src/theory/quantifiers/equality_infer.h index 80d6ef98b..5b714c2d3 100644 --- a/src/theory/quantifiers/equality_infer.h +++ b/src/theory/quantifiers/equality_infer.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,7 +17,6 @@ #ifndef __CVC4__THEORY__QUANTIFIERS__EQUALITY_INFER_H #define __CVC4__THEORY__QUANTIFIERS__EQUALITY_INFER_H -#include <ext/hash_set> #include <iostream> #include <map> #include <vector> diff --git a/src/theory/quantifiers/first_order_model.cpp b/src/theory/quantifiers/first_order_model.cpp index 612646b42..0ffa0c115 100644 --- a/src/theory/quantifiers/first_order_model.cpp +++ b/src/theory/quantifiers/first_order_model.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/first_order_model.h b/src/theory/quantifiers/first_order_model.h index e4adfc8bd..8a00c70f6 100644 --- a/src/theory/quantifiers/first_order_model.h +++ b/src/theory/quantifiers/first_order_model.h @@ -2,9 +2,9 @@ /*! \file first_order_model.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tim King + ** Andrew Reynolds, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/full_model_check.cpp b/src/theory/quantifiers/full_model_check.cpp index c41d09187..82a1c6626 100644 --- a/src/theory/quantifiers/full_model_check.cpp +++ b/src/theory/quantifiers/full_model_check.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/full_model_check.h b/src/theory/quantifiers/full_model_check.h index 3e7c9918e..c5d005969 100644 --- a/src/theory/quantifiers/full_model_check.h +++ b/src/theory/quantifiers/full_model_check.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/fun_def_engine.cpp b/src/theory/quantifiers/fun_def_engine.cpp index cf1d14663..354d90b8b 100644 --- a/src/theory/quantifiers/fun_def_engine.cpp +++ b/src/theory/quantifiers/fun_def_engine.cpp @@ -2,9 +2,9 @@ /*! \file fun_def_engine.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/fun_def_engine.h b/src/theory/quantifiers/fun_def_engine.h index 3b95281c0..ea1dbbc59 100644 --- a/src/theory/quantifiers/fun_def_engine.h +++ b/src/theory/quantifiers/fun_def_engine.h @@ -2,9 +2,9 @@ /*! \file fun_def_engine.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/fun_def_process.cpp b/src/theory/quantifiers/fun_def_process.cpp index 20a7ed00f..064d6c8d9 100644 --- a/src/theory/quantifiers/fun_def_process.cpp +++ b/src/theory/quantifiers/fun_def_process.cpp @@ -2,9 +2,9 @@ /*! \file fun_def_process.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/fun_def_process.h b/src/theory/quantifiers/fun_def_process.h index 28a1f3cfa..e7a53324d 100644 --- a/src/theory/quantifiers/fun_def_process.h +++ b/src/theory/quantifiers/fun_def_process.h @@ -2,9 +2,9 @@ /*! \file fun_def_process.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/inst_match.cpp b/src/theory/quantifiers/inst_match.cpp index 9a3fe379c..e24b8f96a 100644 --- a/src/theory/quantifiers/inst_match.cpp +++ b/src/theory/quantifiers/inst_match.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/inst_match.h b/src/theory/quantifiers/inst_match.h index 4c62dd296..8597755c9 100644 --- a/src/theory/quantifiers/inst_match.h +++ b/src/theory/quantifiers/inst_match.h @@ -2,9 +2,9 @@ /*! \file inst_match.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tim King + ** Andrew Reynolds, Morgan Deters, Francois Bobot ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,13 +17,10 @@ #ifndef __CVC4__THEORY__QUANTIFIERS__INST_MATCH_H #define __CVC4__THEORY__QUANTIFIERS__INST_MATCH_H -#include "util/hash.h" -#include "context/cdo.h" - -#include <ext/hash_set> #include <map> #include "context/cdlist.h" +#include "context/cdo.h" #include "expr/node.h" namespace CVC4 { diff --git a/src/theory/quantifiers/inst_match_generator.cpp b/src/theory/quantifiers/inst_match_generator.cpp index 8d7b321c8..79a412b3c 100644 --- a/src/theory/quantifiers/inst_match_generator.cpp +++ b/src/theory/quantifiers/inst_match_generator.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -16,6 +16,7 @@ #include "expr/datatype.h" #include "options/quantifiers_options.h" +#include "options/datatypes_options.h" #include "theory/quantifiers/candidate_generator.h" #include "theory/quantifiers/term_database.h" #include "theory/quantifiers/trigger.h" @@ -116,7 +117,8 @@ void InstMatchGenerator::initialize( Node q, QuantifiersEngine* qe, std::vector< break; } } - }else if( d_match_pattern.getKind()==APPLY_SELECTOR_TOTAL && d_match_pattern[0].getKind()==INST_CONSTANT && options::purifyDtTriggers() ){ + }else if( d_match_pattern.getKind()==APPLY_SELECTOR_TOTAL && d_match_pattern[0].getKind()==INST_CONSTANT && + options::purifyDtTriggers() && !options::dtSharedSelectors() ){ d_match_pattern = d_match_pattern[0]; } d_match_pattern_type = d_match_pattern.getType(); diff --git a/src/theory/quantifiers/inst_match_generator.h b/src/theory/quantifiers/inst_match_generator.h index 910cde131..882d786fb 100644 --- a/src/theory/quantifiers/inst_match_generator.h +++ b/src/theory/quantifiers/inst_match_generator.h @@ -2,9 +2,9 @@ /*! \file inst_match_generator.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Clark Barrett + ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/inst_propagator.cpp b/src/theory/quantifiers/inst_propagator.cpp index 6457de145..49de464b1 100644 --- a/src/theory/quantifiers/inst_propagator.cpp +++ b/src/theory/quantifiers/inst_propagator.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/inst_propagator.h b/src/theory/quantifiers/inst_propagator.h index 6201cf152..6c058c258 100644 --- a/src/theory/quantifiers/inst_propagator.h +++ b/src/theory/quantifiers/inst_propagator.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/inst_strategy_cbqi.cpp b/src/theory/quantifiers/inst_strategy_cbqi.cpp index 58bebef35..8e53c97dc 100644 --- a/src/theory/quantifiers/inst_strategy_cbqi.cpp +++ b/src/theory/quantifiers/inst_strategy_cbqi.cpp @@ -2,9 +2,9 @@ /*! \file inst_strategy_cbqi.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tim King + ** Andrew Reynolds, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -561,6 +561,9 @@ bool InstStrategyCbqi::doCbqi( Node q ){ } } } + if( d_quantEngine->getTermDatabase()->isQAttrSygus( q ) ){ + ret = 0; + } if( ret!=0 ){ //if quantifier has a non-handled variable, then do not use cbqi //if quantifier has an APPLY_UF term, then do not use cbqi unless EPR diff --git a/src/theory/quantifiers/inst_strategy_cbqi.h b/src/theory/quantifiers/inst_strategy_cbqi.h index 6c2dc9275..a1e6a2bdc 100644 --- a/src/theory/quantifiers/inst_strategy_cbqi.h +++ b/src/theory/quantifiers/inst_strategy_cbqi.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/inst_strategy_e_matching.cpp b/src/theory/quantifiers/inst_strategy_e_matching.cpp index 2cef4f6a1..582b6ba7c 100644 --- a/src/theory/quantifiers/inst_strategy_e_matching.cpp +++ b/src/theory/quantifiers/inst_strategy_e_matching.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -659,6 +659,10 @@ void FullSaturation::check( Theory::Effort e, unsigned quant_e ) { } bool FullSaturation::process( Node f, bool fullEffort ){ + // ignore if constant true (rare case of non-standard quantifier whose body is rewritten to true) + if( f[1].isConst() && f[1].getConst<bool>() ){ + return false; + } //first, try from relevant domain RelevantDomain * rd = d_quantEngine->getRelevantDomain(); unsigned rstart = options::fullSaturateQuantRd() ? 0 : 1; @@ -770,7 +774,7 @@ bool FullSaturation::process( Node f, bool fullEffort ){ } } } - //term enumerator? + //TODO : term enumerator? return false; } diff --git a/src/theory/quantifiers/inst_strategy_e_matching.h b/src/theory/quantifiers/inst_strategy_e_matching.h index e6d993294..5a4f8e499 100644 --- a/src/theory/quantifiers/inst_strategy_e_matching.h +++ b/src/theory/quantifiers/inst_strategy_e_matching.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/instantiation_engine.cpp b/src/theory/quantifiers/instantiation_engine.cpp index afeed1e5d..c90a3c386 100644 --- a/src/theory/quantifiers/instantiation_engine.cpp +++ b/src/theory/quantifiers/instantiation_engine.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/instantiation_engine.h b/src/theory/quantifiers/instantiation_engine.h index 79963cb45..308024f4d 100644 --- a/src/theory/quantifiers/instantiation_engine.h +++ b/src/theory/quantifiers/instantiation_engine.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/local_theory_ext.cpp b/src/theory/quantifiers/local_theory_ext.cpp index 09ed99735..cf5fe3b50 100644 --- a/src/theory/quantifiers/local_theory_ext.cpp +++ b/src/theory/quantifiers/local_theory_ext.cpp @@ -2,9 +2,9 @@ /*! \file local_theory_ext.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/local_theory_ext.h b/src/theory/quantifiers/local_theory_ext.h index 04a6bc9c8..68b6a562a 100644 --- a/src/theory/quantifiers/local_theory_ext.h +++ b/src/theory/quantifiers/local_theory_ext.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/macros.cpp b/src/theory/quantifiers/macros.cpp index 636bfdb59..6b071f8f7 100644 --- a/src/theory/quantifiers/macros.cpp +++ b/src/theory/quantifiers/macros.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -44,7 +44,7 @@ bool QuantifierMacros::simplify( std::vector< Node >& assertions, bool doRewrite Trace("macros") << "Find macros, ground=" << d_ground_macros << "..." << std::endl; //first, collect macro definitions std::vector< Node > macro_assertions; - for( unsigned i=0; i<assertions.size(); i++ ){ + for( int i=0; i<(int)assertions.size(); i++ ){ Trace("macros-debug") << " process assertion " << assertions[i] << std::endl; if( processAssertion( assertions[i] ) ){ PROOF( @@ -167,6 +167,7 @@ bool QuantifierMacros::isBoundVarApplyUf( Node n ) { Assert( n.getKind()==APPLY_UF ); TypeNode tno = n.getOperator().getType(); std::map< Node, bool > vars; + // allow if a vector of unique variables of the same type as UF arguments for( unsigned i=0; i<n.getNumChildren(); i++ ){ if( n[i].getKind()!=BOUND_VARIABLE ){ return false; @@ -174,11 +175,6 @@ bool QuantifierMacros::isBoundVarApplyUf( Node n ) { if( n[i].getType()!=tno[i] ){ return false; } - if( !tno[i].isSort() && !tno[i].isReal() && ( !tno[i].isDatatype() || tno[i].isParametricDatatype() ) && - !tno[i].isBitVector() && !tno[i].isString() && !tno[i].isFloatingPoint() ){ - //only non-parametric types are supported - return false; - } if( vars.find( n[i] )==vars.end() ){ vars[n[i]] = true; }else{ @@ -331,6 +327,7 @@ bool QuantifierMacros::process( Node n, bool pol, std::vector< Node >& args, Nod }else{ //literal case if( isMacroLiteral( n, pol ) ){ + Trace("macros-debug") << "Check macro literal : " << n << std::endl; std::map< Node, bool > visited; std::vector< Node > candidates; for( size_t i=0; i<n.getNumChildren(); i++ ){ @@ -339,6 +336,7 @@ bool QuantifierMacros::process( Node n, bool pol, std::vector< Node >& args, Nod for( size_t i=0; i<candidates.size(); i++ ){ Node m = candidates[i]; Node op = m.getOperator(); + Trace("macros-debug") << "Check macro candidate : " << m << std::endl; if( d_macro_defs.find( op )==d_macro_defs.end() ){ std::vector< Node > fvs; visited.clear(); @@ -416,6 +414,7 @@ Node QuantifierMacros::simplify( Node n ){ if( it!=d_macro_defs.end() && !it->second.isNull() ){ //only apply if children are subtypes of arguments bool success = true; + // FIXME : this can be eliminated when we have proper typing rules std::vector< Node > cond; TypeNode tno = op.getType(); for( unsigned i=0; i<children.size(); i++ ){ @@ -423,13 +422,13 @@ Node QuantifierMacros::simplify( Node n ){ if( etc.isNull() ){ //if this does fail, we are incomplete, since we are eliminating quantified formula corresponding to op, // and not ensuring it applies to n when its types are correct. - //however, this should never fail: we never process types for which we cannot constuct conditions that ensure correct types, e.g. (is-int t). - Assert( false ); + //Assert( false ); success = false; break; }else if( !etc.isConst() ){ cond.push_back( etc ); } + Assert( children[i].getType().isSubtypeOf( tno[i] ) ); } if( success ){ //do substitution if necessary diff --git a/src/theory/quantifiers/macros.h b/src/theory/quantifiers/macros.h index 60af7ad0a..bd6a96cc0 100644 --- a/src/theory/quantifiers/macros.h +++ b/src/theory/quantifiers/macros.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/model_builder.cpp b/src/theory/quantifiers/model_builder.cpp index 055c9e31c..41c68a117 100644 --- a/src/theory/quantifiers/model_builder.cpp +++ b/src/theory/quantifiers/model_builder.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/model_builder.h b/src/theory/quantifiers/model_builder.h index 3f548c9fd..2900320bb 100644 --- a/src/theory/quantifiers/model_builder.h +++ b/src/theory/quantifiers/model_builder.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/model_engine.cpp b/src/theory/quantifiers/model_engine.cpp index 2faf13f1a..c43187163 100644 --- a/src/theory/quantifiers/model_engine.cpp +++ b/src/theory/quantifiers/model_engine.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/model_engine.h b/src/theory/quantifiers/model_engine.h index 728539e91..ad77ae8dc 100644 --- a/src/theory/quantifiers/model_engine.h +++ b/src/theory/quantifiers/model_engine.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/quant_conflict_find.cpp b/src/theory/quantifiers/quant_conflict_find.cpp index f462535dd..20d470de3 100644 --- a/src/theory/quantifiers/quant_conflict_find.cpp +++ b/src/theory/quantifiers/quant_conflict_find.cpp @@ -2,9 +2,9 @@ /*! \file quant_conflict_find.cpp ** \verbatim ** Top contributors (to current version): - ** Clark Barrett, Tim King, Andrew Reynolds + ** Clark Barrett, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/quant_conflict_find.h b/src/theory/quantifiers/quant_conflict_find.h index dc8a9acb2..794787bfc 100644 --- a/src/theory/quantifiers/quant_conflict_find.h +++ b/src/theory/quantifiers/quant_conflict_find.h @@ -2,9 +2,9 @@ /*! \file quant_conflict_find.h ** \verbatim ** Top contributors (to current version): - ** Clark Barrett, Tim King, Andrew Reynolds + ** Clark Barrett, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/quant_equality_engine.cpp b/src/theory/quantifiers/quant_equality_engine.cpp index 46a8b7ce2..b40212872 100644 --- a/src/theory/quantifiers/quant_equality_engine.cpp +++ b/src/theory/quantifiers/quant_equality_engine.cpp @@ -2,9 +2,9 @@ /*! \file quant_equality_engine.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/quant_equality_engine.h b/src/theory/quantifiers/quant_equality_engine.h index 26654de4d..f827b4fd7 100644 --- a/src/theory/quantifiers/quant_equality_engine.h +++ b/src/theory/quantifiers/quant_equality_engine.h @@ -2,9 +2,9 @@ /*! \file quant_equality_engine.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King + ** Andrew Reynolds, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/quant_split.cpp b/src/theory/quantifiers/quant_split.cpp index 63935f170..282ff3bc4 100644 --- a/src/theory/quantifiers/quant_split.cpp +++ b/src/theory/quantifiers/quant_split.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/quant_split.h b/src/theory/quantifiers/quant_split.h index 3e3b08814..daf4114bc 100644 --- a/src/theory/quantifiers/quant_split.h +++ b/src/theory/quantifiers/quant_split.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/quant_util.cpp b/src/theory/quantifiers/quant_util.cpp index 0ddc447be..b34abba13 100644 --- a/src/theory/quantifiers/quant_util.cpp +++ b/src/theory/quantifiers/quant_util.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -531,3 +531,75 @@ Node QuantEPR::mkEPRAxiom( TypeNode tn ) { } } + +void TermRecBuild::addTerm( Node n ) { + d_term.push_back( n ); + std::vector< Node > currc; + d_kind.push_back( n.getKind() ); + if( n.getMetaKind()==kind::metakind::PARAMETERIZED ){ + currc.push_back( n.getOperator() ); + d_has_op.push_back( true ); + }else{ + d_has_op.push_back( false ); + } + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + currc.push_back( n[i] ); + } + d_children.push_back( currc ); +} + +void TermRecBuild::init( Node n ) { + Assert( d_term.empty() ); + addTerm( n ); +} + +void TermRecBuild::push( unsigned p ) { + Assert( !d_term.empty() ); + unsigned curr = d_term.size()-1; + Assert( d_pos.size()==curr ); + Assert( d_pos.size()+1==d_children.size() ); + Assert( p<d_term[curr].getNumChildren() ); + addTerm( d_term[curr][p] ); + d_pos.push_back( p ); +} + +void TermRecBuild::pop() { + Assert( !d_pos.empty() ); + d_pos.pop_back(); + d_kind.pop_back(); + d_has_op.pop_back(); + d_children.pop_back(); + d_term.pop_back(); +} + +void TermRecBuild::replaceChild( unsigned i, Node n ) { + Assert( !d_term.empty() ); + unsigned curr = d_term.size()-1; + unsigned o = d_has_op[curr] ? 1 : 0; + d_children[curr][i+o] = n; +} + +Node TermRecBuild::getChild( unsigned i ) { + unsigned curr = d_term.size()-1; + unsigned o = d_has_op[curr] ? 1 : 0; + return d_children[curr][i+o]; +} + +Node TermRecBuild::build( unsigned d ) { + Assert( d_pos.size()+1==d_term.size() ); + Assert( d<d_term.size() ); + int p = d<d_pos.size() ? d_pos[d] : -2; + std::vector< Node > children; + unsigned o = d_has_op[d] ? 1 : 0; + for( unsigned i=0; i<d_children[d].size(); i++ ){ + Node nc; + if( p+o==i ){ + nc = build( d+1 ); + }else{ + nc = d_children[d][i]; + } + children.push_back( nc ); + } + return NodeManager::currentNM()->mkNode( d_kind[d], children ); +} + diff --git a/src/theory/quantifiers/quant_util.h b/src/theory/quantifiers/quant_util.h index fcc162a7a..f46b73b1c 100644 --- a/src/theory/quantifiers/quant_util.h +++ b/src/theory/quantifiers/quant_util.h @@ -2,9 +2,9 @@ /*! \file quant_util.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,13 +17,12 @@ #ifndef __CVC4__THEORY__QUANT_UTIL_H #define __CVC4__THEORY__QUANT_UTIL_H -#include "theory/theory.h" -#include "theory/uf/equality_engine.h" - -#include <ext/hash_set> #include <iostream> #include <map> +#include "theory/theory.h" +#include "theory/uf/equality_engine.h" + namespace CVC4 { namespace theory { @@ -207,6 +206,24 @@ public: bool hasEPRAxiom( TypeNode tn ) const { return d_epr_axiom.find( tn )!=d_epr_axiom.end(); } }; +class TermRecBuild { +private: + std::vector< Node > d_term; + std::vector< std::vector< Node > > d_children; + std::vector< Kind > d_kind; + std::vector< bool > d_has_op; + std::vector< unsigned > d_pos; + void addTerm( Node n ); +public: + TermRecBuild(){} + void init( Node n ); + void push( unsigned p ); + void pop(); + void replaceChild( unsigned i, Node n ); + Node getChild( unsigned i ); + Node build( unsigned p=0 ); +}; + } } diff --git a/src/theory/quantifiers/quantifiers_attributes.cpp b/src/theory/quantifiers/quantifiers_attributes.cpp index b797f4ce9..a9b1470fd 100644 --- a/src/theory/quantifiers/quantifiers_attributes.cpp +++ b/src/theory/quantifiers/quantifiers_attributes.cpp @@ -2,9 +2,9 @@ /*! \file quantifiers_attributes.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tim King + ** Andrew Reynolds, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -42,6 +42,16 @@ void QuantifiersAttributes::setUserAttribute( const std::string& attr, Node n, s Trace("quant-attr-debug") << "Set sygus " << n << std::endl; SygusAttribute ca; n.setAttribute( ca, true ); + }else if( attr=="sygus-synth-fun" ){ + Assert( node_values.size()==1 ); + Trace("quant-attr-debug") << "Set sygus synth fun " << n << " to " << node_values[0] << std::endl; + SygusSynthFunAttribute ssfa; + n.setAttribute( ssfa, node_values[0] ); + }else if( attr=="sygus-synth-fun-var-list" ){ + Assert( node_values.size()==1 ); + Trace("quant-attr-debug") << "Set sygus synth fun var list to " << n << " to " << node_values[0] << std::endl; + SygusSynthFunVarListAttribute ssfvla; + n.setAttribute( ssfvla, node_values[0] ); }else if( attr=="synthesis" ){ Trace("quant-attr-debug") << "Set synthesis " << n << std::endl; SynthesisAttribute ca; diff --git a/src/theory/quantifiers/quantifiers_attributes.h b/src/theory/quantifiers/quantifiers_attributes.h index 53cef796a..93a4ef408 100644 --- a/src/theory/quantifiers/quantifiers_attributes.h +++ b/src/theory/quantifiers/quantifiers_attributes.h @@ -2,9 +2,9 @@ /*! \file quantifiers_attributes.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Morgan Deters, Paul Meng, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/quantifiers_rewriter.cpp b/src/theory/quantifiers/quantifiers_rewriter.cpp index 4c395f59d..4cb41e19e 100644 --- a/src/theory/quantifiers/quantifiers_rewriter.cpp +++ b/src/theory/quantifiers/quantifiers_rewriter.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -1188,9 +1188,15 @@ Node QuantifiersRewriter::computePrenexAgg( Node n, bool topLevel, std::map< uns children[i] = children[i][1]; } } - // TODO : keep the pattern + // keep the pattern + std::vector< Node > iplc; + if( n.getNumChildren()==3 ){ + for( unsigned i=0; i<n[2].getNumChildren(); i++ ){ + iplc.push_back( n[2][i] ); + } + } Node nb = children.size()==1 ? children[0] : NodeManager::currentNM()->mkNode( OR, children ); - ret = mkForall( args, nb, true ); + ret = mkForall( args, nb, iplc, true ); }else{ std::vector< Node > args; std::vector< Node > nargs; @@ -1347,14 +1353,19 @@ Node QuantifiersRewriter::mkForAll( std::vector< Node >& args, Node body, QAttri return NodeManager::currentNM()->mkNode( kind::FORALL, children ); } } + Node QuantifiersRewriter::mkForall( std::vector< Node >& args, Node body, bool marked ) { + std::vector< Node > iplc; + return mkForall( args, body, iplc, marked ); +} + +Node QuantifiersRewriter::mkForall( std::vector< Node >& args, Node body, std::vector< Node >& iplc, bool marked ) { if( args.empty() ){ return body; }else{ std::vector< Node > children; children.push_back( NodeManager::currentNM()->mkNode(kind::BOUND_VAR_LIST, args ) ); children.push_back( body ); - std::vector< Node > iplc; if( marked ){ Node avar = NodeManager::currentNM()->mkSkolem( "id", NodeManager::currentNM()->booleanType() ); QuantIdNumAttribute ida; diff --git a/src/theory/quantifiers/quantifiers_rewriter.h b/src/theory/quantifiers/quantifiers_rewriter.h index bb1d77dfe..d1f819726 100644 --- a/src/theory/quantifiers/quantifiers_rewriter.h +++ b/src/theory/quantifiers/quantifiers_rewriter.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -94,6 +94,7 @@ public: static Node preprocess( Node n, bool isInst = false ); static Node mkForAll( std::vector< Node >& args, Node body, QAttributes& qa ); static Node mkForall( std::vector< Node >& args, Node body, bool marked = false ); + static Node mkForall( std::vector< Node >& args, Node body, std::vector< Node >& iplc, bool marked = false ); };/* class QuantifiersRewriter */ }/* CVC4::theory::quantifiers namespace */ diff --git a/src/theory/quantifiers/relevant_domain.cpp b/src/theory/quantifiers/relevant_domain.cpp index 63231dec7..9bc47a507 100644 --- a/src/theory/quantifiers/relevant_domain.cpp +++ b/src/theory/quantifiers/relevant_domain.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/relevant_domain.h b/src/theory/quantifiers/relevant_domain.h index be6ebcd9d..6594b7352 100644 --- a/src/theory/quantifiers/relevant_domain.h +++ b/src/theory/quantifiers/relevant_domain.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/rewrite_engine.cpp b/src/theory/quantifiers/rewrite_engine.cpp index 3e6b0ffa9..f60d27cb9 100644 --- a/src/theory/quantifiers/rewrite_engine.cpp +++ b/src/theory/quantifiers/rewrite_engine.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/rewrite_engine.h b/src/theory/quantifiers/rewrite_engine.h index ef3337e53..34994f993 100644 --- a/src/theory/quantifiers/rewrite_engine.h +++ b/src/theory/quantifiers/rewrite_engine.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/symmetry_breaking.cpp b/src/theory/quantifiers/symmetry_breaking.cpp index 2a2b13583..a8218480b 100644 --- a/src/theory/quantifiers/symmetry_breaking.cpp +++ b/src/theory/quantifiers/symmetry_breaking.cpp @@ -2,9 +2,9 @@ /*! \file symmetry_breaking.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Tim King, Morgan Deters + ** Andrew Reynolds, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/symmetry_breaking.h b/src/theory/quantifiers/symmetry_breaking.h index e682955e7..466e6d9a9 100644 --- a/src/theory/quantifiers/symmetry_breaking.h +++ b/src/theory/quantifiers/symmetry_breaking.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/term_database.cpp b/src/theory/quantifiers/term_database.cpp index 30b17d42c..ec5fc633d 100644 --- a/src/theory/quantifiers/term_database.cpp +++ b/src/theory/quantifiers/term_database.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Francois Bobot, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,20 +17,17 @@ #include "expr/datatype.h" #include "options/base_options.h" #include "options/quantifiers_options.h" +#include "options/datatypes_options.h" #include "theory/quantifiers/ce_guided_instantiation.h" #include "theory/quantifiers/first_order_model.h" #include "theory/quantifiers/fun_def_engine.h" #include "theory/quantifiers/rewrite_engine.h" #include "theory/quantifiers/theory_quantifiers.h" #include "theory/quantifiers/trigger.h" +#include "theory/quantifiers/term_database_sygus.h" #include "theory/quantifiers_engine.h" #include "theory/theory_engine.h" -//for sygus -#include "smt/smt_engine_scope.h" -#include "theory/bv/theory_bv_utils.h" -#include "util/bitvector.h" - using namespace std; using namespace CVC4::kind; using namespace CVC4::context; @@ -723,7 +720,7 @@ bool TermDb::reset( Theory::Effort effort ){ } } //explicitly add inst closure terms to the equality engine to ensure only EE terms are indexed - for( std::hash_set< Node, NodeHashFunction >::iterator it = d_iclosure_processed.begin(); it !=d_iclosure_processed.end(); ++it ){ + for( std::unordered_set< Node, NodeHashFunction >::iterator it = d_iclosure_processed.begin(); it !=d_iclosure_processed.end(); ++it ){ Node n = *it; if( !ee->hasTerm( n ) ){ ee->addTerm( n ); @@ -1102,7 +1099,10 @@ void getSelfSel( const Datatype& dt, const DatatypeConstructor& dc, Node n, Type } */ for( unsigned k=0; k<ssc.size(); k++ ){ - selfSel.push_back( NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, dc[j].getSelector(), n ) ); + Node ss = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, dc.getSelectorInternal( n.getType().toType(), j ), n ); + if( std::find( selfSel.begin(), selfSel.end(), ss )==selfSel.end() ){ + selfSel.push_back( ss ); + } } } } @@ -1843,13 +1843,16 @@ Node TermDb::ensureType( Node n, TypeNode tn ) { void TermDb::getRelevancyCondition( Node n, std::vector< Node >& cond ) { if( n.getKind()==APPLY_SELECTOR_TOTAL ){ - unsigned scindex = Datatype::cindexOf(n.getOperator().toExpr()); - const Datatype& dt = ((DatatypeType)(n[0].getType()).toType()).getDatatype(); - Node rc = NodeManager::currentNM()->mkNode( APPLY_TESTER, Node::fromExpr( dt[scindex].getTester() ), n[0] ).negate(); - if( std::find( cond.begin(), cond.end(), rc )==cond.end() ){ - cond.push_back( rc ); + // don't worry about relevancy conditions if using shared selectors + if( !options::dtSharedSelectors() ){ + unsigned scindex = Datatype::cindexOf(n.getOperator().toExpr()); + const Datatype& dt = ((DatatypeType)(n[0].getType()).toType()).getDatatype(); + Node rc = NodeManager::currentNM()->mkNode( APPLY_TESTER, Node::fromExpr( dt[scindex].getTester() ), n[0] ).negate(); + if( std::find( cond.begin(), cond.end(), rc )==cond.end() ){ + cond.push_back( rc ); + } + getRelevancyCondition( n[0], cond ); } - getRelevancyCondition( n[0], cond ); } } @@ -1956,6 +1959,10 @@ bool TermDb::isComm( Kind k ) { k==BITVECTOR_PLUS || k==BITVECTOR_MULT || k==BITVECTOR_AND || k==BITVECTOR_OR || k==BITVECTOR_XOR || k==BITVECTOR_XNOR; } +bool TermDb::isNonAdditive( Kind k ) { + return k==AND || k==OR || k==BITVECTOR_AND || k==BITVECTOR_OR; +} + bool TermDb::isBoolConnective( Kind k ) { return k==OR || k==AND || k==EQUAL || k==ITE || k==FORALL || k==NOT || k==SEP_STAR; } @@ -2278,1108 +2285,6 @@ Node TermDb::getQAttrQuantIdNumNode( Node q ) { } } -TermDbSygus::TermDbSygus( context::Context* c, QuantifiersEngine* qe ) : d_quantEngine( qe ){ - d_true = NodeManager::currentNM()->mkConst( true ); - d_false = NodeManager::currentNM()->mkConst( false ); -} - -bool TermDbSygus::reset( Theory::Effort e ) { - return true; -} - -TNode TermDbSygus::getVar( TypeNode tn, int i ) { - while( i>=(int)d_fv[tn].size() ){ - std::stringstream ss; - TypeNode vtn = tn; - if( tn.isDatatype() ){ - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - ss << "fv_" << dt.getName() << "_" << i; - if( !dt.getSygusType().isNull() ){ - vtn = TypeNode::fromType( dt.getSygusType() ); - } - }else{ - ss << "fv_" << tn << "_" << i; - } - Assert( !vtn.isNull() ); - Node v = NodeManager::currentNM()->mkSkolem( ss.str(), vtn, "for sygus normal form testing" ); - d_fv_stype[v] = tn; - d_fv_num[v] = i; - d_fv[tn].push_back( v ); - } - return d_fv[tn][i]; -} - -TNode TermDbSygus::getVarInc( TypeNode tn, std::map< TypeNode, int >& var_count ) { - std::map< TypeNode, int >::iterator it = var_count.find( tn ); - if( it==var_count.end() ){ - var_count[tn] = 1; - return getVar( tn, 0 ); - }else{ - int index = it->second; - var_count[tn]++; - return getVar( tn, index ); - } -} - -TypeNode TermDbSygus::getSygusTypeForVar( Node v ) { - Assert( d_fv_stype.find( v )!=d_fv_stype.end() ); - return d_fv_stype[v]; -} - -bool TermDbSygus::getMatch( Node p, Node n, std::map< int, Node >& s ) { - std::vector< int > new_s; - return getMatch2( p, n, s, new_s ); -} - -bool TermDbSygus::getMatch2( Node p, Node n, std::map< int, Node >& s, std::vector< int >& new_s ) { - std::map< Node, int >::iterator it = d_fv_num.find( p ); - if( it!=d_fv_num.end() ){ - Node prev = s[it->second]; - s[it->second] = n; - if( prev.isNull() ){ - new_s.push_back( it->second ); - } - return prev.isNull() || prev==n; - }else if( n.getNumChildren()==0 ){ - return p==n; - }else if( n.getKind()==p.getKind() && n.getNumChildren()==p.getNumChildren() ){ - //try both ways? - unsigned rmax = TermDb::isComm( n.getKind() ) && n.getNumChildren()==2 ? 2 : 1; - std::vector< int > new_tmp; - for( unsigned r=0; r<rmax; r++ ){ - bool success = true; - for( unsigned i=0; i<n.getNumChildren(); i++ ){ - int io = r==0 ? i : ( i==0 ? 1 : 0 ); - if( !getMatch2( p[i], n[io], s, new_tmp ) ){ - success = false; - for( unsigned j=0; j<new_tmp.size(); j++ ){ - s.erase( new_tmp[j] ); - } - new_tmp.clear(); - break; - } - } - if( success ){ - new_s.insert( new_s.end(), new_tmp.begin(), new_tmp.end() ); - return true; - } - } - } - return false; -} - -bool TermDbSygus::getMatch( Node t, TypeNode st, int& index_found, std::vector< Node >& args, int index_exc, int index_start ) { - Assert( st.isDatatype() ); - const Datatype& dt = ((DatatypeType)(st).toType()).getDatatype(); - Assert( dt.isSygus() ); - std::map< Kind, std::vector< Node > > kgens; - std::vector< Node > gens; - for( unsigned i=index_start; i<dt.getNumConstructors(); i++ ){ - if( (int)i!=index_exc ){ - Node g = getGenericBase( st, dt, i ); - gens.push_back( g ); - kgens[g.getKind()].push_back( g ); - Trace("sygus-db-debug") << "Check generic base : " << g << " from " << dt[i].getName() << std::endl; - if( g.getKind()==t.getKind() ){ - Trace("sygus-db-debug") << "Possible match ? " << g << " " << t << " for " << dt[i].getName() << std::endl; - std::map< int, Node > sigma; - if( getMatch( g, t, sigma ) ){ - //we found an exact match - bool msuccess = true; - for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){ - if( sigma[j].isNull() ){ - msuccess = false; - break; - }else{ - args.push_back( sigma[j] ); - } - } - if( msuccess ){ - index_found = i; - return true; - } - //we found an exact match - //std::map< TypeNode, int > var_count; - //Node new_t = mkGeneric( dt, i, var_count, args ); - //Trace("sygus-db-debug") << "Rewrote to : " << new_t << std::endl; - //return new_t; - } - } - } - } - /* - //otherwise, try to modulate based on kinds - for( std::map< Kind, std::vector< Node > >::iterator it = kgens.begin(); it != kgens.end(); ++it ){ - if( it->second.size()>1 ){ - for( unsigned i=0; i<it->second.size(); i++ ){ - for( unsigned j=0; j<it->second.size(); j++ ){ - if( i!=j ){ - std::map< int, Node > sigma; - if( getMatch( it->second[i], it->second[j], sigma ) ){ - if( sigma.size()==1 ){ - //Node mod_pat = sigma.begin().second; - //Trace("cegqi-si-rcons-debug") << "Modulated pattern " << mod_pat << " from " << it->second[i] << " and " << it->second[j] << std::endl; - } - } - } - } - } - } - } - */ - return false; -} - -Node TermDbSygus::getGenericBase( TypeNode tn, const Datatype& dt, int c ) { - std::map< int, Node >::iterator it = d_generic_base[tn].find( c ); - if( it==d_generic_base[tn].end() ){ - registerSygusType( tn ); - std::map< TypeNode, int > var_count; - std::map< int, Node > pre; - Node g = mkGeneric( dt, c, var_count, pre ); - Trace("sygus-db-debug") << "Sygus DB : Generic is " << g << std::endl; - Node gr = Rewriter::rewrite( g ); - Trace("sygus-db-debug") << "Sygus DB : Generic rewritten is " << gr << std::endl; - gr = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( gr.toExpr() ) ); - Trace("sygus-db") << "Sygus DB : Generic base " << dt[c].getName() << " : " << gr << std::endl; - d_generic_base[tn][c] = gr; - return gr; - }else{ - return it->second; - } -} - -Node TermDbSygus::mkGeneric( const Datatype& dt, int c, std::map< TypeNode, int >& var_count, std::map< int, Node >& pre ) { - Assert( c>=0 && c<(int)dt.getNumConstructors() ); - Assert( dt.isSygus() ); - Assert( !dt[c].getSygusOp().isNull() ); - std::vector< Node > children; - Node op = Node::fromExpr( dt[c].getSygusOp() ); - if( op.getKind()!=BUILTIN ){ - children.push_back( op ); - } - Trace("sygus-db") << "mkGeneric " << dt.getName() << " " << op << " " << op.getKind() << "..." << std::endl; - for( int i=0; i<(int)dt[c].getNumArgs(); i++ ){ - TypeNode tna = getArgType( dt[c], i ); - Node a; - std::map< int, Node >::iterator it = pre.find( i ); - if( it!=pre.end() ){ - a = it->second; - }else{ - a = getVarInc( tna, var_count ); - } - Assert( !a.isNull() ); - children.push_back( a ); - } - Node ret; - if( op.getKind()==BUILTIN ){ - ret = NodeManager::currentNM()->mkNode( op, children ); - }else{ - Kind ok = getOperatorKind( op ); - Trace("sygus-db") << "Operator kind is " << ok << std::endl; - if( children.size()==1 && ok==kind::UNDEFINED_KIND ){ - ret = children[0]; - }else{ - ret = NodeManager::currentNM()->mkNode( ok, children ); - /* - Node n = NodeManager::currentNM()->mkNode( APPLY, children ); - //must expand definitions - Node ne = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( n.toExpr() ) ); - Trace("sygus-db-debug") << "Expanded definitions in " << n << " to " << ne << std::endl; - return ne; - */ - } - } - Trace("sygus-db") << "...returning " << ret << std::endl; - return ret; -} - -Node TermDbSygus::sygusToBuiltin( Node n, TypeNode tn ) { - std::map< Node, Node >::iterator it = d_sygus_to_builtin[tn].find( n ); - if( it==d_sygus_to_builtin[tn].end() ){ - Trace("sygus-db-debug") << "SygusToBuiltin : compute for " << n << ", type = " << tn << std::endl; - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - Assert( n.getKind()==APPLY_CONSTRUCTOR ); - unsigned i = Datatype::indexOf( n.getOperator().toExpr() ); - Assert( n.getNumChildren()==dt[i].getNumArgs() ); - std::map< TypeNode, int > var_count; - std::map< int, Node > pre; - for( unsigned j=0; j<n.getNumChildren(); j++ ){ - pre[j] = sygusToBuiltin( n[j], getArgType( dt[i], j ) ); - } - Node ret = mkGeneric( dt, i, var_count, pre ); - Trace("sygus-db-debug") << "SygusToBuiltin : Generic is " << ret << std::endl; - ret = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( ret.toExpr() ) ); - Trace("sygus-db-debug") << "SygusToBuiltin : After expand definitions " << ret << std::endl; - d_sygus_to_builtin[tn][n] = ret; - return ret; - }else{ - return it->second; - } -} - -//rcons_depth limits the number of recursive calls when doing accelerated constant reconstruction (currently limited to 1000) -//this is hacky : depending upon order of calls, constant rcons may succeed, e.g. 1001, 999 vs. 999, 1001 -Node TermDbSygus::builtinToSygusConst( Node c, TypeNode tn, int rcons_depth ) { - std::map< Node, Node >::iterator it = d_builtin_const_to_sygus[tn].find( c ); - if( it==d_builtin_const_to_sygus[tn].end() ){ - Node sc; - d_builtin_const_to_sygus[tn][c] = sc; - Assert( c.isConst() ); - Assert( tn.isDatatype() ); - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - Trace("csi-rcons-debug") << "Try to reconstruct " << c << " in " << dt.getName() << std::endl; - Assert( dt.isSygus() ); - // if we are not interested in reconstructing constants, or the grammar allows them, return a proxy - if( !options::cegqiSingleInvReconstructConst() || dt.getSygusAllowConst() ){ - Node k = NodeManager::currentNM()->mkSkolem( "sy", tn, "sygus proxy" ); - SygusProxyAttribute spa; - k.setAttribute(spa,c); - sc = k; - }else{ - int carg = getOpArg( tn, c ); - if( carg!=-1 ){ - //sc = Node::fromExpr( dt[carg].getSygusOp() ); - sc = NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, Node::fromExpr( dt[carg].getConstructor() ) ); - }else{ - //identity functions - for( unsigned i=0; i<getNumIdFuncs( tn ); i++ ){ - unsigned ii = getIdFuncIndex( tn, i ); - Assert( dt[ii].getNumArgs()==1 ); - //try to directly reconstruct from single argument - TypeNode tnc = getArgType( dt[ii], 0 ); - Trace("csi-rcons-debug") << "Based on id function " << dt[ii].getSygusOp() << ", try reconstructing " << c << " instead in " << tnc << std::endl; - Node n = builtinToSygusConst( c, tnc, rcons_depth ); - if( !n.isNull() ){ - sc = NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, Node::fromExpr( dt[ii].getConstructor() ), n ); - break; - } - } - if( sc.isNull() ){ - if( rcons_depth<1000 ){ - //accelerated, recursive reconstruction of constants - Kind pk = getPlusKind( TypeNode::fromType( dt.getSygusType() ) ); - if( pk!=UNDEFINED_KIND ){ - int arg = getKindArg( tn, pk ); - if( arg!=-1 ){ - Kind ck = getComparisonKind( TypeNode::fromType( dt.getSygusType() ) ); - Kind pkm = getPlusKind( TypeNode::fromType( dt.getSygusType() ), true ); - //get types - Assert( dt[arg].getNumArgs()==2 ); - TypeNode tn1 = getArgType( dt[arg], 0 ); - TypeNode tn2 = getArgType( dt[arg], 1 ); - //iterate over all positive constants, largest to smallest - int start = d_const_list[tn1].size()-1; - int end = d_const_list[tn1].size()-d_const_list_pos[tn1]; - for( int i=start; i>=end; --i ){ - Node c1 = d_const_list[tn1][i]; - //only consider if smaller than c, and - if( doCompare( c1, c, ck ) ){ - Node c2 = NodeManager::currentNM()->mkNode( pkm, c, c1 ); - c2 = Rewriter::rewrite( c2 ); - if( c2.isConst() ){ - //reconstruct constant on the other side - Node sc2 = builtinToSygusConst( c2, tn2, rcons_depth+1 ); - if( !sc2.isNull() ){ - Node sc1 = builtinToSygusConst( c1, tn1, rcons_depth ); - Assert( !sc1.isNull() ); - sc = NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, Node::fromExpr( dt[arg].getConstructor() ), sc1, sc2 ); - break; - } - } - } - } - } - } - } - } - } - } - d_builtin_const_to_sygus[tn][c] = sc; - return sc; - }else{ - return it->second; - } -} - -Node TermDbSygus::getSygusNormalized( Node n, std::map< TypeNode, int >& var_count, std::map< Node, Node >& subs ) { - return n; - /* TODO? - if( n.getKind()==SKOLEM ){ - std::map< Node, Node >::iterator its = subs.find( n ); - if( its!=subs.end() ){ - return its->second; - }else{ - std::map< Node, TypeNode >::iterator it = d_fv_stype.find( n ); - if( it!=d_fv_stype.end() ){ - Node v = getVarInc( it->second, var_count ); - subs[n] = v; - return v; - }else{ - return n; - } - } - }else{ - if( n.getNumChildren()>0 ){ - std::vector< Node > children; - if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){ - children.push_back( n.getOperator() ); - } - bool childChanged = false; - for( unsigned i=0; i<n.getNumChildren(); i++ ){ - Node nc = getSygusNormalized( n[i], var_count, subs ); - childChanged = childChanged || nc!=n[i]; - children.push_back( nc ); - } - if( childChanged ){ - return NodeManager::currentNM()->mkNode( n.getKind(), children ); - } - } - return n; - } - */ -} - -Node TermDbSygus::getNormalized( TypeNode t, Node prog, bool do_pre_norm, bool do_post_norm ) { - if( do_pre_norm ){ - std::map< TypeNode, int > var_count; - std::map< Node, Node > subs; - prog = getSygusNormalized( prog, var_count, subs ); - } - std::map< Node, Node >::iterator itn = d_normalized[t].find( prog ); - if( itn==d_normalized[t].end() ){ - Node progr = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( prog.toExpr() ) ); - progr = Rewriter::rewrite( progr ); - if( do_post_norm ){ - std::map< TypeNode, int > var_count; - std::map< Node, Node > subs; - progr = getSygusNormalized( progr, var_count, subs ); - } - Trace("sygus-sym-break2") << "...rewrites to " << progr << std::endl; - d_normalized[t][prog] = progr; - return progr; - }else{ - return itn->second; - } -} - -int TermDbSygus::getSygusTermSize( Node n ){ - if( isVar( n ) ){ - return 0; - }else{ - int sum = 0; - for( unsigned i=0; i<n.getNumChildren(); i++ ){ - sum += getSygusTermSize( n[i] ); - } - return 1+sum; - } -} - -bool TermDbSygus::isAntisymmetric( Kind k, Kind& dk ) { - if( k==GT ){ - dk = LT; - return true; - }else if( k==GEQ ){ - dk = LEQ; - return true; - }else if( k==BITVECTOR_UGT ){ - dk = BITVECTOR_ULT; - return true; - }else if( k==BITVECTOR_UGE ){ - dk = BITVECTOR_ULE; - return true; - }else if( k==BITVECTOR_SGT ){ - dk = BITVECTOR_SLT; - return true; - }else if( k==BITVECTOR_SGE ){ - dk = BITVECTOR_SLE; - return true; - }else{ - return false; - } -} - -bool TermDbSygus::isIdempotentArg( Node n, Kind ik, int arg ) { - TypeNode tn = n.getType(); - if( n==getTypeValue( tn, 0 ) ){ - if( ik==PLUS || ik==OR || ik==XOR || ik==BITVECTOR_PLUS || ik==BITVECTOR_OR || ik==BITVECTOR_XOR ){ - return true; - }else if( ik==MINUS || ik==BITVECTOR_SHL || ik==BITVECTOR_LSHR || ik==BITVECTOR_SUB ){ - return arg==1; - } - }else if( n==getTypeValue( tn, 1 ) ){ - if( ik==MULT || ik==BITVECTOR_MULT ){ - return true; - }else if( ik==DIVISION || ik==BITVECTOR_UDIV || ik==BITVECTOR_SDIV ){ - return arg==1; - } - }else if( n==getTypeMaxValue( tn ) ){ - if( ik==EQUAL || ik==BITVECTOR_AND || ik==BITVECTOR_XNOR ){ - return true; - } - } - return false; -} - - -bool TermDbSygus::isSingularArg( Node n, Kind ik, int arg ) { - TypeNode tn = n.getType(); - if( n==getTypeValue( tn, 0 ) ){ - if( ik==AND || ik==MULT || ik==BITVECTOR_AND || ik==BITVECTOR_MULT ){ - return true; - }else if( ik==DIVISION || ik==BITVECTOR_UDIV || ik==BITVECTOR_SDIV ){ - return arg==0; - } - }else if( n==getTypeMaxValue( tn ) ){ - if( ik==OR || ik==BITVECTOR_OR ){ - return true; - } - } - return false; -} - -bool TermDbSygus::hasOffsetArg( Kind ik, int arg, int& offset, Kind& ok ) { - if( ik==LT ){ - Assert( arg==0 || arg==1 ); - offset = arg==0 ? 1 : -1; - ok = LEQ; - return true; - }else if( ik==BITVECTOR_ULT ){ - Assert( arg==0 || arg==1 ); - offset = arg==0 ? 1 : -1; - ok = BITVECTOR_ULE; - return true; - }else if( ik==BITVECTOR_SLT ){ - Assert( arg==0 || arg==1 ); - offset = arg==0 ? 1 : -1; - ok = BITVECTOR_SLE; - return true; - } - return false; -} - - -Node TermDbSygus::getTypeValue( TypeNode tn, int val ) { - std::map< int, Node >::iterator it = d_type_value[tn].find( val ); - if( it==d_type_value[tn].end() ){ - Node n; - if( tn.isInteger() || tn.isReal() ){ - Rational c(val); - n = NodeManager::currentNM()->mkConst( c ); - }else if( tn.isBitVector() ){ - unsigned int uv = val; - BitVector bval(tn.getConst<BitVectorSize>(), uv); - n = NodeManager::currentNM()->mkConst<BitVector>(bval); - }else if( tn.isBoolean() ){ - if( val==0 ){ - n = d_false; - } - } - d_type_value[tn][val] = n; - return n; - }else{ - return it->second; - } -} - -Node TermDbSygus::getTypeMaxValue( TypeNode tn ) { - std::map< TypeNode, Node >::iterator it = d_type_max_value.find( tn ); - if( it==d_type_max_value.end() ){ - Node n; - if( tn.isBitVector() ){ - n = bv::utils::mkOnes(tn.getConst<BitVectorSize>()); - }else if( tn.isBoolean() ){ - n = d_true; - } - d_type_max_value[tn] = n; - return n; - }else{ - return it->second; - } -} - -Node TermDbSygus::getTypeValueOffset( TypeNode tn, Node val, int offset, int& status ) { - std::map< int, Node >::iterator it = d_type_value_offset[tn][val].find( offset ); - if( it==d_type_value_offset[tn][val].end() ){ - Node val_o; - Node offset_val = getTypeValue( tn, offset ); - status = -1; - if( !offset_val.isNull() ){ - if( tn.isInteger() || tn.isReal() ){ - val_o = Rewriter::rewrite( NodeManager::currentNM()->mkNode( PLUS, val, offset_val ) ); - status = 0; - }else if( tn.isBitVector() ){ - val_o = Rewriter::rewrite( NodeManager::currentNM()->mkNode( BITVECTOR_PLUS, val, offset_val ) ); - } - } - d_type_value_offset[tn][val][offset] = val_o; - d_type_value_offset_status[tn][val][offset] = status; - return val_o; - }else{ - status = d_type_value_offset_status[tn][val][offset]; - return it->second; - } -} - -struct sortConstants { - TermDbSygus * d_tds; - Kind d_comp_kind; - bool operator() (Node i, Node j) { - if( i!=j ){ - return d_tds->doCompare( i, j, d_comp_kind ); - }else{ - return false; - } - } -}; - -void TermDbSygus::registerSygusType( TypeNode tn ){ - if( d_register.find( tn )==d_register.end() ){ - if( !tn.isDatatype() ){ - d_register[tn] = TypeNode::null(); - }else{ - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - Trace("sygus-db") << "Register type " << dt.getName() << "..." << std::endl; - d_register[tn] = TypeNode::fromType( dt.getSygusType() ); - if( d_register[tn].isNull() ){ - Trace("sygus-db") << "...not sygus." << std::endl; - }else{ - //for constant reconstruction - Kind ck = getComparisonKind( TypeNode::fromType( dt.getSygusType() ) ); - Node z = getTypeValue( TypeNode::fromType( dt.getSygusType() ), 0 ); - d_const_list_pos[tn] = 0; - //iterate over constructors - for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ - Expr sop = dt[i].getSygusOp(); - Assert( !sop.isNull() ); - Node n = Node::fromExpr( sop ); - Trace("sygus-db") << " Operator #" << i << " : " << sop; - if( sop.getKind() == kind::BUILTIN ){ - Kind sk = NodeManager::operatorToKind( n ); - Trace("sygus-db") << ", kind = " << sk; - d_kinds[tn][sk] = i; - d_arg_kind[tn][i] = sk; - }else if( sop.isConst() ){ - Trace("sygus-db") << ", constant"; - d_consts[tn][n] = i; - d_arg_const[tn][i] = n; - d_const_list[tn].push_back( n ); - if( ck!=UNDEFINED_KIND && doCompare( z, n, ck ) ){ - d_const_list_pos[tn]++; - } - } - if( dt[i].isSygusIdFunc() ){ - d_id_funcs[tn].push_back( i ); - } - d_ops[tn][n] = i; - d_arg_ops[tn][i] = n; - Trace("sygus-db") << std::endl; - } - //sort the constant list - if( !d_const_list[tn].empty() ){ - if( ck!=UNDEFINED_KIND ){ - sortConstants sc; - sc.d_comp_kind = ck; - sc.d_tds = this; - std::sort( d_const_list[tn].begin(), d_const_list[tn].end(), sc ); - } - Trace("sygus-db") << "Type has " << d_const_list[tn].size() << " constants..." << std::endl << " "; - for( unsigned i=0; i<d_const_list[tn].size(); i++ ){ - Trace("sygus-db") << d_const_list[tn][i] << " "; - } - Trace("sygus-db") << std::endl; - Trace("sygus-db") << "Of these, " << d_const_list_pos[tn] << " are marked as positive." << std::endl; - } - //register connected types - for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ - for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){ - registerSygusType( getArgType( dt[i], j ) ); - } - } - } - } - } -} - -bool TermDbSygus::isRegistered( TypeNode tn ) { - return d_register.find( tn )!=d_register.end(); -} - -TypeNode TermDbSygus::sygusToBuiltinType( TypeNode tn ) { - Assert( isRegistered( tn ) ); - return d_register[tn]; -} - -int TermDbSygus::getKindArg( TypeNode tn, Kind k ) { - Assert( isRegistered( tn ) ); - std::map< TypeNode, std::map< Kind, int > >::iterator itt = d_kinds.find( tn ); - if( itt!=d_kinds.end() ){ - std::map< Kind, int >::iterator it = itt->second.find( k ); - if( it!=itt->second.end() ){ - return it->second; - } - } - return -1; -} - -int TermDbSygus::getConstArg( TypeNode tn, Node n ){ - Assert( isRegistered( tn ) ); - std::map< TypeNode, std::map< Node, int > >::iterator itt = d_consts.find( tn ); - if( itt!=d_consts.end() ){ - std::map< Node, int >::iterator it = itt->second.find( n ); - if( it!=itt->second.end() ){ - return it->second; - } - } - return -1; -} - -int TermDbSygus::getOpArg( TypeNode tn, Node n ) { - std::map< Node, int >::iterator it = d_ops[tn].find( n ); - if( it!=d_ops[tn].end() ){ - return it->second; - }else{ - return -1; - } -} - -bool TermDbSygus::hasKind( TypeNode tn, Kind k ) { - return getKindArg( tn, k )!=-1; -} -bool TermDbSygus::hasConst( TypeNode tn, Node n ) { - return getConstArg( tn, n )!=-1; -} -bool TermDbSygus::hasOp( TypeNode tn, Node n ) { - return getOpArg( tn, n )!=-1; -} - -Node TermDbSygus::getArgOp( TypeNode tn, int i ) { - Assert( isRegistered( tn ) ); - std::map< TypeNode, std::map< int, Node > >::iterator itt = d_arg_ops.find( tn ); - if( itt!=d_arg_ops.end() ){ - std::map< int, Node >::iterator itn = itt->second.find( i ); - if( itn!=itt->second.end() ){ - return itn->second; - } - } - return Node::null(); -} - -Node TermDbSygus::getArgConst( TypeNode tn, int i ) { - Assert( isRegistered( tn ) ); - std::map< TypeNode, std::map< int, Node > >::iterator itt = d_arg_const.find( tn ); - if( itt!=d_arg_const.end() ){ - std::map< int, Node >::iterator itn = itt->second.find( i ); - if( itn!=itt->second.end() ){ - return itn->second; - } - } - return Node::null(); -} - -Kind TermDbSygus::getArgKind( TypeNode tn, int i ) { - Assert( isRegistered( tn ) ); - std::map< TypeNode, std::map< int, Kind > >::iterator itt = d_arg_kind.find( tn ); - if( itt!=d_arg_kind.end() ){ - std::map< int, Kind >::iterator itk = itt->second.find( i ); - if( itk!=itt->second.end() ){ - return itk->second; - } - } - return UNDEFINED_KIND; -} - -bool TermDbSygus::isKindArg( TypeNode tn, int i ) { - return getArgKind( tn, i )!=UNDEFINED_KIND; -} - -bool TermDbSygus::isConstArg( TypeNode tn, int i ) { - Assert( isRegistered( tn ) ); - std::map< TypeNode, std::map< int, Node > >::iterator itt = d_arg_const.find( tn ); - if( itt!=d_arg_const.end() ){ - return itt->second.find( i )!=itt->second.end(); - }else{ - return false; - } -} - -unsigned TermDbSygus::getNumIdFuncs( TypeNode tn ) { - return d_id_funcs[tn].size(); -} - -unsigned TermDbSygus::getIdFuncIndex( TypeNode tn, unsigned i ) { - return d_id_funcs[tn][i]; -} - -TypeNode TermDbSygus::getArgType( const DatatypeConstructor& c, int i ) { - Assert( i>=0 && i<(int)c.getNumArgs() ); - return TypeNode::fromType( ((SelectorType)c[i].getType()).getRangeType() ); -} - -Node TermDbSygus::minimizeBuiltinTerm( Node n ) { - if( ( n.getKind()==EQUAL || n.getKind()==LEQ || n.getKind()==LT || n.getKind()==GEQ || n.getKind()==GT ) && - ( n[0].getType().isInteger() || n[0].getType().isReal() ) ){ - bool changed = false; - std::vector< Node > mon[2]; - for( unsigned r=0; r<2; r++ ){ - unsigned ro = r==0 ? 1 : 0; - Node c; - Node nc; - if( n[r].getKind()==PLUS ){ - for( unsigned i=0; i<n[r].getNumChildren(); i++ ){ - if( QuantArith::getMonomial( n[r][i], c, nc ) && c.getConst<Rational>().isNegativeOne() ){ - mon[ro].push_back( nc ); - changed = true; - }else{ - if( !n[r][i].isConst() || !n[r][i].getConst<Rational>().isZero() ){ - mon[r].push_back( n[r][i] ); - } - } - } - }else{ - if( QuantArith::getMonomial( n[r], c, nc ) && c.getConst<Rational>().isNegativeOne() ){ - mon[ro].push_back( nc ); - changed = true; - }else{ - if( !n[r].isConst() || !n[r].getConst<Rational>().isZero() ){ - mon[r].push_back( n[r] ); - } - } - } - } - if( changed ){ - Node nn[2]; - for( unsigned r=0; r<2; r++ ){ - nn[r] = mon[r].size()==0 ? NodeManager::currentNM()->mkConst( Rational(0) ) : ( mon[r].size()==1 ? mon[r][0] : NodeManager::currentNM()->mkNode( PLUS, mon[r] ) ); - } - return NodeManager::currentNM()->mkNode( n.getKind(), nn[0], nn[1] ); - } - } - return n; -} - -Node TermDbSygus::expandBuiltinTerm( Node t ){ - if( t.getKind()==EQUAL ){ - if( t[0].getType().isReal() ){ - return NodeManager::currentNM()->mkNode( AND, NodeManager::currentNM()->mkNode( LEQ, t[0], t[1] ), - NodeManager::currentNM()->mkNode( LEQ, t[1], t[0] ) ); - }else if( t[0].getType().isBoolean() ){ - return NodeManager::currentNM()->mkNode( OR, NodeManager::currentNM()->mkNode( AND, t[0], t[1] ), - NodeManager::currentNM()->mkNode( AND, t[0].negate(), t[1].negate() ) ); - } - }else if( t.getKind()==ITE && t.getType().isBoolean() ){ - return NodeManager::currentNM()->mkNode( OR, NodeManager::currentNM()->mkNode( AND, t[0], t[1] ), - NodeManager::currentNM()->mkNode( AND, t[0].negate(), t[2] ) ); - } - return Node::null(); -} - - -Kind TermDbSygus::getComparisonKind( TypeNode tn ) { - if( tn.isInteger() || tn.isReal() ){ - return LT; - }else if( tn.isBitVector() ){ - return BITVECTOR_ULT; - }else{ - return UNDEFINED_KIND; - } -} - -Kind TermDbSygus::getPlusKind( TypeNode tn, bool is_neg ) { - if( tn.isInteger() || tn.isReal() ){ - return is_neg ? MINUS : PLUS; - }else if( tn.isBitVector() ){ - return is_neg ? BITVECTOR_SUB : BITVECTOR_PLUS; - }else{ - return UNDEFINED_KIND; - } -} - -bool TermDbSygus::doCompare( Node a, Node b, Kind k ) { - Node com = NodeManager::currentNM()->mkNode( k, a, b ); - com = Rewriter::rewrite( com ); - return com==d_true; -} - - -void doStrReplace(std::string& str, const std::string& oldStr, const std::string& newStr){ - size_t pos = 0; - while((pos = str.find(oldStr, pos)) != std::string::npos){ - str.replace(pos, oldStr.length(), newStr); - pos += newStr.length(); - } -} - -Kind TermDbSygus::getOperatorKind( Node op ) { - Assert( op.getKind()!=BUILTIN ); - if( smt::currentSmtEngine()->isDefinedFunction( op.toExpr() ) ){ - return APPLY; - }else{ - TypeNode tn = op.getType(); - if( tn.isConstructor() ){ - return APPLY_CONSTRUCTOR; - }else if( tn.isSelector() ){ - return APPLY_SELECTOR; - }else if( tn.isTester() ){ - return APPLY_TESTER; - }else{ - return NodeManager::operatorToKind( op ); - } - } -} - -void TermDbSygus::printSygusTerm( std::ostream& out, Node n, std::vector< Node >& lvs ) { - if( n.getKind()==APPLY_CONSTRUCTOR ){ - TypeNode tn = n.getType(); - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - if( dt.isSygus() ){ - int cIndex = Datatype::indexOf( n.getOperator().toExpr() ); - Assert( !dt[cIndex].getSygusOp().isNull() ); - if( dt[cIndex].getSygusLetBody().isNull() ){ - if( n.getNumChildren()>0 ){ - out << "("; - } - Node op = dt[cIndex].getSygusOp(); - if( op.getType().isBitVector() && op.isConst() ){ - //print in the style it was given - Trace("sygus-print-bvc") << "[Print " << op << " " << dt[cIndex].getName() << "]" << std::endl; - std::stringstream ss; - ss << dt[cIndex].getName(); - std::string str = ss.str(); - std::size_t found = str.find_last_of("_"); - Assert( found!=std::string::npos ); - std::string name = std::string( str.begin() + found +1, str.end() ); - out << name; - }else{ - out << op; - } - if( n.getNumChildren()>0 ){ - for( unsigned i=0; i<n.getNumChildren(); i++ ){ - out << " "; - printSygusTerm( out, n[i], lvs ); - } - out << ")"; - } - }else{ - std::stringstream let_out; - //print as let term - if( dt[cIndex].getNumSygusLetInputArgs()>0 ){ - let_out << "(let ("; - } - std::vector< Node > subs_lvs; - std::vector< Node > new_lvs; - for( unsigned i=0; i<dt[cIndex].getNumSygusLetArgs(); i++ ){ - Node v = Node::fromExpr( dt[cIndex].getSygusLetArg( i ) ); - subs_lvs.push_back( v ); - std::stringstream ss; - ss << "_l_" << new_lvs.size(); - Node lv = NodeManager::currentNM()->mkBoundVar( ss.str(), v.getType() ); - new_lvs.push_back( lv ); - //map free variables to proper terms - if( i<dt[cIndex].getNumSygusLetInputArgs() ){ - //it should be printed as a let argument - let_out << "("; - let_out << lv << " " << lv.getType() << " "; - printSygusTerm( let_out, n[i], lvs ); - let_out << ")"; - } - } - if( dt[cIndex].getNumSygusLetInputArgs()>0 ){ - let_out << ") "; - } - //print the body - Node let_body = Node::fromExpr( dt[cIndex].getSygusLetBody() ); - let_body = let_body.substitute( subs_lvs.begin(), subs_lvs.end(), new_lvs.begin(), new_lvs.end() ); - new_lvs.insert( new_lvs.end(), lvs.begin(), lvs.end() ); - printSygusTerm( let_out, let_body, new_lvs ); - if( dt[cIndex].getNumSygusLetInputArgs()>0 ){ - let_out << ")"; - } - //do variable substitutions since ASSUMING : let_vars are interpreted literally and do not represent a class of variables - std::string lbody = let_out.str(); - for( unsigned i=0; i<dt[cIndex].getNumSygusLetArgs(); i++ ){ - std::stringstream old_str; - old_str << new_lvs[i]; - std::stringstream new_str; - if( i>=dt[cIndex].getNumSygusLetInputArgs() ){ - printSygusTerm( new_str, n[i], lvs ); - }else{ - new_str << Node::fromExpr( dt[cIndex].getSygusLetArg( i ) ); - } - doStrReplace( lbody, old_str.str().c_str(), new_str.str().c_str() ); - } - out << lbody; - } - return; - } - }else if( !n.getAttribute(SygusProxyAttribute()).isNull() ){ - out << n.getAttribute(SygusProxyAttribute()); - }else{ - out << n; - } -} - -Node TermDbSygus::getAnchor( Node n ) { - if( n.getKind()==APPLY_SELECTOR_TOTAL ){ - return getAnchor( n[0] ); - }else{ - return n; - } -} - -void TermDbSygus::registerEvalTerm( Node n ) { - if( options::sygusDirectEval() ){ - if( n.getKind()==APPLY_UF && !n.getType().isBoolean() ){ - Trace("sygus-eager") << "TermDbSygus::eager: Register eval term : " << n << std::endl; - TypeNode tn = n[0].getType(); - if( tn.isDatatype() ){ - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - if( dt.isSygus() ){ - Node f = n.getOperator(); - Trace("sygus-eager") << "...the evaluation function is : " << f << std::endl; - if( n[0].getKind()!=APPLY_CONSTRUCTOR ){ - d_evals[n[0]].push_back( n ); - TypeNode tn = n[0].getType(); - Assert( tn.isDatatype() ); - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - Node var_list = Node::fromExpr( dt.getSygusVarList() ); - Assert( dt.isSygus() ); - d_eval_args[n[0]].push_back( std::vector< Node >() ); - for( unsigned j=1; j<n.getNumChildren(); j++ ){ - //if( var_list[j-1].getType().isBoolean() ){ - // //TODO: remove this case when boolean term conversion is eliminated - // Node c = NodeManager::currentNM()->mkConst(BitVector(1u, 1u)); - // d_eval_args[n[0]].back().push_back( n[j].eqNode( c ) ); - //}else{ - d_eval_args[n[0]].back().push_back( n[j] ); - //} - } - Node a = getAnchor( n[0] ); - d_subterms[a][n[0]] = true; - } - } - } - } - } -} - -void TermDbSygus::registerModelValue( Node a, Node v, std::vector< Node >& terms, std::vector< Node >& vals, std::vector< Node >& exps ) { - std::map< Node, std::map< Node, bool > >::iterator its = d_subterms.find( a ); - if( its!=d_subterms.end() ){ - Trace("sygus-eager") << "registerModelValue : " << a << ", has " << its->second.size() << " registered subterms." << std::endl; - for( std::map< Node, bool >::iterator itss = its->second.begin(); itss != its->second.end(); ++itss ){ - Node n = itss->first; - Trace("sygus-eager-debug") << "...process : " << n << std::endl; - std::map< Node, std::vector< std::vector< Node > > >::iterator it = d_eval_args.find( n ); - if( it!=d_eval_args.end() && !it->second.empty() ){ - TNode at = a; - TNode vt = v; - Node vn = n.substitute( at, vt ); - vn = Rewriter::rewrite( vn ); - unsigned start = d_node_mv_args_proc[n][vn]; - Node antec = n.eqNode( vn ); - TypeNode tn = n.getType(); - Assert( tn.isDatatype() ); - const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); - Assert( dt.isSygus() ); - Trace("sygus-eager") << "TermDbSygus::eager: Register model value : " << vn << " for " << n << std::endl; - Trace("sygus-eager") << "...it has " << it->second.size() << " evaluations, already processed " << start << "." << std::endl; - Node bTerm = d_quantEngine->getTermDatabaseSygus()->sygusToBuiltin( vn, tn ); - Trace("sygus-eager") << "Built-in term : " << bTerm << std::endl; - std::vector< Node > vars; - Node var_list = Node::fromExpr( dt.getSygusVarList() ); - for( unsigned j=0; j<var_list.getNumChildren(); j++ ){ - vars.push_back( var_list[j] ); - } - //for each evaluation - for( unsigned i=start; i<it->second.size(); i++ ){ - Assert( vars.size()==it->second[i].size() ); - Node sBTerm = bTerm.substitute( vars.begin(), vars.end(), it->second[i].begin(), it->second[i].end() ); - sBTerm = Rewriter::rewrite( sBTerm ); - //Node lem = NodeManager::currentNM()->mkNode(EQUAL, d_evals[n][i], sBTerm ); - //lem = NodeManager::currentNM()->mkNode( OR, antec.negate(), lem ); - terms.push_back( d_evals[n][i] ); - vals.push_back( sBTerm ); - exps.push_back( antec ); - Trace("sygus-eager") << "Conclude : " << d_evals[n][i] << " == " << sBTerm << std::endl; - Trace("sygus-eager") << " from " << antec << std::endl; - //Trace("sygus-eager") << "Lemma : " << lem << std::endl; - //lems.push_back( lem ); - } - d_node_mv_args_proc[n][vn] = it->second.size(); - } - } - } -} - - -Node TermDbSygus::unfold( Node en, std::map< Node, Node >& vtm, std::vector< Node >& exp, bool track_exp ) { - if( en.getKind()==kind::APPLY_UF ){ - Node ev = en[0]; - if( track_exp ){ - std::map< Node, Node >::iterator itv = vtm.find( en[0] ); - if( itv!=vtm.end() ){ - ev = itv->second; - }else{ - Assert( false ); - } - Assert( en[0].getType()==ev.getType() ); - Assert( ev.isConst() ); - } - Assert( ev.getKind()==kind::APPLY_CONSTRUCTOR ); - std::vector< Node > args; - for( unsigned i=1; i<en.getNumChildren(); i++ ){ - args.push_back( en[i] ); - } - const Datatype& dt = ((DatatypeType)(ev.getType()).toType()).getDatatype(); - unsigned i = Datatype::indexOf( ev.getOperator().toExpr() ); - if( track_exp ){ - //explanation - Node ee = NodeManager::currentNM()->mkNode( kind::APPLY_TESTER, Node::fromExpr( dt[i].getTester() ), en[0] ); - if( std::find( exp.begin(), exp.end(), ee )==exp.end() ){ - exp.push_back( ee ); - } - } - std::map< int, Node > pre; - for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){ - std::vector< Node > cc; - //get the evaluation argument for the selector - const Datatype & ad = ((DatatypeType)dt[i][j].getRangeType()).getDatatype(); - cc.push_back( Node::fromExpr( ad.getSygusEvaluationFunc() ) ); - Node s = en[0].getKind()==kind::APPLY_CONSTRUCTOR ? en[0][j] : NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[i][j].getSelector() ), en[0] ); - cc.push_back( s ); - if( track_exp ){ - //update vtm map - vtm[s] = ev[j]; - } - cc.insert( cc.end(), args.begin(), args.end() ); - pre[j] = NodeManager::currentNM()->mkNode( kind::APPLY_UF, cc ); - } - std::map< TypeNode, int > var_count; - Node ret = mkGeneric( dt, i, var_count, pre ); - // if it is a variable, apply the substitution - if( ret.getKind()==kind::BOUND_VARIABLE ){ - //replace by argument - Node var_list = Node::fromExpr( dt.getSygusVarList() ); - //TODO : set argument # on sygus variables - for( unsigned j=0; j<var_list.getNumChildren(); j++ ){ - if( var_list[j]==ret ){ - ret = args[j]; - break; - } - } - Assert( ret.isConst() ); - }else if( ret.getKind()==APPLY ){ - //must expand definitions to account for defined functions in sygus grammars - ret = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( ret.toExpr() ) ); - } - return ret; - }else{ - Assert( en.isConst() ); - } - return en; -} - }/* CVC4::theory::quantifiers namespace */ }/* CVC4::theory namespace */ }/* CVC4 namespace */ diff --git a/src/theory/quantifiers/term_database.h b/src/theory/quantifiers/term_database.h index c018172b5..4650cc5d4 100644 --- a/src/theory/quantifiers/term_database.h +++ b/src/theory/quantifiers/term_database.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,12 +17,14 @@ #ifndef __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_H #define __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_H +#include <map> +#include <unordered_set> + #include "expr/attribute.h" #include "theory/theory.h" #include "theory/type_enumerator.h" #include "theory/quantifiers/quant_util.h" -#include <map> namespace CVC4 { namespace theory { @@ -93,6 +95,14 @@ typedef expr::Attribute< LtePartialInstAttributeId, bool > LtePartialInstAttribu struct SygusProxyAttributeId {}; typedef expr::Attribute<SygusProxyAttributeId, Node> SygusProxyAttribute; +// attribute for associating a synthesis function with a first order variable +struct SygusSynthFunAttributeId {}; +typedef expr::Attribute<SygusSynthFunAttributeId, Node> SygusSynthFunAttribute; + +// attribute for associating a variable list with a synth fun +struct SygusSynthFunVarListAttributeId {}; +typedef expr::Attribute<SygusSynthFunVarListAttributeId, Node> SygusSynthFunVarListAttribute; + //attribute for fun-def abstraction type struct AbsTypeFunDefAttributeId {}; typedef expr::Attribute<AbsTypeFunDefAttributeId, bool> AbsTypeFunDefAttribute; @@ -109,6 +119,11 @@ typedef expr::Attribute< QuantElimPartialAttributeId, bool > QuantElimPartialAtt struct QuantIdNumAttributeId {}; typedef expr::Attribute< QuantIdNumAttributeId, uint64_t > QuantIdNumAttribute; +/** sygus var num */ +struct SygusVarNumAttributeId {}; +typedef expr::Attribute<SygusVarNumAttributeId, uint64_t> SygusVarNumAttribute; + + class QuantifiersEngine; @@ -181,9 +196,9 @@ private: /** reference to the quantifiers engine */ QuantifiersEngine* d_quantEngine; /** terms processed */ - std::hash_set< Node, NodeHashFunction > d_processed; + std::unordered_set< Node, NodeHashFunction > d_processed; /** terms processed */ - std::hash_set< Node, NodeHashFunction > d_iclosure_processed; + std::unordered_set< Node, NodeHashFunction > d_iclosure_processed; /** select op map */ std::map< Node, std::map< TypeNode, Node > > d_par_op_map; /** whether master equality engine is UF-inconsistent */ @@ -495,6 +510,8 @@ public: static bool isAssoc( Kind k ); /** is comm */ static bool isComm( Kind k ); + /** ( x k ... ) k x = ( x k ... ) */ + static bool isNonAdditive( Kind k ); /** is bool connective */ static bool isBoolConnective( Kind k ); /** is bool connective term */ @@ -559,126 +576,6 @@ public: static void computeQuantAttributes( Node q, QAttributes& qa ); };/* class TermDb */ -class TermDbSygus { -private: - /** reference to the quantifiers engine */ - QuantifiersEngine* d_quantEngine; - std::map< TypeNode, std::vector< Node > > d_fv; - std::map< Node, TypeNode > d_fv_stype; - std::map< Node, int > d_fv_num; - Node d_true; - Node d_false; -public: - TNode getVar( TypeNode tn, int i ); - TNode getVarInc( TypeNode tn, std::map< TypeNode, int >& var_count ); - bool isVar( Node n ) { return d_fv_stype.find( n )!=d_fv_stype.end(); } - int getVarNum( Node n ) { return d_fv_num[n]; } -private: - std::map< TypeNode, std::map< int, Node > > d_generic_base; - std::map< TypeNode, std::vector< Node > > d_generic_templ; - bool getMatch( Node p, Node n, std::map< int, Node >& s ); - bool getMatch2( Node p, Node n, std::map< int, Node >& s, std::vector< int >& new_s ); -public: - bool getMatch( Node n, TypeNode st, int& index_found, std::vector< Node >& args, int index_exc = -1, int index_start = 0 ); -private: - //information for sygus types - std::map< TypeNode, TypeNode > d_register; //stores sygus -> builtin type - std::map< TypeNode, std::map< int, Kind > > d_arg_kind; - std::map< TypeNode, std::map< Kind, int > > d_kinds; - std::map< TypeNode, std::map< int, Node > > d_arg_const; - std::map< TypeNode, std::map< Node, int > > d_consts; - std::map< TypeNode, std::map< Node, int > > d_ops; - std::map< TypeNode, std::map< int, Node > > d_arg_ops; - std::map< TypeNode, std::vector< int > > d_id_funcs; - std::map< TypeNode, std::vector< Node > > d_const_list; //sorted list of constants for type - std::map< TypeNode, unsigned > d_const_list_pos; - //information for builtin types - std::map< TypeNode, std::map< int, Node > > d_type_value; - std::map< TypeNode, Node > d_type_max_value; - std::map< TypeNode, std::map< Node, std::map< int, Node > > > d_type_value_offset; - std::map< TypeNode, std::map< Node, std::map< int, int > > > d_type_value_offset_status; - //normalized map - std::map< TypeNode, std::map< Node, Node > > d_normalized; - std::map< TypeNode, std::map< Node, Node > > d_sygus_to_builtin; - std::map< TypeNode, std::map< Node, Node > > d_builtin_const_to_sygus; -public: - TermDbSygus( context::Context* c, QuantifiersEngine* qe ); - ~TermDbSygus(){} - bool reset( Theory::Effort e ); - std::string identify() const { return "TermDbSygus"; } - - bool isRegistered( TypeNode tn ); - TypeNode sygusToBuiltinType( TypeNode tn ); - int getKindArg( TypeNode tn, Kind k ); - int getConstArg( TypeNode tn, Node n ); - int getOpArg( TypeNode tn, Node n ); - bool hasKind( TypeNode tn, Kind k ); - bool hasConst( TypeNode tn, Node n ); - bool hasOp( TypeNode tn, Node n ); - Node getArgConst( TypeNode tn, int i ); - Node getArgOp( TypeNode tn, int i ); - Kind getArgKind( TypeNode tn, int i ); - bool isKindArg( TypeNode tn, int i ); - bool isConstArg( TypeNode tn, int i ); - unsigned getNumIdFuncs( TypeNode tn ); - unsigned getIdFuncIndex( TypeNode tn, unsigned i ); - void registerSygusType( TypeNode tn ); - /** get arg type */ - TypeNode getArgType( const DatatypeConstructor& c, int i ); - /** isAntisymmetric */ - bool isAntisymmetric( Kind k, Kind& dk ); - /** is idempotent arg */ - bool isIdempotentArg( Node n, Kind ik, int arg ); - /** is singular arg */ - bool isSingularArg( Node n, Kind ik, int arg ); - /** get offset arg */ - bool hasOffsetArg( Kind ik, int arg, int& offset, Kind& ok ); - /** get value */ - Node getTypeValue( TypeNode tn, int val ); - /** get value */ - Node getTypeValueOffset( TypeNode tn, Node val, int offset, int& status ); - /** get value */ - Node getTypeMaxValue( TypeNode tn ); - TypeNode getSygusTypeForVar( Node v ); - Node getGenericBase( TypeNode tn, const Datatype& dt, int c ); - Node mkGeneric( const Datatype& dt, int c, std::map< TypeNode, int >& var_count, std::map< int, Node >& pre ); - Node sygusToBuiltin( Node n, TypeNode tn ); - Node builtinToSygusConst( Node c, TypeNode tn, int rcons_depth = 0 ); - Node getSygusNormalized( Node n, std::map< TypeNode, int >& var_count, std::map< Node, Node >& subs ); - Node getNormalized( TypeNode t, Node prog, bool do_pre_norm = false, bool do_post_norm = true ); - int getSygusTermSize( Node n ); - /** given a term, construct an equivalent smaller one that respects syntax */ - Node minimizeBuiltinTerm( Node n ); - /** given a term, expand it into more basic components */ - Node expandBuiltinTerm( Node n ); - /** get comparison kind */ - Kind getComparisonKind( TypeNode tn ); - Kind getPlusKind( TypeNode tn, bool is_neg = false ); - bool doCompare( Node a, Node b, Kind k ); - /** get operator kind */ - static Kind getOperatorKind( Node op ); - /** print sygus term */ - static void printSygusTerm( std::ostream& out, Node n, std::vector< Node >& lvs ); - - /** get anchor */ - static Node getAnchor( Node n ); -//for eager instantiation -private: - std::map< Node, std::map< Node, bool > > d_subterms; - std::map< Node, std::vector< Node > > d_evals; - std::map< Node, std::vector< std::vector< Node > > > d_eval_args; - std::map< Node, std::map< Node, unsigned > > d_node_mv_args_proc; -public: - void registerEvalTerm( Node n ); - void registerModelValue( Node n, Node v, std::vector< Node >& exps, std::vector< Node >& terms, std::vector< Node >& vals ); - Node unfold( Node en, std::map< Node, Node >& vtm, std::vector< Node >& exp, bool track_exp = true ); - Node unfold( Node en ){ - std::map< Node, Node > vtm; - std::vector< Node > exp; - return unfold( en, vtm, exp, false ); - } -}; - }/* CVC4::theory::quantifiers namespace */ }/* CVC4::theory namespace */ }/* CVC4 namespace */ diff --git a/src/theory/quantifiers/term_database_sygus.cpp b/src/theory/quantifiers/term_database_sygus.cpp new file mode 100644 index 000000000..d8913da56 --- /dev/null +++ b/src/theory/quantifiers/term_database_sygus.cpp @@ -0,0 +1,3008 @@ +/********************* */ +/*! \file term_database_sygus.cpp + ** \verbatim + ** Top contributors (to current version): + ** Andrew Reynoldsg + ** 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 Implementation of term databse class + **/ + +#include "theory/quantifiers/term_database_sygus.h" + +#include "expr/datatype.h" +#include "options/base_options.h" +#include "options/quantifiers_options.h" +#include "options/datatypes_options.h" +#include "theory/quantifiers/ce_guided_instantiation.h" +#include "theory/quantifiers/first_order_model.h" +#include "theory/quantifiers/fun_def_engine.h" +#include "theory/quantifiers/rewrite_engine.h" +#include "theory/quantifiers/theory_quantifiers.h" +#include "theory/quantifiers/trigger.h" +#include "theory/quantifiers_engine.h" +#include "theory/theory_engine.h" + +//for sygus +#include "smt/smt_engine_scope.h" +#include "theory/bv/theory_bv_utils.h" +#include "util/bitvector.h" +#include "theory/datatypes/datatypes_rewriter.h" +#include "theory/strings/theory_strings_rewriter.h" + +using namespace std; +using namespace CVC4::kind; +using namespace CVC4::context; +using namespace CVC4::theory::inst; + +namespace CVC4 { +namespace theory { +namespace quantifiers { + +bool EvalSygusInvarianceTest::invariant( quantifiers::TermDbSygus * tds, Node nvn, Node x ){ + TNode tnvn = nvn; + Node conj_subs = d_conj.substitute( d_var, tnvn ); + Node conj_subs_unfold = tds->evaluateWithUnfolding( conj_subs, d_visited ); + Trace("sygus-cref-eval2-debug") << " ...check unfolding : " << conj_subs_unfold << std::endl; + Trace("sygus-cref-eval2-debug") << " ......from : " << conj_subs << std::endl; + if( conj_subs_unfold==d_result ){ + Trace("sygus-cref-eval2") << "Evaluation min explain : " << conj_subs << " still evaluates to " << d_result << " regardless of "; + Trace("sygus-cref-eval2") << x << std::endl; + return true; + }else{ + return false; + } +} + +TermDbSygus::TermDbSygus( context::Context* c, QuantifiersEngine* qe ) : d_quantEngine( qe ){ + d_true = NodeManager::currentNM()->mkConst( true ); + d_false = NodeManager::currentNM()->mkConst( false ); +} + +bool TermDbSygus::reset( Theory::Effort e ) { + return true; +} + +TNode TermDbSygus::getFreeVar( TypeNode tn, int i, bool useSygusType ) { + unsigned sindex = 0; + TypeNode vtn = tn; + if( useSygusType ){ + if( tn.isDatatype() ){ + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + if( !dt.getSygusType().isNull() ){ + vtn = TypeNode::fromType( dt.getSygusType() ); + sindex = 1; + } + } + } + while( i>=(int)d_fv[sindex][tn].size() ){ + std::stringstream ss; + if( tn.isDatatype() ){ + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + ss << "fv_" << dt.getName() << "_" << i; + }else{ + ss << "fv_" << tn << "_" << i; + } + Assert( !vtn.isNull() ); + Node v = NodeManager::currentNM()->mkSkolem( ss.str(), vtn, "for sygus normal form testing" ); + d_fv_stype[v] = tn; + d_fv_num[v] = i; + d_fv[sindex][tn].push_back( v ); + } + return d_fv[sindex][tn][i]; +} + +TNode TermDbSygus::getFreeVarInc( TypeNode tn, std::map< TypeNode, int >& var_count, bool useSygusType ) { + std::map< TypeNode, int >::iterator it = var_count.find( tn ); + if( it==var_count.end() ){ + var_count[tn] = 1; + return getFreeVar( tn, 0, useSygusType ); + }else{ + int index = it->second; + var_count[tn]++; + return getFreeVar( tn, index, useSygusType ); + } +} + +bool TermDbSygus::hasFreeVar( Node n, std::map< Node, bool >& visited ){ + if( visited.find( n )==visited.end() ){ + visited[n] = true; + if( isFreeVar( n ) ){ + return true; + } + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + if( hasFreeVar( n[i], visited ) ){ + return true; + } + } + } + return false; +} + +bool TermDbSygus::hasFreeVar( Node n ) { + std::map< Node, bool > visited; + return hasFreeVar( n, visited ); +} + +TypeNode TermDbSygus::getSygusTypeForVar( Node v ) { + Assert( d_fv_stype.find( v )!=d_fv_stype.end() ); + return d_fv_stype[v]; +} + +bool TermDbSygus::getMatch( Node p, Node n, std::map< int, Node >& s ) { + std::vector< int > new_s; + return getMatch2( p, n, s, new_s ); +} + +bool TermDbSygus::getMatch2( Node p, Node n, std::map< int, Node >& s, std::vector< int >& new_s ) { + std::map< Node, int >::iterator it = d_fv_num.find( p ); + if( it!=d_fv_num.end() ){ + Node prev = s[it->second]; + s[it->second] = n; + if( prev.isNull() ){ + new_s.push_back( it->second ); + } + return prev.isNull() || prev==n; + }else if( n.getNumChildren()==0 ){ + return p==n; + }else if( n.getKind()==p.getKind() && n.getNumChildren()==p.getNumChildren() ){ + //try both ways? + unsigned rmax = TermDb::isComm( n.getKind() ) && n.getNumChildren()==2 ? 2 : 1; + std::vector< int > new_tmp; + for( unsigned r=0; r<rmax; r++ ){ + bool success = true; + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + int io = r==0 ? i : ( i==0 ? 1 : 0 ); + if( !getMatch2( p[i], n[io], s, new_tmp ) ){ + success = false; + for( unsigned j=0; j<new_tmp.size(); j++ ){ + s.erase( new_tmp[j] ); + } + new_tmp.clear(); + break; + } + } + if( success ){ + new_s.insert( new_s.end(), new_tmp.begin(), new_tmp.end() ); + return true; + } + } + } + return false; +} + +bool TermDbSygus::getMatch( Node t, TypeNode st, int& index_found, std::vector< Node >& args, int index_exc, int index_start ) { + Assert( st.isDatatype() ); + const Datatype& dt = ((DatatypeType)(st).toType()).getDatatype(); + Assert( dt.isSygus() ); + std::map< Kind, std::vector< Node > > kgens; + std::vector< Node > gens; + for( unsigned i=index_start; i<dt.getNumConstructors(); i++ ){ + if( (int)i!=index_exc ){ + Node g = getGenericBase( st, dt, i ); + gens.push_back( g ); + kgens[g.getKind()].push_back( g ); + Trace("sygus-db-debug") << "Check generic base : " << g << " from " << dt[i].getName() << std::endl; + if( g.getKind()==t.getKind() ){ + Trace("sygus-db-debug") << "Possible match ? " << g << " " << t << " for " << dt[i].getName() << std::endl; + std::map< int, Node > sigma; + if( getMatch( g, t, sigma ) ){ + //we found an exact match + bool msuccess = true; + for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){ + if( sigma[j].isNull() ){ + msuccess = false; + break; + }else{ + args.push_back( sigma[j] ); + } + } + if( msuccess ){ + index_found = i; + return true; + } + //we found an exact match + //std::map< TypeNode, int > var_count; + //Node new_t = mkGeneric( dt, i, var_count, args ); + //Trace("sygus-db-debug") << "Rewrote to : " << new_t << std::endl; + //return new_t; + } + } + } + } + /* + //otherwise, try to modulate based on kinds + for( std::map< Kind, std::vector< Node > >::iterator it = kgens.begin(); it != kgens.end(); ++it ){ + if( it->second.size()>1 ){ + for( unsigned i=0; i<it->second.size(); i++ ){ + for( unsigned j=0; j<it->second.size(); j++ ){ + if( i!=j ){ + std::map< int, Node > sigma; + if( getMatch( it->second[i], it->second[j], sigma ) ){ + if( sigma.size()==1 ){ + //Node mod_pat = sigma.begin().second; + //Trace("cegqi-si-rcons-debug") << "Modulated pattern " << mod_pat << " from " << it->second[i] << " and " << it->second[j] << std::endl; + } + } + } + } + } + } + } + */ + return false; +} + +Node TermDbSygus::getGenericBase( TypeNode tn, const Datatype& dt, int c ) { + std::map< int, Node >::iterator it = d_generic_base[tn].find( c ); + if( it==d_generic_base[tn].end() ){ + Assert( isRegistered( tn ) ); + std::map< TypeNode, int > var_count; + std::map< int, Node > pre; + Node g = mkGeneric( dt, c, var_count, pre ); + Trace("sygus-db-debug") << "Sygus DB : Generic is " << g << std::endl; + Node gr = Rewriter::rewrite( g ); + Trace("sygus-db-debug") << "Sygus DB : Generic rewritten is " << gr << std::endl; + gr = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( gr.toExpr() ) ); + Trace("sygus-db-debug") << "Sygus DB : Generic base " << dt[c].getName() << " : " << gr << std::endl; + d_generic_base[tn][c] = gr; + return gr; + }else{ + return it->second; + } +} + +Node TermDbSygus::mkGeneric( const Datatype& dt, int c, std::map< TypeNode, int >& var_count, std::map< int, Node >& pre ) { + Assert( c>=0 && c<(int)dt.getNumConstructors() ); + Assert( dt.isSygus() ); + Assert( !dt[c].getSygusOp().isNull() ); + std::vector< Node > children; + Node op = Node::fromExpr( dt[c].getSygusOp() ); + if( op.getKind()!=BUILTIN ){ + children.push_back( op ); + } + Trace("sygus-db-debug") << "mkGeneric " << dt.getName() << " " << op << " " << op.getKind() << "..." << std::endl; + for( int i=0; i<(int)dt[c].getNumArgs(); i++ ){ + TypeNode tna = getArgType( dt[c], i ); + Node a; + std::map< int, Node >::iterator it = pre.find( i ); + if( it!=pre.end() ){ + a = it->second; + }else{ + a = getFreeVarInc( tna, var_count, true ); + } + Assert( !a.isNull() ); + children.push_back( a ); + } + Node ret; + if( op.getKind()==BUILTIN ){ + ret = NodeManager::currentNM()->mkNode( op, children ); + }else{ + Kind ok = getOperatorKind( op ); + Trace("sygus-db-debug") << "Operator kind is " << ok << std::endl; + if( children.size()==1 && ok==kind::UNDEFINED_KIND ){ + ret = children[0]; + }else{ + ret = NodeManager::currentNM()->mkNode( ok, children ); + /* + Node n = NodeManager::currentNM()->mkNode( APPLY, children ); + //must expand definitions + Node ne = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( n.toExpr() ) ); + Trace("sygus-db-debug") << "Expanded definitions in " << n << " to " << ne << std::endl; + return ne; + */ + } + } + Trace("sygus-db-debug") << "...returning " << ret << std::endl; + return ret; +} + +Node TermDbSygus::sygusToBuiltin( Node n, TypeNode tn ) { + Assert( n.getType()==tn ); + Assert( tn.isDatatype() ); + std::map< Node, Node >::iterator it = d_sygus_to_builtin[tn].find( n ); + if( it==d_sygus_to_builtin[tn].end() ){ + Trace("sygus-db-debug") << "SygusToBuiltin : compute for " << n << ", type = " << tn << std::endl; + Node ret; + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + if( n.getKind()==APPLY_CONSTRUCTOR ){ + unsigned i = Datatype::indexOf( n.getOperator().toExpr() ); + Assert( n.getNumChildren()==dt[i].getNumArgs() ); + std::map< TypeNode, int > var_count; + std::map< int, Node > pre; + for( unsigned j=0; j<n.getNumChildren(); j++ ){ + pre[j] = sygusToBuiltin( n[j], getArgType( dt[i], j ) ); + } + ret = mkGeneric( dt, i, var_count, pre ); + Trace("sygus-db-debug") << "SygusToBuiltin : Generic is " << ret << std::endl; + ret = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( ret.toExpr() ) ); + Trace("sygus-db-debug") << "SygusToBuiltin : After expand definitions " << ret << std::endl; + d_sygus_to_builtin[tn][n] = ret; + }else{ + Assert( isFreeVar( n ) ); + //map to builtin variable type + int fv_num = getVarNum( n ); + Assert( !dt.getSygusType().isNull() ); + TypeNode vtn = TypeNode::fromType( dt.getSygusType() ); + ret = getFreeVar( vtn, fv_num ); + } + return ret; + }else{ + return it->second; + } +} + +Node TermDbSygus::sygusSubstituted( TypeNode tn, Node n, std::vector< Node >& args ) { + Assert( d_var_list[tn].size()==args.size() ); + return n.substitute( d_var_list[tn].begin(), d_var_list[tn].end(), args.begin(), args.end() ); +} + +//rcons_depth limits the number of recursive calls when doing accelerated constant reconstruction (currently limited to 1000) +//this is hacky : depending upon order of calls, constant rcons may succeed, e.g. 1001, 999 vs. 999, 1001 +Node TermDbSygus::builtinToSygusConst( Node c, TypeNode tn, int rcons_depth ) { + std::map< Node, Node >::iterator it = d_builtin_const_to_sygus[tn].find( c ); + if( it==d_builtin_const_to_sygus[tn].end() ){ + Node sc; + d_builtin_const_to_sygus[tn][c] = sc; + Assert( c.isConst() ); + Assert( tn.isDatatype() ); + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + Trace("csi-rcons-debug") << "Try to reconstruct " << c << " in " << dt.getName() << std::endl; + Assert( dt.isSygus() ); + // if we are not interested in reconstructing constants, or the grammar allows them, return a proxy + if( !options::cegqiSingleInvReconstructConst() || dt.getSygusAllowConst() ){ + Node k = NodeManager::currentNM()->mkSkolem( "sy", tn, "sygus proxy" ); + SygusProxyAttribute spa; + k.setAttribute(spa,c); + sc = k; + }else{ + int carg = getOpConsNum( tn, c ); + if( carg!=-1 ){ + //sc = Node::fromExpr( dt[carg].getSygusOp() ); + sc = NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, Node::fromExpr( dt[carg].getConstructor() ) ); + }else{ + //identity functions + for( unsigned i=0; i<getNumIdFuncs( tn ); i++ ){ + unsigned ii = getIdFuncIndex( tn, i ); + Assert( dt[ii].getNumArgs()==1 ); + //try to directly reconstruct from single argument + TypeNode tnc = getArgType( dt[ii], 0 ); + Trace("csi-rcons-debug") << "Based on id function " << dt[ii].getSygusOp() << ", try reconstructing " << c << " instead in " << tnc << std::endl; + Node n = builtinToSygusConst( c, tnc, rcons_depth ); + if( !n.isNull() ){ + sc = NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, Node::fromExpr( dt[ii].getConstructor() ), n ); + break; + } + } + if( sc.isNull() ){ + if( rcons_depth<1000 ){ + //accelerated, recursive reconstruction of constants + Kind pk = getPlusKind( TypeNode::fromType( dt.getSygusType() ) ); + if( pk!=UNDEFINED_KIND ){ + int arg = getKindConsNum( tn, pk ); + if( arg!=-1 ){ + Kind ck = getComparisonKind( TypeNode::fromType( dt.getSygusType() ) ); + Kind pkm = getPlusKind( TypeNode::fromType( dt.getSygusType() ), true ); + //get types + Assert( dt[arg].getNumArgs()==2 ); + TypeNode tn1 = getArgType( dt[arg], 0 ); + TypeNode tn2 = getArgType( dt[arg], 1 ); + //iterate over all positive constants, largest to smallest + int start = d_const_list[tn1].size()-1; + int end = d_const_list[tn1].size()-d_const_list_pos[tn1]; + for( int i=start; i>=end; --i ){ + Node c1 = d_const_list[tn1][i]; + //only consider if smaller than c, and + if( doCompare( c1, c, ck ) ){ + Node c2 = NodeManager::currentNM()->mkNode( pkm, c, c1 ); + c2 = Rewriter::rewrite( c2 ); + if( c2.isConst() ){ + //reconstruct constant on the other side + Node sc2 = builtinToSygusConst( c2, tn2, rcons_depth+1 ); + if( !sc2.isNull() ){ + Node sc1 = builtinToSygusConst( c1, tn1, rcons_depth ); + Assert( !sc1.isNull() ); + sc = NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, Node::fromExpr( dt[arg].getConstructor() ), sc1, sc2 ); + break; + } + } + } + } + } + } + } + } + } + } + d_builtin_const_to_sygus[tn][c] = sc; + return sc; + }else{ + return it->second; + } +} + +Node TermDbSygus::getSygusNormalized( Node n, std::map< TypeNode, int >& var_count, std::map< Node, Node >& subs ) { + return n; + /* TODO? + if( n.getKind()==SKOLEM ){ + std::map< Node, Node >::iterator its = subs.find( n ); + if( its!=subs.end() ){ + return its->second; + }else{ + std::map< Node, TypeNode >::iterator it = d_fv_stype.find( n ); + if( it!=d_fv_stype.end() ){ + Node v = getVarInc( it->second, var_count ); + subs[n] = v; + return v; + }else{ + return n; + } + } + }else{ + if( n.getNumChildren()>0 ){ + std::vector< Node > children; + if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){ + children.push_back( n.getOperator() ); + } + bool childChanged = false; + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + Node nc = getSygusNormalized( n[i], var_count, subs ); + childChanged = childChanged || nc!=n[i]; + children.push_back( nc ); + } + if( childChanged ){ + return NodeManager::currentNM()->mkNode( n.getKind(), children ); + } + } + return n; + } + */ +} + +Node TermDbSygus::getNormalized( TypeNode t, Node prog, bool do_pre_norm, bool do_post_norm ) { + if( do_pre_norm ){ + std::map< TypeNode, int > var_count; + std::map< Node, Node > subs; + prog = getSygusNormalized( prog, var_count, subs ); + } + std::map< Node, Node >::iterator itn = d_normalized[t].find( prog ); + if( itn==d_normalized[t].end() ){ + Node progr = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( prog.toExpr() ) ); + progr = Rewriter::rewrite( progr ); + if( do_post_norm ){ + std::map< TypeNode, int > var_count; + std::map< Node, Node > subs; + progr = getSygusNormalized( progr, var_count, subs ); + } + Trace("sygus-sym-break2") << "...rewrites to " << progr << std::endl; + d_normalized[t][prog] = progr; + return progr; + }else{ + return itn->second; + } +} + +unsigned TermDbSygus::getSygusTermSize( Node n ){ + if( n.getNumChildren()==0 ){ + return 0; + }else{ + unsigned sum = 0; + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + sum += getSygusTermSize( n[i] ); + } + return 1+sum; + } +} + +unsigned TermDbSygus::getSygusConstructors( Node n, std::vector< Node >& cons ) { + Assert( n.getKind()==APPLY_CONSTRUCTOR ); + Node op = n.getOperator(); + if( std::find( cons.begin(), cons.end(), op )==cons.end() ){ + cons.push_back( op ); + } + if( n.getNumChildren()==0 ){ + return 0; + }else{ + unsigned sum = 0; + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + sum += getSygusConstructors( n[i], cons ); + } + return 1+sum; + } +} + +bool TermDbSygus::isAntisymmetric( Kind k, Kind& dk ) { + if( k==GT ){ + dk = LT; + return true; + }else if( k==GEQ ){ + dk = LEQ; + return true; + }else if( k==BITVECTOR_UGT ){ + dk = BITVECTOR_ULT; + return true; + }else if( k==BITVECTOR_UGE ){ + dk = BITVECTOR_ULE; + return true; + }else if( k==BITVECTOR_SGT ){ + dk = BITVECTOR_SLT; + return true; + }else if( k==BITVECTOR_SGE ){ + dk = BITVECTOR_SLE; + return true; + }else{ + return false; + } +} + +bool TermDbSygus::isIdempotentArg( Node n, Kind ik, int arg ) { + // these should all be binary operators + //Assert( ik!=DIVISION && ik!=INTS_DIVISION && ik!=INTS_MODULUS && ik!=BITVECTOR_UDIV ); + TypeNode tn = n.getType(); + if( n==getTypeValue( tn, 0 ) ){ + if( ik==PLUS || ik==OR || ik==XOR || ik==BITVECTOR_PLUS || ik==BITVECTOR_OR || ik==BITVECTOR_XOR || ik==STRING_CONCAT ){ + return true; + }else if( ik==MINUS || ik==BITVECTOR_SHL || ik==BITVECTOR_LSHR || ik==BITVECTOR_ASHR || ik==BITVECTOR_SUB || + ik==BITVECTOR_UREM || ik==BITVECTOR_UREM_TOTAL ){ + return arg==1; + } + }else if( n==getTypeValue( tn, 1 ) ){ + if( ik==MULT || ik==BITVECTOR_MULT ){ + return true; + }else if( ik==DIVISION || ik==DIVISION_TOTAL || ik==INTS_DIVISION || ik==INTS_DIVISION_TOTAL || + ik==INTS_MODULUS || ik==INTS_MODULUS_TOTAL || + ik==BITVECTOR_UDIV_TOTAL || ik==BITVECTOR_UDIV || ik==BITVECTOR_SDIV ){ + return arg==1; + } + }else if( n==getTypeMaxValue( tn ) ){ + if( ik==EQUAL || ik==BITVECTOR_AND || ik==BITVECTOR_XNOR ){ + return true; + } + } + return false; +} + + +Node TermDbSygus::isSingularArg( Node n, Kind ik, int arg ) { + TypeNode tn = n.getType(); + if( n==getTypeValue( tn, 0 ) ){ + if( ik==AND || ik==MULT || ik==BITVECTOR_AND || ik==BITVECTOR_MULT ){ + return n; + }else if( ik==BITVECTOR_SHL || ik==BITVECTOR_LSHR || ik==BITVECTOR_ASHR || + ik==BITVECTOR_UREM || ik==BITVECTOR_UREM_TOTAL ){ + if( arg==0 ){ + return n; + } + }else if( ik==BITVECTOR_UDIV_TOTAL || ik==BITVECTOR_UDIV || ik==BITVECTOR_SDIV ){ + if( arg==0 ){ + return n; + }else if( arg==1 ){ + return getTypeMaxValue( tn ); + } + }else if( ik==DIVISION || ik==DIVISION_TOTAL || ik==INTS_DIVISION || ik==INTS_DIVISION_TOTAL || + ik==INTS_MODULUS || ik==INTS_MODULUS_TOTAL ){ + if( arg==0 ){ + return n; + }else{ + //TODO? + } + }else if( ik==STRING_SUBSTR ){ + if( arg==0 ){ + return n; + }else if( arg==2 ){ + return getTypeValue( NodeManager::currentNM()->stringType(), 0 ); + } + }else if( ik==STRING_STRIDOF ){ + if( arg==0 || arg==1 ){ + return getTypeValue( NodeManager::currentNM()->integerType(), -1 ); + } + } + }else if( n==getTypeValue( tn, 1 ) ){ + if( ik==BITVECTOR_UREM_TOTAL ){ + return getTypeValue( tn, 0 ); + } + }else if( n==getTypeMaxValue( tn ) ){ + if( ik==OR || ik==BITVECTOR_OR ){ + return n; + } + }else{ + if( n.getType().isReal() && n.getConst<Rational>().sgn()<0 ){ + // negative arguments + if( ik==STRING_SUBSTR || ik==STRING_CHARAT ){ + return getTypeValue( NodeManager::currentNM()->stringType(), 0 ); + }else if( ik==STRING_STRIDOF ){ + Assert( arg==2 ); + return getTypeValue( NodeManager::currentNM()->integerType(), -1 ); + } + } + } + return Node::null(); +} + +bool TermDbSygus::hasOffsetArg( Kind ik, int arg, int& offset, Kind& ok ) { + if( ik==LT ){ + Assert( arg==0 || arg==1 ); + offset = arg==0 ? 1 : -1; + ok = LEQ; + return true; + }else if( ik==BITVECTOR_ULT ){ + Assert( arg==0 || arg==1 ); + offset = arg==0 ? 1 : -1; + ok = BITVECTOR_ULE; + return true; + }else if( ik==BITVECTOR_SLT ){ + Assert( arg==0 || arg==1 ); + offset = arg==0 ? 1 : -1; + ok = BITVECTOR_SLE; + return true; + } + return false; +} + + + +class ReqTrie { +public: + ReqTrie() : d_req_kind( UNDEFINED_KIND ){} + std::map< unsigned, ReqTrie > d_children; + Kind d_req_kind; + TypeNode d_req_type; + Node d_req_const; + void print( const char * c, int indent = 0 ){ + if( d_req_kind!=UNDEFINED_KIND ){ + Trace(c) << d_req_kind << " "; + }else if( !d_req_type.isNull() ){ + Trace(c) << d_req_type; + }else if( !d_req_const.isNull() ){ + Trace(c) << d_req_const; + }else{ + Trace(c) << "_"; + } + Trace(c) << std::endl; + for( std::map< unsigned, ReqTrie >::iterator it = d_children.begin(); it != d_children.end(); ++it ){ + for( int i=0; i<=indent; i++ ) { Trace(c) << " "; } + Trace(c) << it->first << " : "; + it->second.print( c, indent+1 ); + } + } + bool satisfiedBy( quantifiers::TermDbSygus * tdb, TypeNode tn ){ + if( !d_req_const.isNull() ){ + if( !tdb->hasConst( tn, d_req_const ) ){ + return false; + } + } + if( !d_req_type.isNull() ){ + if( tn!=d_req_type ){ + return false; + } + } + if( d_req_kind!=UNDEFINED_KIND ){ + int c = tdb->getKindConsNum( tn, d_req_kind ); + if( c!=-1 ){ + bool ret = true; + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + for( std::map< unsigned, ReqTrie >::iterator it = d_children.begin(); it != d_children.end(); ++it ){ + if( it->first<dt[c].getNumArgs() ){ + TypeNode tnc = tdb->getArgType( dt[c], it->first ); + if( !it->second.satisfiedBy( tdb, tnc ) ){ + ret = false; + break; + } + }else{ + ret = false; + break; + } + } + if( !ret ){ + return false; + } + // TODO : commutative operators try both? + }else{ + return false; + } + } + return true; + } + bool empty() { + return d_req_kind==UNDEFINED_KIND && d_req_const.isNull() && d_req_type.isNull(); + } +}; + +//this function gets all easy redundant cases, before consulting rewriters +bool TermDbSygus::considerArgKind( TypeNode tn, TypeNode tnp, Kind k, Kind pk, int arg ) { + const Datatype& pdt = ((DatatypeType)(tnp).toType()).getDatatype(); + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + Assert( hasKind( tn, k ) ); + Assert( hasKind( tnp, pk ) ); + Trace("sygus-sb-debug") << "Consider sygus arg kind " << k << ", pk = " << pk << ", arg = " << arg << "?" << std::endl; + int c = getKindConsNum( tn, k ); + int pc = getKindConsNum( tnp, pk ); + if( k==pk ){ + //check for associativity + if( quantifiers::TermDb::isAssoc( k ) ){ + //if the operator is associative, then a repeated occurrence should only occur in the leftmost argument position + int firstArg = getFirstArgOccurrence( pdt[pc], tn ); + Assert( firstArg!=-1 ); + if( arg!=firstArg ){ + Trace("sygus-sb-simple") << " sb-simple : do not consider " << k << " at child arg " << arg << " of " << k << " since it is associative, with first arg = " << firstArg << std::endl; + return false; + }else{ + return true; + } + } + } + //describes the shape of an alternate term to construct + // we check whether this term is in the sygus grammar below + ReqTrie rt; + Assert( rt.empty() ); + + //construct rt by cases + if( pk==NOT || pk==BITVECTOR_NOT || pk==UMINUS || pk==BITVECTOR_NEG ){ + //negation normal form + if( pk==k ){ + rt.d_req_type = getArgType( dt[c], 0 ); + }else{ + Kind reqk = UNDEFINED_KIND; //required kind for all children + std::map< unsigned, Kind > reqkc; //required kind for some children + if( pk==NOT ){ + if( k==AND ) { + rt.d_req_kind = OR;reqk = NOT; + }else if( k==OR ){ + rt.d_req_kind = AND;reqk = NOT; + //AJR : eliminate this if we eliminate xor + }else if( k==EQUAL ) { + rt.d_req_kind = XOR; + }else if( k==XOR ) { + rt.d_req_kind = EQUAL; + }else if( k==ITE ){ + rt.d_req_kind = ITE;reqkc[1] = NOT;reqkc[2] = NOT; + rt.d_children[0].d_req_type = getArgType( dt[c], 0 ); + }else if( k==LEQ || k==GT ){ + // (not (~ x y)) -----> (~ (+ y 1) x) + rt.d_req_kind = k; + rt.d_children[0].d_req_kind = PLUS; + rt.d_children[0].d_children[0].d_req_type = getArgType( dt[c], 1 ); + rt.d_children[0].d_children[1].d_req_const = NodeManager::currentNM()->mkConst( Rational( 1 ) ); + rt.d_children[1].d_req_type = getArgType( dt[c], 0 ); + //TODO: other possibilities? + }else if( k==LT || k==GEQ ){ + // (not (~ x y)) -----> (~ y (+ x 1)) + rt.d_req_kind = k; + rt.d_children[0].d_req_type = getArgType( dt[c], 1 ); + rt.d_children[1].d_req_kind = PLUS; + rt.d_children[1].d_children[0].d_req_type = getArgType( dt[c], 0 ); + rt.d_children[1].d_children[1].d_req_const = NodeManager::currentNM()->mkConst( Rational( 1 ) ); + } + }else if( pk==BITVECTOR_NOT ){ + if( k==BITVECTOR_AND ) { + rt.d_req_kind = BITVECTOR_OR;reqk = BITVECTOR_NOT; + }else if( k==BITVECTOR_OR ){ + rt.d_req_kind = BITVECTOR_AND;reqk = BITVECTOR_NOT; + }else if( k==BITVECTOR_XNOR ) { + rt.d_req_kind = BITVECTOR_XOR; + }else if( k==BITVECTOR_XOR ) { + rt.d_req_kind = BITVECTOR_XNOR; + } + }else if( pk==UMINUS ){ + if( k==PLUS ){ + rt.d_req_kind = PLUS;reqk = UMINUS; + } + }else if( pk==BITVECTOR_NEG ){ + if( k==PLUS ){ + rt.d_req_kind = PLUS;reqk = BITVECTOR_NEG; + } + } + if( !rt.empty() && ( reqk!=UNDEFINED_KIND || !reqkc.empty() ) ){ + int pcr = getKindConsNum( tnp, rt.d_req_kind ); + if( pcr!=-1 ){ + Assert( pcr<(int)pdt.getNumConstructors() ); + //must have same number of arguments + if( pdt[pcr].getNumArgs()==dt[c].getNumArgs() ){ + for( unsigned i=0; i<pdt[pcr].getNumArgs(); i++ ){ + Kind rk = reqk; + if( reqk==UNDEFINED_KIND ){ + std::map< unsigned, Kind >::iterator itr = reqkc.find( i ); + if( itr!=reqkc.end() ){ + rk = itr->second; + } + } + if( rk!=UNDEFINED_KIND ){ + rt.d_children[i].d_req_kind = rk; + rt.d_children[i].d_children[0].d_req_type = getArgType( dt[c], i ); + } + } + } + } + } + } + }else if( k==MINUS || k==BITVECTOR_SUB ){ + if( pk==EQUAL || + pk==MINUS || pk==BITVECTOR_SUB || + pk==LEQ || pk==LT || pk==GEQ || pk==GT ){ + int oarg = arg==0 ? 1 : 0; + // (~ x (- y z)) ----> (~ (+ x z) y) + // (~ (- y z) x) ----> (~ y (+ x z)) + rt.d_req_kind = pk; + rt.d_children[arg].d_req_type = getArgType( dt[c], 0 ); + rt.d_children[oarg].d_req_kind = k==MINUS ? PLUS : BITVECTOR_PLUS; + rt.d_children[oarg].d_children[0].d_req_type = getArgType( pdt[pc], oarg ); + rt.d_children[oarg].d_children[1].d_req_type = getArgType( dt[c], 1 ); + }else if( pk==PLUS || pk==BITVECTOR_PLUS ){ + // (+ x (- y z)) -----> (- (+ x y) z) + // (+ (- y z) x) -----> (- (+ x y) z) + rt.d_req_kind = pk==PLUS ? MINUS : BITVECTOR_SUB; + int oarg = arg==0 ? 1 : 0; + rt.d_children[0].d_req_kind = pk; + rt.d_children[0].d_children[0].d_req_type = getArgType( pdt[pc], oarg ); + rt.d_children[0].d_children[1].d_req_type = getArgType( dt[c], 0 ); + rt.d_children[1].d_req_type = getArgType( dt[c], 1 ); + // TODO : this is subsumbed by solving for MINUS + } + }else if( k==ITE ){ + if( pk!=ITE ){ + // (o X (ite y z w) X') -----> (ite y (o X z X') (o X w X')) + rt.d_req_kind = ITE; + rt.d_children[0].d_req_type = getArgType( dt[c], 0 ); + unsigned n_args = pdt[pc].getNumArgs(); + for( unsigned r=1; r<=2; r++ ){ + rt.d_children[r].d_req_kind = pk; + for( unsigned q=0; q<n_args; q++ ){ + if( (int)q==arg ){ + rt.d_children[r].d_children[q].d_req_type = getArgType( dt[c], r ); + }else{ + rt.d_children[r].d_children[q].d_req_type = getArgType( pdt[pc], q ); + } + } + } + //TODO: this increases term size but is probably a good idea + } + }else if( k==NOT ){ + if( pk==ITE ){ + // (ite (not y) z w) -----> (ite y w z) + rt.d_req_kind = ITE; + rt.d_children[0].d_req_type = getArgType( dt[c], 0 ); + rt.d_children[1].d_req_type = getArgType( pdt[pc], 2 ); + rt.d_children[2].d_req_type = getArgType( pdt[pc], 1 ); + } + } + Trace("sygus-sb-debug") << "Consider sygus arg kind " << k << ", pk = " << pk << ", arg = " << arg << "?" << std::endl; + if( !rt.empty() ){ + rt.print("sygus-sb-debug"); + //check if it meets the requirements + if( rt.satisfiedBy( this, tnp ) ){ + Trace("sygus-sb-debug") << "...success!" << std::endl; + Trace("sygus-sb-simple") << " sb-simple : do not consider " << k << " as arg " << arg << " of " << pk << std::endl; + //do not need to consider the kind in the search since there are ways to construct equivalent terms + return false; + }else{ + Trace("sygus-sb-debug") << "...failed." << std::endl; + } + Trace("sygus-sb-debug") << std::endl; + } + //must consider this kind in the search + return true; +} + +bool TermDbSygus::considerConst( TypeNode tn, TypeNode tnp, Node c, Kind pk, int arg ) { + const Datatype& pdt = ((DatatypeType)(tnp).toType()).getDatatype(); + // child grammar-independent + if( !considerConst( pdt, tnp, c, pk, arg ) ){ + return false; + } + // TODO : this can probably be made child grammar independent + int pc = getKindConsNum( tnp, pk ); + if( pdt[pc].getNumArgs()==2 ){ + Kind ok; + int offset; + if( hasOffsetArg( pk, arg, offset, ok ) ){ + Trace("sygus-sb-simple-debug") << pk << " has offset arg " << ok << " " << offset << std::endl; + int ok_arg = getKindConsNum( tnp, ok ); + if( ok_arg!=-1 ){ + Trace("sygus-sb-simple-debug") << "...at argument " << ok_arg << std::endl; + //other operator be the same type + if( isTypeMatch( pdt[ok_arg], pdt[arg] ) ){ + int status; + Node co = getTypeValueOffset( c.getType(), c, offset, status ); + Trace("sygus-sb-simple-debug") << c << " with offset " << offset << " is " << co << ", status=" << status << std::endl; + if( status==0 && !co.isNull() ){ + if( hasConst( tn, co ) ){ + Trace("sygus-sb-simple") << " sb-simple : by offset reasoning, do not consider const " << c; + Trace("sygus-sb-simple") << " as arg " << arg << " of " << pk << " since we can use " << co << " under " << ok << " " << std::endl; + return false; + } + } + } + } + } + } + return true; +} + +bool TermDbSygus::considerConst( const Datatype& pdt, TypeNode tnp, Node c, Kind pk, int arg ) { + Assert( hasKind( tnp, pk ) ); + int pc = getKindConsNum( tnp, pk ); + bool ret = true; + Trace("sygus-sb-debug") << "Consider sygus const " << c << ", parent = " << pk << ", arg = " << arg << "?" << std::endl; + if( isIdempotentArg( c, pk, arg ) ){ + if( pdt[pc].getNumArgs()==2 ){ + int oarg = arg==0 ? 1 : 0; + TypeNode otn = TypeNode::fromType( ((SelectorType)pdt[pc][oarg].getType()).getRangeType() ); + if( otn==tnp ){ + Trace("sygus-sb-simple") << " sb-simple : " << c << " is idempotent arg " << arg << " of " << pk << "..." << std::endl; + ret = false; + } + } + }else{ + Node sc = isSingularArg( c, pk, arg ); + if( !sc.isNull() ){ + if( hasConst( tnp, sc ) ){ + Trace("sygus-sb-simple") << " sb-simple : " << c << " is singular arg " << arg << " of " << pk << ", evaluating to " << sc << "..." << std::endl; + ret = false; + } + } + } + if( ret ){ + ReqTrie rt; + Assert( rt.empty() ); + Node max_c = getTypeMaxValue( c.getType() ); + Node zero_c = getTypeValue( c.getType(), 0 ); + Node one_c = getTypeValue( c.getType(), 1 ); + if( pk==XOR || pk==BITVECTOR_XOR ){ + if( c==max_c ){ + rt.d_req_kind = pk==XOR ? NOT : BITVECTOR_NOT; + } + }else if( pk==ITE ){ + if( arg==0 ){ + if( c==max_c ){ + rt.d_children[2].d_req_type = tnp; + }else if( c==zero_c ){ + rt.d_children[1].d_req_type = tnp; + } + } + }else if( pk==STRING_SUBSTR ){ + if( c==one_c ){ + rt.d_req_kind = STRING_CHARAT; + rt.d_children[0].d_req_type = getArgType( pdt[pc], 0 ); + rt.d_children[1].d_req_type = getArgType( pdt[pc], 1 ); + } + } + if( !rt.empty() ){ + //check if satisfied + if( rt.satisfiedBy( this, tnp ) ){ + Trace("sygus-sb-simple") << " sb-simple : do not consider const " << c << " as arg " << arg << " of " << pk; + Trace("sygus-sb-simple") << " in " << ((DatatypeType)tnp.toType()).getDatatype().getName() << std::endl; + //do not need to consider the constant in the search since there are ways to construct equivalent terms + ret = false; + } + } + } + // TODO : cache? + return ret; +} + +int TermDbSygus::solveForArgument( TypeNode tn, unsigned cindex, unsigned arg ) { + // FIXME + return -1; // TODO : if using, modify considerArgKind above + Assert( isRegistered( tn ) ); + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + Assert( cindex<dt.getNumConstructors() ); + Assert( arg<dt[cindex].getNumArgs() ); + Kind nk = getConsNumKind( tn, cindex ); + TypeNode tnc = getArgType( dt[cindex], arg ); + const Datatype& cdt = ((DatatypeType)(tnc).toType()).getDatatype(); + + ReqTrie rt; + Assert( rt.empty() ); + int solve_ret = -1; + if( nk==MINUS || nk==BITVECTOR_SUB ){ + if( dt[cindex].getNumArgs()==2 && arg==0 ){ + TypeNode tnco = getArgType( dt[cindex], 1 ); + Node builtin = getTypeValue( sygusToBuiltinType( tnc ), 0 ); + solve_ret = getConstConsNum( tn, builtin ); + if( solve_ret!=-1 ){ + // t - s -----> ( 0 - s ) + t + rt.d_req_kind = MINUS ? PLUS : BITVECTOR_PLUS; + rt.d_children[0].d_req_type = tn; // avoid? + rt.d_children[0].d_req_kind = nk; + rt.d_children[0].d_children[0].d_req_const = builtin; + rt.d_children[0].d_children[0].d_req_type = tnco; + rt.d_children[1].d_req_type = tnc; + // TODO : this can be made more general for multiple type grammars to remove MINUS entirely + } + } + } + + if( !rt.empty() ){ + Assert( solve_ret>=0 ); + Assert( solve_ret<=(int)cdt.getNumConstructors() ); + //check if satisfied + if( rt.satisfiedBy( this, tn ) ){ + Trace("sygus-sb-simple") << " sb-simple : ONLY consider " << cdt[solve_ret].getSygusOp() << " as arg " << arg << " of " << nk; + Trace("sygus-sb-simple") << " in " << ((DatatypeType)tn.toType()).getDatatype().getName() << std::endl; + return solve_ret; + } + } + + return -1; +} + +Node TermDbSygus::getTypeValue( TypeNode tn, int val ) { + std::map< int, Node >::iterator it = d_type_value[tn].find( val ); + if( it==d_type_value[tn].end() ){ + Node n; + if( tn.isInteger() || tn.isReal() ){ + Rational c(val); + n = NodeManager::currentNM()->mkConst( c ); + }else if( tn.isBitVector() ){ + unsigned int uv = val; + BitVector bval(tn.getConst<BitVectorSize>(), uv); + n = NodeManager::currentNM()->mkConst<BitVector>(bval); + }else if( tn.isBoolean() ){ + if( val==0 ){ + n = d_false; + } + }else if( tn.isString() ){ + if( val==0 ){ + n = NodeManager::currentNM()->mkConst( ::CVC4::String("") ); + } + } + d_type_value[tn][val] = n; + return n; + }else{ + return it->second; + } +} + +Node TermDbSygus::getTypeMaxValue( TypeNode tn ) { + std::map< TypeNode, Node >::iterator it = d_type_max_value.find( tn ); + if( it==d_type_max_value.end() ){ + Node n; + if( tn.isBitVector() ){ + n = bv::utils::mkOnes(tn.getConst<BitVectorSize>()); + }else if( tn.isBoolean() ){ + n = d_true; + } + d_type_max_value[tn] = n; + return n; + }else{ + return it->second; + } +} + +Node TermDbSygus::getTypeValueOffset( TypeNode tn, Node val, int offset, int& status ) { + std::map< int, Node >::iterator it = d_type_value_offset[tn][val].find( offset ); + if( it==d_type_value_offset[tn][val].end() ){ + Node val_o; + Node offset_val = getTypeValue( tn, offset ); + status = -1; + if( !offset_val.isNull() ){ + if( tn.isInteger() || tn.isReal() ){ + val_o = Rewriter::rewrite( NodeManager::currentNM()->mkNode( PLUS, val, offset_val ) ); + status = 0; + }else if( tn.isBitVector() ){ + val_o = Rewriter::rewrite( NodeManager::currentNM()->mkNode( BITVECTOR_PLUS, val, offset_val ) ); + // TODO : enable? watch for overflows + } + } + d_type_value_offset[tn][val][offset] = val_o; + d_type_value_offset_status[tn][val][offset] = status; + return val_o; + }else{ + status = d_type_value_offset_status[tn][val][offset]; + return it->second; + } +} + +struct sortConstants { + TermDbSygus * d_tds; + Kind d_comp_kind; + bool operator() (Node i, Node j) { + if( i!=j ){ + return d_tds->doCompare( i, j, d_comp_kind ); + }else{ + return false; + } + } +}; + +class ReconstructTrie { +public: + std::map< Node, ReconstructTrie > d_children; + std::vector< Node > d_reconstruct; + void add( std::vector< Node >& cons, Node r, unsigned index = 0 ){ + if( index==cons.size() ){ + d_reconstruct.push_back( r ); + }else{ + d_children[cons[index]].add( cons, r, index+1 ); + } + } + Node getReconstruct( std::map< Node, int >& rcons, unsigned depth ) { + if( !d_reconstruct.empty() ){ + for( unsigned i=0; i<d_reconstruct.size(); i++ ){ + Node r = d_reconstruct[i]; + if( rcons[r]==0 ){ + Trace("sygus-static-enum") << "...eliminate constructor " << r << std::endl; + rcons[r] = 1; + return r; + } + } + } + if( depth>0 ){ + for( unsigned w=0; w<2; w++ ){ + for( std::map< Node, ReconstructTrie >::iterator it = d_children.begin(); it != d_children.end(); ++it ){ + Node n = it->first; + if( ( w==0 && rcons[n]!=0 ) || ( w==1 && rcons[n]==0 ) ){ + Node r = it->second.getReconstruct( rcons, depth - w ); + if( !r.isNull() ){ + if( w==1 ){ + Trace("sygus-static-enum") << "...use " << n << " to eliminate constructor " << r << std::endl; + rcons[n] = -1; + } + return r; + } + } + } + } + } + return Node::null(); + } +}; + +void TermDbSygus::registerSygusType( TypeNode tn ) { + std::map< TypeNode, TypeNode >::iterator itr = d_register.find( tn ); + if( itr==d_register.end() ){ + d_register[tn] = TypeNode::null(); + if( tn.isDatatype() ){ + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + Trace("sygus-db") << "Register type " << dt.getName() << "..." << std::endl; + TypeNode btn = TypeNode::fromType( dt.getSygusType() ); + d_register[tn] = btn; + if( !d_register[tn].isNull() ){ + // get the sygus variable list + Node var_list = Node::fromExpr( dt.getSygusVarList() ); + if( !var_list.isNull() ){ + for( unsigned j=0; j<var_list.getNumChildren(); j++ ){ + Node sv = var_list[j]; + SygusVarNumAttribute svna; + sv.setAttribute( svna, j ); + d_var_list[tn].push_back( sv ); + } + }else{ + // no arguments to synthesis functions + } + //for constant reconstruction + Kind ck = getComparisonKind( TypeNode::fromType( dt.getSygusType() ) ); + Node z = getTypeValue( TypeNode::fromType( dt.getSygusType() ), 0 ); + d_const_list_pos[tn] = 0; + //iterate over constructors + for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ + Expr sop = dt[i].getSygusOp(); + Assert( !sop.isNull() ); + Node n = Node::fromExpr( sop ); + Trace("sygus-db") << " Operator #" << i << " : " << sop; + if( sop.getKind() == kind::BUILTIN ){ + Kind sk = NodeManager::operatorToKind( n ); + Trace("sygus-db") << ", kind = " << sk; + d_kinds[tn][sk] = i; + d_arg_kind[tn][i] = sk; + }else if( sop.isConst() ){ + Trace("sygus-db") << ", constant"; + d_consts[tn][n] = i; + d_arg_const[tn][i] = n; + d_const_list[tn].push_back( n ); + if( ck!=UNDEFINED_KIND && doCompare( z, n, ck ) ){ + d_const_list_pos[tn]++; + } + } + if( dt[i].isSygusIdFunc() ){ + d_id_funcs[tn].push_back( i ); + } + d_ops[tn][n] = i; + d_arg_ops[tn][i] = n; + Trace("sygus-db") << std::endl; + } + //sort the constant list + if( !d_const_list[tn].empty() ){ + if( ck!=UNDEFINED_KIND ){ + sortConstants sc; + sc.d_comp_kind = ck; + sc.d_tds = this; + std::sort( d_const_list[tn].begin(), d_const_list[tn].end(), sc ); + } + Trace("sygus-db") << "Type has " << d_const_list[tn].size() << " constants..." << std::endl << " "; + for( unsigned i=0; i<d_const_list[tn].size(); i++ ){ + Trace("sygus-db") << d_const_list[tn][i] << " "; + } + Trace("sygus-db") << std::endl; + Trace("sygus-db") << "Of these, " << d_const_list_pos[tn] << " are marked as positive." << std::endl; + } + //register connected types + for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ + for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){ + registerSygusType( getArgType( dt[i], j ) ); + } + } + + //compute the redundant operators + if( options::sygusMinGrammar() ){ + for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ + bool nred = true; + Trace("sygus-split-debug") << "Is " << dt[i].getName() << " a redundant operator?" << std::endl; + Kind ck = getConsNumKind( tn, i ); + if( ck!=UNDEFINED_KIND ){ + Kind dk; + if( isAntisymmetric( ck, dk ) ){ + int j = getKindConsNum( tn, dk ); + if( j!=-1 ){ + Trace("sygus-split-debug") << "Possible redundant operator : " << ck << " with " << dk << std::endl; + //check for type mismatches + bool success = true; + for( unsigned k=0; k<2; k++ ){ + unsigned ko = k==0 ? 1 : 0; + TypeNode tni = TypeNode::fromType( ((SelectorType)dt[i][k].getType()).getRangeType() ); + TypeNode tnj = TypeNode::fromType( ((SelectorType)dt[j][ko].getType()).getRangeType() ); + if( tni!=tnj ){ + Trace("sygus-split-debug") << "Argument types " << tni << " and " << tnj << " are not equal." << std::endl; + success = false; + break; + } + } + if( success ){ + Trace("sygus-nf") << "* Sygus norm " << dt.getName() << " : do not consider any " << ck << " terms." << std::endl; + nred = false; + } + } + } + } + if( nred ){ + Trace("sygus-split-debug") << "Check " << dt[i].getName() << " based on generic rewriting" << std::endl; + std::map< TypeNode, int > var_count; + std::map< int, Node > pre; + Node g = mkGeneric( dt, i, var_count, pre ); + nred = !computeGenericRedundant( tn, g ); + Trace("sygus-split-debug") << "...done check " << dt[i].getName() << " based on generic rewriting" << std::endl; + } + d_sygus_red_status[tn].push_back( nred ? 0 : 1 ); + } + // run an enumerator for this type + if( options::sygusMinGrammarAgg() ){ + TypeEnumerator te(tn); + unsigned count = 0; + std::map< Node, std::vector< Node > > builtin_to_orig; + Trace("sygus-static-enum") << "Static enumerate " << dt.getName() << "..." << std::endl; + while( !te.isFinished() && count<1000 ){ + Node n = *te; + Node bn = sygusToBuiltin( n, tn ); + Trace("sygus-static-enum") << " " << bn; + Node bnr = Rewriter::rewrite( bn ); + Trace("sygus-static-enum") << " ..." << bnr << std::endl; + builtin_to_orig[bnr].push_back( n ); + ++te; + count++; + } + std::map< Node, bool > reserved; + for( unsigned i=0; i<=2; i++ ){ + Node rsv = i==2 ? getTypeMaxValue( btn ) : getTypeValue( btn, i ); + if( !rsv.isNull() ){ + reserved[ rsv ] = true; + } + } + Trace("sygus-static-enum") << "...make the reconstruct index data structure..." << std::endl; + ReconstructTrie rt; + std::map< Node, int > rcons; + unsigned max_depth = 0; + for( std::map< Node, std::vector< Node > >::iterator itb = builtin_to_orig.begin(); itb != builtin_to_orig.end(); ++itb ){ + if( itb->second.size()>0 ){ + std::map< Node, std::vector< Node > > clist; + Node single_cons; + for( unsigned j=0; j<itb->second.size(); j++ ){ + Node e = itb->second[j]; + getSygusConstructors( e, clist[e] ); + if( clist[e].size()>max_depth ){ + max_depth = clist[e].size(); + } + for( unsigned k=0; k<clist[e].size(); k++ ){ + /* + unsigned cindex = Datatype::indexOf( clist[e][k].toExpr() ); + if( isGenericRedundant( tn, cindex ) ){ + is_gen_redundant = true; + break; + }else{ + */ + rcons[clist[e][k]] = 0; + } + //if( is_gen_redundant ){ + // clist.erase( e ); + //}else{ + if( clist[e].size()==1 ){ + Trace("sygus-static-enum") << "...single constructor term : " << e << ", builtin is " << itb->first << ", cons is " << clist[e][0] << std::endl; + if( single_cons.isNull() ){ + single_cons = clist[e][0]; + }else{ + Trace("sygus-static-enum") << "*** already can eliminate constructor " << clist[e][0] << std::endl; + unsigned cindex = Datatype::indexOf( clist[e][0].toExpr() ); + d_sygus_red_status[tn][cindex] = 1; + } + } + //} + } + // do not eliminate 0, 1, or max + if( !single_cons.isNull() && reserved.find( itb->first )==reserved.end() ){ + Trace("sygus-static-enum") << "...possibly elim " << single_cons << std::endl; + for( std::map< Node, std::vector< Node > >::iterator itc = clist.begin(); itc != clist.end(); ++itc ){ + if( std::find( itc->second.begin(), itc->second.end(), single_cons )==itc->second.end() ){ + rt.add( itc->second, single_cons ); + } + } + } + } + } + Trace("sygus-static-enum") << "...compute reconstructions..." << std::endl; + Node next_rcons; + do { + unsigned depth = 0; + do{ + next_rcons = rt.getReconstruct( rcons, depth ); + depth++; + }while( next_rcons.isNull() && depth<=max_depth ); + // if we found a constructor to eliminate + if( !next_rcons.isNull() ){ + Trace("sygus-static-enum") << "*** eliminate constructor " << next_rcons << std::endl; + unsigned cindex = Datatype::indexOf( next_rcons.toExpr() ); + d_sygus_red_status[tn][cindex] = 2; + } + }while( !next_rcons.isNull() ); + Trace("sygus-static-enum") << "...finished..." << std::endl; + } + }else{ + // assume all are non-redundant + for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ + d_sygus_red_status[tn].push_back( 0 ); + } + } + } + } + } +} + +void TermDbSygus::registerMeasuredTerm( Node e, Node root, bool mkActiveGuard ) { + Assert( d_measured_term.find( e )==d_measured_term.end() ); + Trace("sygus-db") << "Register measured term : " << e << " with root " << root << std::endl; + d_measured_term[e] = root; + if( mkActiveGuard ){ + // make the guard + Node eg = Rewriter::rewrite( NodeManager::currentNM()->mkSkolem( "eG", NodeManager::currentNM()->booleanType() ) ); + eg = d_quantEngine->getValuation().ensureLiteral( eg ); + AlwaysAssert( !eg.isNull() ); + d_quantEngine->getOutputChannel().requirePhase( eg, true ); + //add immediate lemma + Node lem = NodeManager::currentNM()->mkNode( OR, eg, eg.negate() ); + Trace("cegqi-lemma") << "Cegqi::Lemma : enumerator : " << lem << std::endl; + d_quantEngine->getOutputChannel().lemma( lem ); + d_measured_term_active_guard[e] = eg; + } +} + +void TermDbSygus::registerPbeExamples( Node e, std::vector< std::vector< Node > >& exs, + std::vector< Node >& exos, std::vector< Node >& exts ) { + Trace("sygus-db") << "Register " << exs.size() << " PBE examples with " << e << std::endl; + Assert( d_measured_term.find( e )==d_measured_term.end() || isMeasuredTerm( e )==e ); + Assert( d_pbe_exs.find( e )==d_pbe_exs.end() ); + Assert( exs.size()==exos.size() ); + d_pbe_exs[e] = exs; + d_pbe_exos[e] = exos; + for( unsigned i=0; i<exts.size(); i++ ){ + Trace("sygus-db-debug") << " # " << i << " : " << exts[i] << std::endl; + Assert( exts[i].getKind()==APPLY_UF ); + Assert( exts[i][0]==e ); + d_pbe_term_id[exts[i]] = i; + } +} + +Node TermDbSygus::isMeasuredTerm( Node e ) { + std::map< Node, Node >::iterator itm = d_measured_term.find( e ); + if( itm!=d_measured_term.end() ){ + return itm->second; + }else{ + return Node::null(); + } +} + +Node TermDbSygus::getActiveGuardForMeasureTerm( Node e ) { + std::map< Node, Node >::iterator itag = d_measured_term_active_guard.find( e ); + if( itag!=d_measured_term_active_guard.end() ){ + return itag->second; + }else{ + return Node::null(); + } +} + +void TermDbSygus::getMeasuredTerms( std::vector< Node >& mts ) { + for( std::map< Node, Node >::iterator itm = d_measured_term.begin(); itm != d_measured_term.end(); ++itm ){ + mts.push_back( itm->first ); + } +} + +bool TermDbSygus::hasPbeExamples( Node e ) { + return d_pbe_exs.find( e )!=d_pbe_exs.end(); +} + +unsigned TermDbSygus::getNumPbeExamples( Node e ) { + std::map< Node, std::vector< std::vector< Node > > >::iterator it = d_pbe_exs.find( e ); + if( it!=d_pbe_exs.end() ){ + return it->second.size(); + }else{ + return 0; + } +} + +void TermDbSygus::getPbeExample( Node e, unsigned i, std::vector< Node >& ex ) { + std::map< Node, std::vector< std::vector< Node > > >::iterator it = d_pbe_exs.find( e ); + if( it!=d_pbe_exs.end() ){ + Assert( i<it->second.size() ); + Assert( i<d_pbe_exos[e].size() ); + ex.insert( ex.end(), it->second[i].begin(), it->second[i].end() ); + }else{ + Assert( false ); + } +} +Node TermDbSygus::getPbeExampleOut( Node e, unsigned i ) { + std::map< Node, std::vector< Node > >::iterator it = d_pbe_exos.find( e ); + if( it!=d_pbe_exos.end() ){ + Assert( i<it->second.size() ); + return it->second[i]; + }else{ + Assert( false ); + return Node::null(); + } +} + +int TermDbSygus::getPbeExampleId( Node n ) { + std::map< Node, unsigned >::iterator it = d_pbe_term_id.find( n ); + if( it!=d_pbe_term_id.end() ){ + return it->second; + }else{ + return -1; + } +} + +bool TermDbSygus::isRegistered( TypeNode tn ) { + return d_register.find( tn )!=d_register.end(); +} + +TypeNode TermDbSygus::sygusToBuiltinType( TypeNode tn ) { + Assert( isRegistered( tn ) ); + return d_register[tn]; +} + +void TermDbSygus::computeMinTypeDepthInternal( TypeNode root_tn, TypeNode tn, unsigned type_depth ) { + std::map< TypeNode, unsigned >::iterator it = d_min_type_depth[root_tn].find( tn ); + if( it==d_min_type_depth[root_tn].end() || type_depth<it->second ){ + d_min_type_depth[root_tn][tn] = type_depth; + Assert( tn.isDatatype() ); + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + //compute for connected types + for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ + for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){ + computeMinTypeDepthInternal( root_tn, getArgType( dt[i], j ), type_depth+1 ); + } + } + } +} + +unsigned TermDbSygus::getMinTypeDepth( TypeNode root_tn, TypeNode tn ){ + std::map< TypeNode, unsigned >::iterator it = d_min_type_depth[root_tn].find( tn ); + if( it==d_min_type_depth[root_tn].end() ){ + computeMinTypeDepthInternal( root_tn, root_tn, 0 ); + Assert( d_min_type_depth[root_tn].find( tn )!=d_min_type_depth[root_tn].end() ); + return d_min_type_depth[root_tn][tn]; + }else{ + return it->second; + } +} + +unsigned TermDbSygus::getMinTermSize( TypeNode tn ) { + Assert( isRegistered( tn ) ); + std::map< TypeNode, unsigned >::iterator it = d_min_term_size.find( tn ); + if( it==d_min_term_size.end() ){ + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ + if( !isGenericRedundant( tn, i ) ){ + if( dt[i].getNumArgs()==0 ){ + d_min_term_size[tn] = 0; + return 0; + } + } + } + // TODO : improve + d_min_term_size[tn] = 1; + return 1; + }else{ + return it->second; + } +} + +unsigned TermDbSygus::getMinConsTermSize( TypeNode tn, unsigned cindex ) { + Assert( isRegistered( tn ) ); + Assert( !isGenericRedundant( tn, cindex ) ); + std::map< unsigned, unsigned >::iterator it = d_min_cons_term_size[tn].find( cindex ); + if( it==d_min_cons_term_size[tn].end() ){ + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + Assert( cindex<dt.getNumConstructors() ); + unsigned ret = 0; + if( dt[cindex].getNumArgs()>0 ){ + ret = 1; + for( unsigned i=0; i<dt[cindex].getNumArgs(); i++ ){ + ret += getMinTermSize( getArgType( dt[cindex], i ) ); + } + } + d_min_cons_term_size[tn][cindex] = ret; + return ret; + }else{ + return it->second; + } +} + + +int TermDbSygus::getKindConsNum( TypeNode tn, Kind k ) { + Assert( isRegistered( tn ) ); + std::map< TypeNode, std::map< Kind, int > >::iterator itt = d_kinds.find( tn ); + if( itt!=d_kinds.end() ){ + std::map< Kind, int >::iterator it = itt->second.find( k ); + if( it!=itt->second.end() ){ + return it->second; + } + } + return -1; +} + +int TermDbSygus::getConstConsNum( TypeNode tn, Node n ){ + Assert( isRegistered( tn ) ); + std::map< TypeNode, std::map< Node, int > >::iterator itt = d_consts.find( tn ); + if( itt!=d_consts.end() ){ + std::map< Node, int >::iterator it = itt->second.find( n ); + if( it!=itt->second.end() ){ + return it->second; + } + } + return -1; +} + +int TermDbSygus::getOpConsNum( TypeNode tn, Node n ) { + std::map< Node, int >::iterator it = d_ops[tn].find( n ); + if( it!=d_ops[tn].end() ){ + return it->second; + }else{ + return -1; + } +} + +bool TermDbSygus::hasKind( TypeNode tn, Kind k ) { + return getKindConsNum( tn, k )!=-1; +} +bool TermDbSygus::hasConst( TypeNode tn, Node n ) { + return getConstConsNum( tn, n )!=-1; +} +bool TermDbSygus::hasOp( TypeNode tn, Node n ) { + return getOpConsNum( tn, n )!=-1; +} + +Node TermDbSygus::getConsNumOp( TypeNode tn, int i ) { + Assert( isRegistered( tn ) ); + std::map< TypeNode, std::map< int, Node > >::iterator itt = d_arg_ops.find( tn ); + if( itt!=d_arg_ops.end() ){ + std::map< int, Node >::iterator itn = itt->second.find( i ); + if( itn!=itt->second.end() ){ + return itn->second; + } + } + return Node::null(); +} + +Node TermDbSygus::getConsNumConst( TypeNode tn, int i ) { + Assert( isRegistered( tn ) ); + std::map< TypeNode, std::map< int, Node > >::iterator itt = d_arg_const.find( tn ); + if( itt!=d_arg_const.end() ){ + std::map< int, Node >::iterator itn = itt->second.find( i ); + if( itn!=itt->second.end() ){ + return itn->second; + } + } + return Node::null(); +} + +Kind TermDbSygus::getConsNumKind( TypeNode tn, int i ) { + Assert( isRegistered( tn ) ); + std::map< TypeNode, std::map< int, Kind > >::iterator itt = d_arg_kind.find( tn ); + if( itt!=d_arg_kind.end() ){ + std::map< int, Kind >::iterator itk = itt->second.find( i ); + if( itk!=itt->second.end() ){ + return itk->second; + } + } + return UNDEFINED_KIND; +} + +bool TermDbSygus::isKindArg( TypeNode tn, int i ) { + return getConsNumKind( tn, i )!=UNDEFINED_KIND; +} + +bool TermDbSygus::isConstArg( TypeNode tn, int i ) { + Assert( isRegistered( tn ) ); + std::map< TypeNode, std::map< int, Node > >::iterator itt = d_arg_const.find( tn ); + if( itt!=d_arg_const.end() ){ + return itt->second.find( i )!=itt->second.end(); + }else{ + return false; + } +} + +unsigned TermDbSygus::getNumIdFuncs( TypeNode tn ) { + return d_id_funcs[tn].size(); +} + +unsigned TermDbSygus::getIdFuncIndex( TypeNode tn, unsigned i ) { + return d_id_funcs[tn][i]; +} + +TypeNode TermDbSygus::getArgType( const DatatypeConstructor& c, int i ) { + Assert( i>=0 && i<(int)c.getNumArgs() ); + return TypeNode::fromType( ((SelectorType)c[i].getType()).getRangeType() ); +} + +/** get first occurrence */ +int TermDbSygus::getFirstArgOccurrence( const DatatypeConstructor& c, TypeNode tn ) { + for( unsigned i=0; i<c.getNumArgs(); i++ ){ + TypeNode tni = getArgType( c, i ); + if( tni==tn ){ + return i; + } + } + return -1; +} + +bool TermDbSygus::isTypeMatch( const DatatypeConstructor& c1, const DatatypeConstructor& c2 ) { + if( c1.getNumArgs()!=c2.getNumArgs() ){ + return false; + }else{ + for( unsigned i=0; i<c1.getNumArgs(); i++ ){ + if( getArgType( c1, i )!=getArgType( c2, i ) ){ + return false; + } + } + return true; + } +} + +Node TermDbSygus::minimizeBuiltinTerm( Node n ) { + if( ( n.getKind()==EQUAL || n.getKind()==LEQ || n.getKind()==LT || n.getKind()==GEQ || n.getKind()==GT ) && + ( n[0].getType().isInteger() || n[0].getType().isReal() ) ){ + bool changed = false; + std::vector< Node > mon[2]; + for( unsigned r=0; r<2; r++ ){ + unsigned ro = r==0 ? 1 : 0; + Node c; + Node nc; + if( n[r].getKind()==PLUS ){ + for( unsigned i=0; i<n[r].getNumChildren(); i++ ){ + if( QuantArith::getMonomial( n[r][i], c, nc ) && c.getConst<Rational>().isNegativeOne() ){ + mon[ro].push_back( nc ); + changed = true; + }else{ + if( !n[r][i].isConst() || !n[r][i].getConst<Rational>().isZero() ){ + mon[r].push_back( n[r][i] ); + } + } + } + }else{ + if( QuantArith::getMonomial( n[r], c, nc ) && c.getConst<Rational>().isNegativeOne() ){ + mon[ro].push_back( nc ); + changed = true; + }else{ + if( !n[r].isConst() || !n[r].getConst<Rational>().isZero() ){ + mon[r].push_back( n[r] ); + } + } + } + } + if( changed ){ + Node nn[2]; + for( unsigned r=0; r<2; r++ ){ + nn[r] = mon[r].size()==0 ? NodeManager::currentNM()->mkConst( Rational(0) ) : ( mon[r].size()==1 ? mon[r][0] : NodeManager::currentNM()->mkNode( PLUS, mon[r] ) ); + } + return NodeManager::currentNM()->mkNode( n.getKind(), nn[0], nn[1] ); + } + } + return n; +} + +Node TermDbSygus::expandBuiltinTerm( Node t ){ + if( t.getKind()==EQUAL ){ + if( t[0].getType().isReal() ){ + return NodeManager::currentNM()->mkNode( AND, NodeManager::currentNM()->mkNode( LEQ, t[0], t[1] ), + NodeManager::currentNM()->mkNode( LEQ, t[1], t[0] ) ); + }else if( t[0].getType().isBoolean() ){ + return NodeManager::currentNM()->mkNode( OR, NodeManager::currentNM()->mkNode( AND, t[0], t[1] ), + NodeManager::currentNM()->mkNode( AND, t[0].negate(), t[1].negate() ) ); + } + }else if( t.getKind()==ITE && t.getType().isBoolean() ){ + return NodeManager::currentNM()->mkNode( OR, NodeManager::currentNM()->mkNode( AND, t[0], t[1] ), + NodeManager::currentNM()->mkNode( AND, t[0].negate(), t[2] ) ); + } + return Node::null(); +} + + +Kind TermDbSygus::getComparisonKind( TypeNode tn ) { + if( tn.isInteger() || tn.isReal() ){ + return LT; + }else if( tn.isBitVector() ){ + return BITVECTOR_ULT; + }else{ + return UNDEFINED_KIND; + } +} + +Kind TermDbSygus::getPlusKind( TypeNode tn, bool is_neg ) { + if( tn.isInteger() || tn.isReal() ){ + return is_neg ? MINUS : PLUS; + }else if( tn.isBitVector() ){ + return is_neg ? BITVECTOR_SUB : BITVECTOR_PLUS; + }else{ + return UNDEFINED_KIND; + } +} + +bool TermDbSygus::doCompare( Node a, Node b, Kind k ) { + Node com = NodeManager::currentNM()->mkNode( k, a, b ); + com = Rewriter::rewrite( com ); + return com==d_true; +} + +Node TermDbSygus::getSemanticSkolem( TypeNode tn, Node n, bool doMk ){ + std::map< Node, Node >::iterator its = d_semantic_skolem[tn].find( n ); + if( its!=d_semantic_skolem[tn].end() ){ + return its->second; + }else if( doMk ){ + Node ss = NodeManager::currentNM()->mkSkolem( "sem", tn, "semantic skolem for sygus" ); + d_semantic_skolem[tn][n] = ss; + return ss; + }else{ + return Node::null(); + } +} + +bool TermDbSygus::involvesDivByZero( Node n, std::map< Node, bool >& visited ){ + if( visited.find( n )==visited.end() ){ + visited[n] = true; + Kind k = n.getKind(); + if( k==DIVISION || k==DIVISION_TOTAL || k==INTS_DIVISION || k==INTS_DIVISION_TOTAL || + k==INTS_MODULUS || k==INTS_MODULUS_TOTAL ){ + if( n[1].isConst() ){ + if( n[1]==getTypeValue( n[1].getType(), 0 ) ){ + return true; + } + }else{ + // if it has free variables it might be a non-zero constant + if( !hasFreeVar( n[1] ) ){ + return true; + } + } + } + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + if( involvesDivByZero( n[i], visited ) ){ + return true; + } + } + } + return false; +} + +bool TermDbSygus::involvesDivByZero( Node n ) { + std::map< Node, bool > visited; + return involvesDivByZero( n, visited ); +} + +void doStrReplace(std::string& str, const std::string& oldStr, const std::string& newStr){ + size_t pos = 0; + while((pos = str.find(oldStr, pos)) != std::string::npos){ + str.replace(pos, oldStr.length(), newStr); + pos += newStr.length(); + } +} + +Kind TermDbSygus::getOperatorKind( Node op ) { + Assert( op.getKind()!=BUILTIN ); + if( smt::currentSmtEngine()->isDefinedFunction( op.toExpr() ) ){ + return APPLY; + }else{ + TypeNode tn = op.getType(); + if( tn.isConstructor() ){ + return APPLY_CONSTRUCTOR; + }else if( tn.isSelector() ){ + return APPLY_SELECTOR; + }else if( tn.isTester() ){ + return APPLY_TESTER; + }else{ + return NodeManager::operatorToKind( op ); + } + } +} + +void TermDbSygus::printSygusTerm( std::ostream& out, Node n, std::vector< Node >& lvs ) { + if( n.getKind()==APPLY_CONSTRUCTOR ){ + TypeNode tn = n.getType(); + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + if( dt.isSygus() ){ + int cIndex = Datatype::indexOf( n.getOperator().toExpr() ); + Assert( !dt[cIndex].getSygusOp().isNull() ); + if( dt[cIndex].getSygusLetBody().isNull() ){ + if( n.getNumChildren()>0 ){ + out << "("; + } + Node op = dt[cIndex].getSygusOp(); + if( op.getType().isBitVector() && op.isConst() ){ + //print in the style it was given + Trace("sygus-print-bvc") << "[Print " << op << " " << dt[cIndex].getName() << "]" << std::endl; + std::stringstream ss; + ss << dt[cIndex].getName(); + std::string str = ss.str(); + std::size_t found = str.find_last_of("_"); + Assert( found!=std::string::npos ); + std::string name = std::string( str.begin() + found +1, str.end() ); + out << name; + }else{ + out << op; + } + if( n.getNumChildren()>0 ){ + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + out << " "; + printSygusTerm( out, n[i], lvs ); + } + out << ")"; + } + }else{ + std::stringstream let_out; + //print as let term + if( dt[cIndex].getNumSygusLetInputArgs()>0 ){ + let_out << "(let ("; + } + std::vector< Node > subs_lvs; + std::vector< Node > new_lvs; + for( unsigned i=0; i<dt[cIndex].getNumSygusLetArgs(); i++ ){ + Node v = Node::fromExpr( dt[cIndex].getSygusLetArg( i ) ); + subs_lvs.push_back( v ); + std::stringstream ss; + ss << "_l_" << new_lvs.size(); + Node lv = NodeManager::currentNM()->mkBoundVar( ss.str(), v.getType() ); + new_lvs.push_back( lv ); + //map free variables to proper terms + if( i<dt[cIndex].getNumSygusLetInputArgs() ){ + //it should be printed as a let argument + let_out << "("; + let_out << lv << " " << lv.getType() << " "; + printSygusTerm( let_out, n[i], lvs ); + let_out << ")"; + } + } + if( dt[cIndex].getNumSygusLetInputArgs()>0 ){ + let_out << ") "; + } + //print the body + Node let_body = Node::fromExpr( dt[cIndex].getSygusLetBody() ); + let_body = let_body.substitute( subs_lvs.begin(), subs_lvs.end(), new_lvs.begin(), new_lvs.end() ); + new_lvs.insert( new_lvs.end(), lvs.begin(), lvs.end() ); + printSygusTerm( let_out, let_body, new_lvs ); + if( dt[cIndex].getNumSygusLetInputArgs()>0 ){ + let_out << ")"; + } + //do variable substitutions since ASSUMING : let_vars are interpreted literally and do not represent a class of variables + std::string lbody = let_out.str(); + for( unsigned i=0; i<dt[cIndex].getNumSygusLetArgs(); i++ ){ + std::stringstream old_str; + old_str << new_lvs[i]; + std::stringstream new_str; + if( i>=dt[cIndex].getNumSygusLetInputArgs() ){ + printSygusTerm( new_str, n[i], lvs ); + }else{ + new_str << Node::fromExpr( dt[cIndex].getSygusLetArg( i ) ); + } + doStrReplace( lbody, old_str.str().c_str(), new_str.str().c_str() ); + } + out << lbody; + } + return; + } + }else if( !n.getAttribute(SygusProxyAttribute()).isNull() ){ + out << n.getAttribute(SygusProxyAttribute()); + }else{ + out << n; + } +} + +Node TermDbSygus::getAnchor( Node n ) { + if( n.getKind()==APPLY_SELECTOR_TOTAL ){ + return getAnchor( n[0] ); + }else{ + return n; + } +} + +unsigned TermDbSygus::getAnchorDepth( Node n ) { + if( n.getKind()==APPLY_SELECTOR_TOTAL ){ + return 1+getAnchorDepth( n[0] ); + }else{ + return 0; + } +} + + +void TermDbSygus::registerEvalTerm( Node n ) { + if( options::sygusDirectEval() ){ + if( n.getKind()==APPLY_UF && !n.getType().isBoolean() ){ + Trace("sygus-eager") << "TermDbSygus::eager: Register eval term : " << n << std::endl; + TypeNode tn = n[0].getType(); + if( tn.isDatatype() ){ + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + if( dt.isSygus() ){ + Node f = n.getOperator(); + Trace("sygus-eager") << "...the evaluation function is : " << f << std::endl; + if( n[0].getKind()!=APPLY_CONSTRUCTOR ){ + // check if it directly occurs in an input/ouput example + int pbe_id = getPbeExampleId( n ); + if( pbe_id!=-1 ){ + Node n_res = getPbeExampleOut( n[0], pbe_id ); + if( !n_res.isNull() ){ + Trace("sygus-eager") << "......do not evaluate " << n << " since it is an input/output example : " << n_res << std::endl; + return; + } + } + d_evals[n[0]].push_back( n ); + TypeNode tn = n[0].getType(); + Assert( tn.isDatatype() ); + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + Node var_list = Node::fromExpr( dt.getSygusVarList() ); + Assert( dt.isSygus() ); + d_eval_args[n[0]].push_back( std::vector< Node >() ); + bool isConst = true; + for( unsigned j=1; j<n.getNumChildren(); j++ ){ + d_eval_args[n[0]].back().push_back( n[j] ); + if( !n[j].isConst() ){ + isConst = false; + } + } + d_eval_args_const[n[0]].push_back( isConst ); + Node a = getAnchor( n[0] ); + d_subterms[a][n[0]] = true; + } + } + } + } + } +} + +void TermDbSygus::registerModelValue( Node a, Node v, std::vector< Node >& terms, std::vector< Node >& vals, std::vector< Node >& exps ) { + std::map< Node, std::map< Node, bool > >::iterator its = d_subterms.find( a ); + if( its!=d_subterms.end() ){ + Trace("sygus-eager") << "registerModelValue : " << a << ", has " << its->second.size() << " registered subterms." << std::endl; + for( std::map< Node, bool >::iterator itss = its->second.begin(); itss != its->second.end(); ++itss ){ + Node n = itss->first; + Trace("sygus-eager-debug") << "...process : " << n << std::endl; + std::map< Node, std::vector< std::vector< Node > > >::iterator it = d_eval_args.find( n ); + if( it!=d_eval_args.end() && !it->second.empty() ){ + TNode at = a; + TNode vt = v; + Node vn = n.substitute( at, vt ); + vn = Rewriter::rewrite( vn ); + unsigned start = d_node_mv_args_proc[n][vn]; + // get explanation in terms of testers + std::vector< Node > antec_exp; + getExplanationForConstantEquality( n, vn, antec_exp ); + Node antec = antec_exp.size()==1 ? antec_exp[0] : NodeManager::currentNM()->mkNode( kind::AND, antec_exp ); + //Node antec = n.eqNode( vn ); + TypeNode tn = n.getType(); + Assert( tn.isDatatype() ); + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + Assert( dt.isSygus() ); + Trace("sygus-eager") << "TermDbSygus::eager: Register model value : " << vn << " for " << n << std::endl; + Trace("sygus-eager") << "...it has " << it->second.size() << " evaluations, already processed " << start << "." << std::endl; + Node bTerm = d_quantEngine->getTermDatabaseSygus()->sygusToBuiltin( vn, tn ); + Trace("sygus-eager") << "Built-in term : " << bTerm << std::endl; + std::vector< Node > vars; + Node var_list = Node::fromExpr( dt.getSygusVarList() ); + for( unsigned j=0; j<var_list.getNumChildren(); j++ ){ + vars.push_back( var_list[j] ); + } + //evaluation children + std::vector< Node > eval_children; + eval_children.push_back( Node::fromExpr( dt.getSygusEvaluationFunc() ) ); + eval_children.push_back( n ); + //for each evaluation + for( unsigned i=start; i<it->second.size(); i++ ){ + Node res; + Node expn; + // unfold? + bool do_unfold = false; + if( options::sygusUnfoldBool() ){ + if( bTerm.getKind()==ITE || bTerm.getType().isBoolean() ){ + do_unfold = true; + } + } + if( do_unfold ){ + // TODO : this is replicated for different values, possibly do better caching + std::map< Node, Node > vtm; + std::vector< Node > exp; + vtm[n] = vn; + eval_children.insert( eval_children.end(), it->second[i].begin(), it->second[i].end() ); + Node eval_fun = NodeManager::currentNM()->mkNode( kind::APPLY_UF, eval_children ); + eval_children.resize( 2 ); + res = unfold( eval_fun, vtm, exp ); + expn = exp.size()==1 ? exp[0] : NodeManager::currentNM()->mkNode( kind::AND, exp ); + }else{ + + EvalSygusInvarianceTest esit; + eval_children.insert( eval_children.end(), it->second[i].begin(), it->second[i].end() ); + esit.d_conj = NodeManager::currentNM()->mkNode( kind::APPLY_UF, eval_children ); + esit.d_var = n; + eval_children[1] = vn; + Node eval_fun = NodeManager::currentNM()->mkNode( kind::APPLY_UF, eval_children ); + esit.d_result = evaluateWithUnfolding( eval_fun ); + res = esit.d_result; + eval_children.resize( 2 ); + eval_children[1] = n; + + //evaluate with minimal explanation + std::vector< Node > mexp; + getExplanationFor( n, vn, mexp, esit ); + Assert( !mexp.empty() ); + expn = mexp.size()==1 ? mexp[0] : NodeManager::currentNM()->mkNode( kind::AND, mexp ); + + //if all constant, we can use evaluation to minimize the explanation + //Assert( i<d_eval_args_const[n].size() ); + //if( d_eval_args_const[n][i] ){ + /* + std::map< Node, Node > vtm; + std::map< Node, Node > visited; + std::map< Node, std::vector< Node > > exp; + vtm[n] = vn; + res = crefEvaluate( eval_fun, vtm, visited, exp ); + Assert( !exp[eval_fun].empty() ); + expn = exp[eval_fun].size()==1 ? exp[eval_fun][0] : NodeManager::currentNM()->mkNode( kind::AND, exp[eval_fun] ); + */ + /* + //otherwise, just do a substitution + }else{ + Assert( vars.size()==it->second[i].size() ); + res = bTerm.substitute( vars.begin(), vars.end(), it->second[i].begin(), it->second[i].end() ); + res = Rewriter::rewrite( res ); + expn = antec; + } + */ + } + Assert( !res.isNull() ); + terms.push_back( d_evals[n][i] ); + vals.push_back( res ); + exps.push_back( expn ); + Trace("sygus-eager") << "Conclude : " << d_evals[n][i] << " == " << res << ", cref eval = " << d_eval_args_const[n][i] << std::endl; + Trace("sygus-eager") << " from " << expn << std::endl; + } + d_node_mv_args_proc[n][vn] = it->second.size(); + } + } + } +} + +void TermDbSygus::getExplanationForConstantEquality( Node n, Node vn, std::vector< Node >& exp ) { + std::map< unsigned, bool > cexc; + getExplanationForConstantEquality( n, vn, exp, cexc ); +} + +void TermDbSygus::getExplanationForConstantEquality( Node n, Node vn, std::vector< Node >& exp, std::map< unsigned, bool >& cexc ) { + Assert( vn.getKind()==kind::APPLY_CONSTRUCTOR ); + Assert( n.getType()==vn.getType() ); + TypeNode tn = n.getType(); + Assert( tn.isDatatype() ); + const Datatype& dt = ((DatatypeType)tn.toType()).getDatatype(); + int i = Datatype::indexOf( vn.getOperator().toExpr() ); + Node tst = datatypes::DatatypesRewriter::mkTester( n, i, dt ); + exp.push_back( tst ); + for( unsigned j=0; j<vn.getNumChildren(); j++ ){ + if( cexc.find( j )==cexc.end() ){ + Node sel = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[i].getSelectorInternal( tn.toType(), j ) ), n ); + getExplanationForConstantEquality( sel, vn[j], exp ); + } + } +} + +Node TermDbSygus::getExplanationForConstantEquality( Node n, Node vn ) { + std::map< unsigned, bool > cexc; + return getExplanationForConstantEquality( n, vn, cexc ); +} + +Node TermDbSygus::getExplanationForConstantEquality( Node n, Node vn, std::map< unsigned, bool >& cexc ) { + std::vector< Node > exp; + getExplanationForConstantEquality( n, vn, exp, cexc ); + Assert( !exp.empty() ); + return exp.size()==1 ? exp[0] : NodeManager::currentNM()->mkNode( kind::AND, exp ); +} + +// we have ( n = vn => eval( n ) = bvr ) ^ vn != vnr , returns exp such that exp => ( eval( n ) = bvr ^ vn != vnr ) +void TermDbSygus::getExplanationFor( TermRecBuild& trb, Node n, Node vn, std::vector< Node >& exp, std::map< TypeNode, int >& var_count, + SygusInvarianceTest& et, Node vnr, Node& vnr_exp, int& sz ) { + Assert( vnr.isNull() || vn!=vnr ); + Assert( vn.getKind()==APPLY_CONSTRUCTOR ); + Assert( vnr.isNull() || vnr.getKind()==APPLY_CONSTRUCTOR ); + Assert( n.getType()==vn.getType() ); + TypeNode ntn = n.getType(); + std::map< unsigned, bool > cexc; + // for each child, check whether replacing by a fresh variable and rewriting again + for( unsigned i=0; i<vn.getNumChildren(); i++ ){ + TypeNode xtn = vn[i].getType(); + Node x = getFreeVarInc( xtn, var_count ); + trb.replaceChild( i, x ); + Node nvn = trb.build(); + Assert( nvn.getKind()==kind::APPLY_CONSTRUCTOR ); + if( et.is_invariant( this, nvn, x ) ){ + cexc[i] = true; + // we are tracking term size if positive + if( sz>=0 ){ + int s = getSygusTermSize( vn[i] ); + sz = sz - s; + } + }else{ + trb.replaceChild( i, vn[i] ); + } + } + const Datatype& dt = ((DatatypeType)ntn.toType()).getDatatype(); + int cindex = Datatype::indexOf( vn.getOperator().toExpr() ); + Assert( cindex>=0 && cindex<(int)dt.getNumConstructors() ); + Node tst = datatypes::DatatypesRewriter::mkTester( n, cindex, dt ); + exp.push_back( tst ); + // if the operator of vn is different than vnr, then disunification obligation is met + if( !vnr.isNull() ){ + if( vnr.getOperator()!=vn.getOperator() ){ + vnr = Node::null(); + vnr_exp = d_true; + } + } + for( unsigned i=0; i<vn.getNumChildren(); i++ ){ + Node sel = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[cindex].getSelectorInternal( ntn.toType(), i ) ), n ); + Node vnr_c = vnr.isNull() ? vnr : ( vn[i]==vnr[i] ? Node::null() : vnr[i] ); + if( cexc.find( i )==cexc.end() ){ + trb.push( i ); + Node vnr_exp_c; + getExplanationFor( trb, sel, vn[i], exp, var_count, et, vnr_c, vnr_exp_c, sz ); + trb.pop(); + if( !vnr_c.isNull() ){ + Assert( !vnr_exp_c.isNull() ); + if( vnr_exp_c.isConst() || vnr_exp.isNull() ){ + // recursively satisfied the disunification obligation + if( vnr_exp_c.isConst() ){ + // was successful, don't consider further + vnr = Node::null(); + } + vnr_exp = vnr_exp_c; + } + } + }else{ + // if excluded, we may need to add the explanation for this + if( vnr_exp.isNull() && !vnr_c.isNull() ){ + vnr_exp = getExplanationForConstantEquality( sel, vnr[i] ); + } + } + } +} + +void TermDbSygus::getExplanationFor( Node n, Node vn, std::vector< Node >& exp, SygusInvarianceTest& et, Node vnr, unsigned& sz ) { + // naive : + //return getExplanationForConstantEquality( n, vn, exp ); + + // set up the recursion object + std::map< TypeNode, int > var_count; + TermRecBuild trb; + trb.init( vn ); + Node vnr_exp; + int sz_use = sz; + getExplanationFor( trb, n, vn, exp, var_count, et, vnr, vnr_exp, sz_use ); + Assert( sz_use>=0 ); + sz = sz_use; + Assert( vnr.isNull() || !vnr_exp.isNull() ); + if( !vnr_exp.isNull() && !vnr_exp.isConst() ){ + exp.push_back( vnr_exp.negate() ); + } +} + +void TermDbSygus::getExplanationFor( Node n, Node vn, std::vector< Node >& exp, SygusInvarianceTest& et ) { + int sz = -1; + std::map< TypeNode, int > var_count; + TermRecBuild trb; + trb.init( vn ); + Node vnr; + Node vnr_exp; + getExplanationFor( trb, n, vn, exp, var_count, et, vnr, vnr_exp, sz ); +} + +Node TermDbSygus::unfold( Node en, std::map< Node, Node >& vtm, std::vector< Node >& exp, bool track_exp ) { + if( en.getKind()==kind::APPLY_UF ){ + Trace("sygus-db-debug") << "Unfold : " << en << std::endl; + Node ev = en[0]; + if( track_exp ){ + std::map< Node, Node >::iterator itv = vtm.find( en[0] ); + if( itv!=vtm.end() ){ + ev = itv->second; + }else{ + Assert( false ); + } + Assert( en[0].getType()==ev.getType() ); + Assert( ev.isConst() ); + } + Assert( ev.getKind()==kind::APPLY_CONSTRUCTOR ); + std::vector< Node > args; + for( unsigned i=1; i<en.getNumChildren(); i++ ){ + args.push_back( en[i] ); + } + const Datatype& dt = ((DatatypeType)(ev.getType()).toType()).getDatatype(); + unsigned i = Datatype::indexOf( ev.getOperator().toExpr() ); + if( track_exp ){ + //explanation + Node ee = NodeManager::currentNM()->mkNode( kind::APPLY_TESTER, Node::fromExpr( dt[i].getTester() ), en[0] ); + if( std::find( exp.begin(), exp.end(), ee )==exp.end() ){ + exp.push_back( ee ); + } + } + Assert( !dt.isParametric() ); + std::map< int, Node > pre; + for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){ + std::vector< Node > cc; + //get the evaluation argument for the selector + Type rt = dt[i][j].getRangeType(); + const Datatype & ad = ((DatatypeType)dt[i][j].getRangeType()).getDatatype(); + cc.push_back( Node::fromExpr( ad.getSygusEvaluationFunc() ) ); + Node s; + if( en[0].getKind()==kind::APPLY_CONSTRUCTOR ){ + s = en[0][j]; + }else{ + s = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, dt[i].getSelectorInternal( en[0].getType().toType(), j ), en[0] ); + } + cc.push_back( s ); + if( track_exp ){ + //update vtm map + vtm[s] = ev[j]; + } + cc.insert( cc.end(), args.begin(), args.end() ); + pre[j] = NodeManager::currentNM()->mkNode( kind::APPLY_UF, cc ); + } + std::map< TypeNode, int > var_count; + Node ret = mkGeneric( dt, i, var_count, pre ); + // if it is a variable, apply the substitution + if( ret.getKind()==kind::BOUND_VARIABLE ){ + Assert( ret.hasAttribute(SygusVarNumAttribute()) ); + int i = ret.getAttribute(SygusVarNumAttribute()); + Assert( Node::fromExpr( dt.getSygusVarList() )[i]==ret ); + ret = args[i]; + }else if( ret.getKind()==APPLY ){ + //must expand definitions to account for defined functions in sygus grammars + ret = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( ret.toExpr() ) ); + } + return ret; + }else{ + Assert( en.isConst() ); + } + return en; +} + + +Node TermDbSygus::getEagerUnfold( Node n, std::map< Node, Node >& visited ) { + std::map< Node, Node >::iterator itv = visited.find( n ); + if( itv==visited.end() ){ + Trace("cegqi-eager-debug") << "getEagerUnfold " << n << std::endl; + Node ret; + if( n.getKind()==APPLY_UF ){ + TypeNode tn = n[0].getType(); + Trace("cegqi-eager-debug") << "check " << n[0].getType() << std::endl; + if( tn.isDatatype() ){ + const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); + if( dt.isSygus() ){ + Trace("cegqi-eager") << "Unfold eager : " << n << std::endl; + Node bTerm = sygusToBuiltin( n[0], tn ); + Trace("cegqi-eager") << "Built-in term : " << bTerm << std::endl; + std::vector< Node > vars; + std::vector< Node > subs; + Node var_list = Node::fromExpr( dt.getSygusVarList() ); + Assert( var_list.getNumChildren()+1==n.getNumChildren() ); + for( unsigned j=0; j<var_list.getNumChildren(); j++ ){ + vars.push_back( var_list[j] ); + } + for( unsigned j=1; j<n.getNumChildren(); j++ ){ + Node nc = getEagerUnfold( n[j], visited ); + subs.push_back( nc ); + Assert( subs[j-1].getType()==var_list[j-1].getType() ); + } + Assert( vars.size()==subs.size() ); + bTerm = bTerm.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() ); + Trace("cegqi-eager") << "Built-in term after subs : " << bTerm << std::endl; + Trace("cegqi-eager-debug") << "Types : " << bTerm.getType() << " " << n.getType() << std::endl; + Assert( n.getType()==bTerm.getType() ); + ret = bTerm; + } + } + } + if( ret.isNull() ){ + if( n.getKind()!=FORALL ){ + bool childChanged = false; + std::vector< Node > children; + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + Node nc = getEagerUnfold( n[i], visited ); + childChanged = childChanged || n[i]!=nc; + children.push_back( nc ); + } + if( childChanged ){ + if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){ + children.insert( children.begin(), n.getOperator() ); + } + ret = NodeManager::currentNM()->mkNode( n.getKind(), children ); + } + } + if( ret.isNull() ){ + ret = n; + } + } + visited[n] = ret; + return ret; + }else{ + return itv->second; + } +} + + +Node TermDbSygus::evaluateBuiltin( TypeNode tn, Node bn, std::vector< Node >& args ) { + if( !args.empty() ){ + std::map< TypeNode, std::vector< Node > >::iterator it = d_var_list.find( tn ); + Assert( it!=d_var_list.end() ); + Assert( it->second.size()==args.size() ); + return Rewriter::rewrite( bn.substitute( it->second.begin(), it->second.end(), args.begin(), args.end() ) ); + }else{ + return Rewriter::rewrite( bn ); + } +} + +Node TermDbSygus::evaluateBuiltin( TypeNode tn, Node bn, Node ar, unsigned i ) { + std::map< Node, std::vector< std::vector< Node > > >::iterator it = d_pbe_exs.find( ar ); + if( it!=d_pbe_exs.end() ){ + Assert( i<it->second.size() ); + return evaluateBuiltin( tn, bn, it->second[i] ); + }else{ + return Rewriter::rewrite( bn ); + } +} + +Node TermDbSygus::evaluateWithUnfolding( Node n, std::map< Node, Node >& visited ) { + std::map< Node, Node >::iterator it = visited.find( n ); + if( it==visited.end() ){ + Node ret = n; + while( ret.getKind()==APPLY_UF && ret[0].getKind()==APPLY_CONSTRUCTOR ){ + ret = unfold( ret ); + } + if( ret.getNumChildren()>0 ){ + std::vector< Node > children; + if( ret.getMetaKind() == kind::metakind::PARAMETERIZED ){ + children.push_back( ret.getOperator() ); + } + bool childChanged = false; + for( unsigned i=0; i<ret.getNumChildren(); i++ ){ + Node nc = evaluateWithUnfolding( ret[i], visited ); + childChanged = childChanged || nc!=ret[i]; + children.push_back( nc ); + } + if( childChanged ){ + ret = NodeManager::currentNM()->mkNode( ret.getKind(), children ); + } + // TODO : extended rewrite? + ret = extendedRewrite( ret ); + } + visited[n] = ret; + return ret; + }else{ + return it->second; + } +} + +Node TermDbSygus::evaluateWithUnfolding( Node n ) { + std::map< Node, Node > visited; + return evaluateWithUnfolding( n, visited ); +} + +bool TermDbSygus::computeGenericRedundant( TypeNode tn, Node g ) { + //everything added to this cache should be mutually exclusive cases + std::map< Node, bool >::iterator it = d_gen_redundant[tn].find( g ); + if( it==d_gen_redundant[tn].end() ){ + Trace("sygus-gnf") << "Register generic for " << tn << " : " << g << std::endl; + Node gr = getNormalized( tn, g, false ); + Trace("sygus-gnf-debug") << "Generic " << g << " rewrites to " << gr << std::endl; + std::map< Node, Node >::iterator itg = d_gen_terms[tn].find( gr ); + bool red = true; + if( itg==d_gen_terms[tn].end() ){ + red = false; + d_gen_terms[tn][gr] = g; + Trace("sygus-gnf-debug") << "...not redundant." << std::endl; + Trace("sygus-nf-reg") << "*** Sygus (generic) normal form : normal form of " << g << " is " << gr << std::endl; + }else{ + Trace("sygus-gnf-debug") << "...redundant." << std::endl; + Trace("sygus-nf") << "* Sygus normal form : simplify since " << g << " and " << itg->second << " both rewrite to " << gr << std::endl; + } + d_gen_redundant[tn][g] = red; + return red; + }else{ + return it->second; + } +} + +bool TermDbSygus::isGenericRedundant( TypeNode tn, unsigned i ) { + Assert( i<d_sygus_red_status[tn].size() ); + if( options::sygusMinGrammarAgg() ){ + return d_sygus_red_status[tn][i]!=0; + }else{ + return d_sygus_red_status[tn][i]==1; + } +} + +Node TermDbSygus::PbeTrie::addPbeExample( TypeNode etn, Node e, Node b, quantifiers::TermDbSygus * tds, unsigned index, unsigned ntotal ) { + Assert( tds->getNumPbeExamples( e )==ntotal ); + if( index==ntotal ){ + //lazy child holds the leaf data + if( d_lazy_child.isNull() ){ + d_lazy_child = b; + } + return d_lazy_child; + }else{ + std::vector< Node > ex; + if( d_children.empty() ){ + if( d_lazy_child.isNull() ){ + d_lazy_child = b; + return d_lazy_child; + }else{ + //evaluate the lazy child + tds->getPbeExample( e, index, ex ); + addPbeExampleEval( etn, e, d_lazy_child, ex, tds, index, ntotal ); + Assert( !d_children.empty() ); + d_lazy_child = Node::null(); + } + }else{ + tds->getPbeExample( e, index, ex ); + } + return addPbeExampleEval( etn, e, b, ex, tds, index, ntotal ); + } +} + +Node TermDbSygus::PbeTrie::addPbeExampleEval( TypeNode etn, Node e, Node b, std::vector< Node >& ex, quantifiers::TermDbSygus * tds, unsigned index, unsigned ntotal ) { + Node eb = tds->evaluateBuiltin( etn, b, ex ); + return d_children[eb].addPbeExample( etn, e, b, tds, index+1, ntotal ); +} + +Node TermDbSygus::addPbeSearchVal( TypeNode tn, Node e, Node bvr ){ + Assert( !e.isNull() ); + if( hasPbeExamples( e ) ){ + unsigned nex = getNumPbeExamples( e ); + Node ret = d_pbe_trie[e][tn].addPbeExample( tn, e, bvr, this, 0, nex ); + Assert( ret.getType()==bvr.getType() ); + return ret; + } + return Node::null(); +} + +Node TermDbSygus::extendedRewritePullIte( Node n ) { + // generalize this? + Assert( n.getNumChildren()==2 ); + Assert( n.getType().isBoolean() ); + Assert( n.getMetaKind() != kind::metakind::PARAMETERIZED ); + std::vector< Node > children; + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + children.push_back( n[i] ); + } + for( unsigned i=0; i<2; i++ ){ + if( n[i].getKind()==kind::ITE ){ + for( unsigned j=0; j<2; j++ ){ + children[i] = n[i][j+1]; + Node eqr = extendedRewrite( NodeManager::currentNM()->mkNode( n.getKind(), children ) ); + children[i] = n[i]; + if( eqr.isConst() ){ + std::vector< Node > new_children; + Kind new_k; + if( eqr==d_true ){ + new_k = kind::OR; + new_children.push_back( j==0 ? n[i][0] : n[i][0].negate() ); + }else{ + Assert( eqr==d_false ); + new_k = kind::AND; + new_children.push_back( j==0 ? n[i][0].negate() : n[i][0] ); + } + children[i] = n[i][2-j]; + Node rem_eq = NodeManager::currentNM()->mkNode( n.getKind(), children ); + children[i] = n[i]; + new_children.push_back( rem_eq ); + Node nc = NodeManager::currentNM()->mkNode( new_k, new_children ); + Trace("sygus-ext-rewrite") << "sygus-extr : " << n << " rewrites to " << nc << " by simple ITE pulling." << std::endl; + //recurse + return extendedRewrite( nc ); + } + } + } + } + return Node::null(); +} + +Node TermDbSygus::extendedRewrite( Node n ) { + std::map< Node, Node >::iterator it = d_ext_rewrite_cache.find( n ); + if( it == d_ext_rewrite_cache.end() ){ + Node ret = n; + if( n.getNumChildren()>0 ){ + std::vector< Node > children; + if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){ + children.push_back( n.getOperator() ); + } + bool childChanged = false; + for( unsigned i=0; i<n.getNumChildren(); i++ ){ + Node nc = extendedRewrite( n[i] ); + childChanged = nc!=n[i] || childChanged; + children.push_back( nc ); + } + Node ret; + if( childChanged ){ + ret = NodeManager::currentNM()->mkNode( n.getKind(), children ); + } + } + ret = Rewriter::rewrite( n ); + Trace("sygus-ext-rewrite-debug") << "Do extended rewrite on : " << ret << " (from " << n << ")" << std::endl; + + Node new_ret; + if( ret.getKind()==kind::EQUAL ){ + // string equalities with disequal prefix or suffix + if( ret[0].getType().isString() ){ + std::vector< Node > c[2]; + for( unsigned i=0; i<2; i++ ){ + strings::TheoryStringsRewriter::getConcat( ret[i], c[i] ); + } + if( c[0].empty()==c[1].empty() ){ + if( !c[0].empty() ){ + for( unsigned i=0; i<2; i++ ){ + unsigned index1 = i==0 ? 0 : c[0].size()-1; + unsigned index2 = i==0 ? 0 : c[1].size()-1; + if( c[0][index1].isConst() && c[1][index2].isConst() ){ + CVC4::String s = c[0][index1].getConst<String>(); + CVC4::String t = c[1][index2].getConst<String>(); + unsigned len_short = s.size() <= t.size() ? s.size() : t.size(); + bool isSameFix = i==1 ? s.rstrncmp(t, len_short): s.strncmp(t, len_short); + if( !isSameFix ){ + Trace("sygus-ext-rewrite") << "sygus-extr : " << ret << " rewrites to false due to disequal string prefix/suffix." << std::endl; + new_ret = d_false; + break; + } + } + } + } + }else{ + new_ret = d_false; + } + } + if( new_ret.isNull() ){ + // simple ITE pulling + new_ret = extendedRewritePullIte( ret ); + } + // TODO : ( ~contains( x, y ) --> false ) => ( ~x=y --> false ) + }else if( ret.getKind()==kind::ITE ){ + Assert( ret[1]!=ret[2] ); + if( ret[0].getKind()==NOT ){ + ret = NodeManager::currentNM()->mkNode( kind::ITE, ret[0][0], ret[2], ret[1] ); + } + if( ret[0].getKind()==kind::EQUAL ){ + // simple invariant ITE + for( unsigned i=0; i<2; i++ ){ + if( ret[1]==ret[0][i] && ret[2]==ret[0][1-i] ){ + Trace("sygus-ext-rewrite") << "sygus-extr : " << ret << " rewrites to " << ret[2] << " due to simple invariant ITE." << std::endl; + new_ret = ret[2]; + break; + } + } + // notice this is strictly more general that the above + if( new_ret.isNull() ){ + // simple substitution + for( unsigned i=0; i<2; i++ ){ + if( ret[0][i].isVar() && ( ( ret[0][1-i].isVar() && ret[0][i]<ret[0][1-i] ) || ret[0][1-i].isConst() ) ){ + TNode r1 = ret[0][i]; + TNode r2 = ret[0][1-i]; + Node retn = ret[1].substitute( r1, r2 ); + if( retn!=ret[1] ){ + new_ret = NodeManager::currentNM()->mkNode( kind::ITE, ret[0], retn, ret[2] ); + Trace("sygus-ext-rewrite") << "sygus-extr : " << ret << " rewrites to " << new_ret << " due to simple ITE substitution." << std::endl; + } + } + } + } + } + }else if( ret.getKind()==DIVISION || ret.getKind()==INTS_DIVISION || ret.getKind()==INTS_MODULUS ){ + // rewrite as though total + std::vector< Node > children; + bool all_const = true; + for( unsigned i=0; i<ret.getNumChildren(); i++ ){ + if( ret[i].isConst() ){ + children.push_back( ret[i] ); + }else{ + all_const = false; + break; + } + } + if( all_const ){ + Kind new_k = ( ret.getKind()==DIVISION ? DIVISION_TOTAL : ( ret.getKind()==INTS_DIVISION ? INTS_DIVISION_TOTAL : INTS_MODULUS_TOTAL ) ); + new_ret = NodeManager::currentNM()->mkNode( new_k, children ); + Trace("sygus-ext-rewrite") << "sygus-extr : " << ret << " rewrites to " << new_ret << " due to total interpretation." << std::endl; + } + } + // more expensive rewrites + if( new_ret.isNull() ){ + Trace("sygus-ext-rewrite-debug2") << "Do expensive rewrites on " << ret << std::endl; + bool polarity = ret.getKind()!=NOT; + Node ret_atom = ret.getKind()==NOT ? ret[0] : ret; + if( ( ret_atom.getKind()==EQUAL && ret_atom[0].getType().isReal() ) || ret_atom.getKind()==GEQ ){ + Trace("sygus-ext-rewrite-debug2") << "Compute monomial sum " << ret_atom << std::endl; + //compute monomial sum + std::map< Node, Node > msum; + if( QuantArith::getMonomialSumLit( ret_atom, msum ) ){ + for( std::map< Node, Node >::iterator itm = msum.begin(); itm != msum.end(); ++itm ){ + Node v = itm->first; + Trace("sygus-ext-rewrite-debug2") << itm->first << " * " << itm->second << std::endl; + if( v.getKind()==ITE ){ + Node veq; + int res = QuantArith::isolate( v, msum, veq, ret_atom.getKind() ); + if( res!=0 ){ + Trace("sygus-ext-rewrite-debug") << " have ITE relation, solved form : " << veq << std::endl; + // try pulling ITE + new_ret = extendedRewritePullIte( veq ); + if( !new_ret.isNull() ){ + if( !polarity ){ + new_ret = new_ret.negate(); + } + break; + } + }else{ + Trace("sygus-ext-rewrite-debug") << " failed to isolate " << v << " in " << ret << std::endl; + } + } + } + }else{ + Trace("sygus-ext-rewrite-debug") << " failed to get monomial sum of " << ret << std::endl; + } + }else if( ret_atom.getKind()==ITE ){ + // TODO : conditional rewriting + }else if( ret.getKind()==kind::AND || ret.getKind()==kind::OR ){ + // TODO condition merging + } + } + + if( !new_ret.isNull() ){ + ret = Rewriter::rewrite( new_ret ); + } + d_ext_rewrite_cache[n] = ret; + return ret; + }else{ + return it->second; + } +} + + + + + + +TypeNode TermDbSygus::mkUnresolvedType(const std::string& name, std::set<Type>& unres) { + TypeNode unresolved = NodeManager::currentNM()->mkSort(name, ExprManager::SORT_FLAG_PLACEHOLDER); + unres.insert( unresolved.toType() ); + return unresolved; +} + +void TermDbSygus::mkSygusConstantsForType( TypeNode type, std::vector<CVC4::Node>& ops ) { + if( type.isInteger() ){ + ops.push_back(NodeManager::currentNM()->mkConst(Rational(0))); + ops.push_back(NodeManager::currentNM()->mkConst(Rational(1))); + }else if( type.isBitVector() ){ + unsigned sz = ((BitVectorType)type.toType()).getSize(); + BitVector bval0(sz, (unsigned int)0); + ops.push_back( NodeManager::currentNM()->mkConst(bval0) ); + BitVector bval1(sz, (unsigned int)1); + ops.push_back( NodeManager::currentNM()->mkConst(bval1) ); + }else if( type.isBoolean() ){ + ops.push_back(NodeManager::currentNM()->mkConst(true)); + ops.push_back(NodeManager::currentNM()->mkConst(false)); + } + //TODO : others? +} + +void TermDbSygus::collectSygusGrammarTypesFor( TypeNode range, std::vector< TypeNode >& types, std::map< TypeNode, std::vector< DatatypeConstructorArg > >& sels ){ + if( !range.isBoolean() ){ + if( std::find( types.begin(), types.end(), range )==types.end() ){ + Trace("sygus-grammar-def") << "...will make grammar for " << range << std::endl; + types.push_back( range ); + if( range.isDatatype() ){ + const Datatype& dt = ((DatatypeType)range.toType()).getDatatype(); + for( unsigned i=0; i<dt.getNumConstructors(); i++ ){ + for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){ + TypeNode crange = TypeNode::fromType( ((SelectorType)dt[i][j].getType()).getRangeType() ); + sels[crange].push_back( dt[i][j] ); + collectSygusGrammarTypesFor( crange, types, sels ); + } + } + } + } + } +} + +void TermDbSygus::mkSygusDefaultGrammar( TypeNode range, Node bvl, const std::string& fun, std::map< TypeNode, std::vector< Node > >& extra_cons, + std::vector< CVC4::Datatype >& datatypes, std::set<Type>& unres ) { + // collect the variables + std::vector<Node> sygus_vars; + if( !bvl.isNull() ){ + for( unsigned i=0; i<bvl.getNumChildren(); i++ ){ + sygus_vars.push_back( bvl[i] ); + } + } + //if( !range.isBoolean() && !range.isInteger() && !range.isBitVector() && !range.isDatatype() ){ + // parseError("No default grammar for type."); + //} + std::vector< std::vector< Expr > > ops; + int startIndex = -1; + Trace("sygus-grammar-def") << "Construct default grammar for " << fun << " " << range << std::endl; + std::map< Type, Type > sygus_to_builtin; + + std::vector< TypeNode > types; + std::map< TypeNode, std::vector< DatatypeConstructorArg > > sels; + //types for each of the variables of parametric sort + for( unsigned i=0; i<sygus_vars.size(); i++ ){ + collectSygusGrammarTypesFor( sygus_vars[i].getType(), types, sels ); + } + //types connected to range + collectSygusGrammarTypesFor( range, types, sels ); + + //name of boolean sort + std::stringstream ssb; + ssb << fun << "_Bool"; + std::string dbname = ssb.str(); + Type unres_bt = mkUnresolvedType(ssb.str(), unres).toType(); + + std::vector< Type > unres_types; + std::map< TypeNode, Type > type_to_unres; + for( unsigned i=0; i<types.size(); i++ ){ + std::stringstream ss; + ss << fun << "_" << types[i]; + std::string dname = ss.str(); + datatypes.push_back(Datatype(dname)); + ops.push_back(std::vector< Expr >()); + //make unresolved type + Type unres_t = mkUnresolvedType(dname, unres).toType(); + unres_types.push_back(unres_t); + type_to_unres[types[i]] = unres_t; + sygus_to_builtin[unres_t] = types[i].toType(); + } + for( unsigned i=0; i<types.size(); i++ ){ + Trace("sygus-grammar-def") << "Make grammar for " << types[i] << " " << unres_types[i] << std::endl; + std::vector<std::string> cnames; + std::vector<std::vector<CVC4::Type> > cargs; + Type unres_t = unres_types[i]; + //add variables + for( unsigned j=0; j<sygus_vars.size(); j++ ){ + if( sygus_vars[j].getType()==types[i] ){ + std::stringstream ss; + ss << sygus_vars[j]; + Trace("sygus-grammar-def") << "...add for variable " << ss.str() << std::endl; + ops[i].push_back( sygus_vars[j].toExpr() ); + cnames.push_back( ss.str() ); + cargs.push_back( std::vector< CVC4::Type >() ); + } + } + //add constants + std::vector< Node > consts; + mkSygusConstantsForType( types[i], consts ); + std::map< TypeNode, std::vector< Node > >::iterator itec = extra_cons.find( types[i] ); + if( itec!=extra_cons.end() ){ + //consts.insert( consts.end(), itec->second.begin(), itec->second.end() ); + for( unsigned j=0; j<itec->second.size(); j++ ){ + if( std::find( consts.begin(), consts.end(), itec->second[j] )==consts.end() ){ + consts.push_back( itec->second[j] ); + } + } + } + for( unsigned j=0; j<consts.size(); j++ ){ + std::stringstream ss; + ss << consts[j]; + Trace("sygus-grammar-def") << "...add for constant " << ss.str() << std::endl; + ops[i].push_back( consts[j].toExpr() ); + cnames.push_back( ss.str() ); + cargs.push_back( std::vector< CVC4::Type >() ); + } + //ITE + CVC4::Kind k = kind::ITE; + Trace("sygus-grammar-def") << "...add for " << k << std::endl; + ops[i].push_back(NodeManager::currentNM()->operatorOf(k).toExpr()); + cnames.push_back( kind::kindToString(k) ); + cargs.push_back( std::vector< CVC4::Type >() ); + cargs.back().push_back(unres_bt); + cargs.back().push_back(unres_t); + cargs.back().push_back(unres_t); + + if( types[i].isInteger() ){ + for( unsigned j=0; j<2; j++ ){ + CVC4::Kind k = j==0 ? kind::PLUS : kind::MINUS; + Trace("sygus-grammar-def") << "...add for " << k << std::endl; + ops[i].push_back(NodeManager::currentNM()->operatorOf(k).toExpr()); + cnames.push_back(kind::kindToString(k)); + cargs.push_back( std::vector< CVC4::Type >() ); + cargs.back().push_back(unres_t); + cargs.back().push_back(unres_t); + } + }else if( types[i].isDatatype() ){ + Trace("sygus-grammar-def") << "...add for constructors" << std::endl; + const Datatype& dt = ((DatatypeType)types[i].toType()).getDatatype(); + for( unsigned k=0; k<dt.getNumConstructors(); k++ ){ + Trace("sygus-grammar-def") << "...for " << dt[k].getName() << std::endl; + ops[i].push_back( dt[k].getConstructor() ); + cnames.push_back( dt[k].getName() ); + cargs.push_back( std::vector< CVC4::Type >() ); + for( unsigned j=0; j<dt[k].getNumArgs(); j++ ){ + TypeNode crange = TypeNode::fromType( ((SelectorType)dt[k][j].getType()).getRangeType() ); + //Assert( type_to_unres.find(crange)!=type_to_unres.end() ); + cargs.back().push_back( type_to_unres[crange] ); + } + } + }else{ + std::stringstream sserr; + sserr << "No implementation for default Sygus grammar of type " << types[i] << std::endl; + //AlwaysAssert( false, sserr.str() ); + // FIXME + AlwaysAssert( false ); + } + //add for all selectors to this type + if( !sels[types[i]].empty() ){ + Trace("sygus-grammar-def") << "...add for selectors" << std::endl; + for( unsigned j=0; j<sels[types[i]].size(); j++ ){ + Trace("sygus-grammar-def") << "...for " << sels[types[i]][j].getName() << std::endl; + TypeNode arg_type = TypeNode::fromType( ((SelectorType)sels[types[i]][j].getType()).getDomain() ); + ops[i].push_back( sels[types[i]][j].getSelector() ); + cnames.push_back( sels[types[i]][j].getName() ); + cargs.push_back( std::vector< CVC4::Type >() ); + //Assert( type_to_unres.find(arg_type)!=type_to_unres.end() ); + cargs.back().push_back( type_to_unres[arg_type] ); + } + } + Trace("sygus-grammar-def") << "...make datatype " << datatypes.back() << std::endl; + datatypes[i].setSygus( types[i].toType(), bvl.toExpr(), true, true ); + for( unsigned j=0; j<ops[i].size(); j++ ){ + datatypes[i].addSygusConstructor( ops[i][j], cnames[j], cargs[j] ); + } + //sorts.push_back( types[i] ); + //set start index if applicable + if( types[i]==range ){ + startIndex = i; + } + } + + //make Boolean type + TypeNode btype = NodeManager::currentNM()->booleanType(); + datatypes.push_back(Datatype(dbname)); + ops.push_back(std::vector<Expr>()); + std::vector<std::string> cnames; + std::vector<std::vector< Type > > cargs; + Trace("sygus-grammar-def") << "Make grammar for " << btype << " " << datatypes.back() << std::endl; + //add variables + for( unsigned i=0; i<sygus_vars.size(); i++ ){ + if( sygus_vars[i].getType().isBoolean() ){ + std::stringstream ss; + ss << sygus_vars[i]; + Trace("sygus-grammar-def") << "...add for variable " << ss.str() << std::endl; + ops.back().push_back( sygus_vars[i].toExpr() ); + cnames.push_back( ss.str() ); + cargs.push_back( std::vector< CVC4::Type >() ); + } + } + //add constants if no variables and no connected types + if( ops.back().empty() && types.empty() ){ + std::vector< Node > consts; + mkSygusConstantsForType( btype, consts ); + for( unsigned j=0; j<consts.size(); j++ ){ + std::stringstream ss; + ss << consts[j]; + Trace("sygus-grammar-def") << "...add for constant " << ss.str() << std::endl; + ops.back().push_back( consts[j].toExpr() ); + cnames.push_back( ss.str() ); + cargs.push_back( std::vector< CVC4::Type >() ); + } + } + //add operators + for( unsigned i=0; i<3; i++ ){ + CVC4::Kind k = i==0 ? kind::NOT : ( i==1 ? kind::AND : kind::OR ); + Trace("sygus-grammar-def") << "...add for " << k << std::endl; + ops.back().push_back(NodeManager::currentNM()->operatorOf(k).toExpr()); + cnames.push_back(kind::kindToString(k)); + cargs.push_back( std::vector< CVC4::Type >() ); + if( k==kind::NOT ){ + cargs.back().push_back(unres_bt); + }else if( k==kind::AND || k==kind::OR ){ + cargs.back().push_back(unres_bt); + cargs.back().push_back(unres_bt); + } + } + //add predicates for types + for( unsigned i=0; i<types.size(); i++ ){ + Trace("sygus-grammar-def") << "...add predicates for " << types[i] << std::endl; + //add equality per type + CVC4::Kind k = kind::EQUAL; + Trace("sygus-grammar-def") << "...add for " << k << std::endl; + ops.back().push_back(NodeManager::currentNM()->operatorOf(k).toExpr()); + std::stringstream ss; + ss << kind::kindToString(k) << "_" << types[i]; + cnames.push_back(ss.str()); + cargs.push_back( std::vector< CVC4::Type >() ); + cargs.back().push_back(unres_types[i]); + cargs.back().push_back(unres_types[i]); + //type specific predicates + if( types[i].isInteger() ){ + CVC4::Kind k = kind::LEQ; + Trace("sygus-grammar-def") << "...add for " << k << std::endl; + ops.back().push_back(NodeManager::currentNM()->operatorOf(k).toExpr()); + cnames.push_back(kind::kindToString(k)); + cargs.push_back( std::vector< CVC4::Type >() ); + cargs.back().push_back(unres_types[i]); + cargs.back().push_back(unres_types[i]); + }else if( types[i].isDatatype() ){ + //add for testers + Trace("sygus-grammar-def") << "...add for testers" << std::endl; + const Datatype& dt = ((DatatypeType)types[i].toType()).getDatatype(); + for( unsigned k=0; k<dt.getNumConstructors(); k++ ){ + Trace("sygus-grammar-def") << "...for " << dt[k].getTesterName() << std::endl; + ops.back().push_back(dt[k].getTester()); + cnames.push_back(dt[k].getTesterName()); + cargs.push_back( std::vector< CVC4::Type >() ); + cargs.back().push_back(unres_types[i]); + } + } + } + if( range==btype ){ + startIndex = datatypes.size()-1; + } + Trace("sygus-grammar-def") << "...make datatype " << datatypes.back() << std::endl; + datatypes.back().setSygus( btype.toType(), bvl.toExpr(), true, true ); + for( unsigned j=0; j<ops.back().size(); j++ ){ + datatypes.back().addSygusConstructor( ops.back()[j], cnames[j], cargs[j] ); + } + //sorts.push_back( btype ); + Trace("sygus-grammar-def") << "...finished make default grammar for " << fun << " " << range << std::endl; + + if( startIndex>0 ){ + CVC4::Datatype tmp_dt = datatypes[0]; + datatypes[0] = datatypes[startIndex]; + datatypes[startIndex] = tmp_dt; + } +} + + +TypeNode TermDbSygus::mkSygusDefaultType( TypeNode range, Node bvl, const std::string& fun, + std::map< TypeNode, std::vector< Node > >& extra_cons ) { + Trace("sygus-grammar-def") << "*** Make sygus default type " << range << ", make datatypes..." << std::endl; + for( std::map< TypeNode, std::vector< Node > >::iterator it = extra_cons.begin(); it != extra_cons.end(); ++it ){ + Trace("sygus-grammar-def") << " ...using " << it->second.size() << " extra constants for " << it->first << std::endl; + } + std::set<Type> unres; + std::vector< CVC4::Datatype > datatypes; + mkSygusDefaultGrammar( range, bvl, fun, extra_cons, datatypes, unres ); + Trace("sygus-grammar-def") << "...made " << datatypes.size() << " datatypes, now make mutual datatype types..." << std::endl; + Assert( !datatypes.empty() ); + std::vector<DatatypeType> types = NodeManager::currentNM()->toExprManager()->mkMutualDatatypeTypes(datatypes, unres); + Assert( types.size()==datatypes.size() ); + return TypeNode::fromType( types[0] ); +} + +}/* CVC4::theory::quantifiers namespace */ +}/* CVC4::theory namespace */ +}/* CVC4 namespace */ + diff --git a/src/theory/quantifiers/term_database_sygus.h b/src/theory/quantifiers/term_database_sygus.h new file mode 100644 index 000000000..70f27dbaa --- /dev/null +++ b/src/theory/quantifiers/term_database_sygus.h @@ -0,0 +1,317 @@ +/********************* */ +/*! \file term_database_sygus.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 term database sygus class + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_SYGUS_H +#define __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_SYGUS_H + +#include "theory/quantifiers/term_database.h" + +namespace CVC4 { +namespace theory { +namespace quantifiers { + +class SygusInvarianceTest { +protected: + // check whether nvn[ x ] should be excluded + virtual bool invariant( TermDbSygus * tds, Node nvn, Node x ) = 0; +public: + bool is_invariant( TermDbSygus * tds, Node nvn, Node x ){ + if( invariant( tds, nvn, x ) ){ + d_update_nvn = nvn; + return true; + }else{ + return false; + } + } + // result of the node after invariant replacements + Node d_update_nvn; +}; + +class EvalSygusInvarianceTest : public SygusInvarianceTest { +public: + Node d_conj; + TNode d_var; + std::map< Node, Node > d_visited; + Node d_result; +protected: + bool invariant( quantifiers::TermDbSygus * tds, Node nvn, Node x ); +}; + +class TermDbSygus { +private: + /** reference to the quantifiers engine */ + QuantifiersEngine* d_quantEngine; + std::map< TypeNode, std::vector< Node > > d_fv[2]; + std::map< Node, TypeNode > d_fv_stype; + std::map< Node, int > d_fv_num; + bool hasFreeVar( Node n, std::map< Node, bool >& visited ); +public: + Node d_true; + Node d_false; +public: + TNode getFreeVar( TypeNode tn, int i, bool useSygusType = false ); + TNode getFreeVarInc( TypeNode tn, std::map< TypeNode, int >& var_count, bool useSygusType = false ); + bool isFreeVar( Node n ) { return d_fv_stype.find( n )!=d_fv_stype.end(); } + int getVarNum( Node n ) { return d_fv_num[n]; } + bool hasFreeVar( Node n ); +private: + std::map< TypeNode, std::map< int, Node > > d_generic_base; + std::map< TypeNode, std::vector< Node > > d_generic_templ; + bool getMatch( Node p, Node n, std::map< int, Node >& s ); + bool getMatch2( Node p, Node n, std::map< int, Node >& s, std::vector< int >& new_s ); +public: + bool getMatch( Node n, TypeNode st, int& index_found, std::vector< Node >& args, int index_exc = -1, int index_start = 0 ); +private: + void computeMinTypeDepthInternal( TypeNode root_tn, TypeNode tn, unsigned type_depth ); + bool involvesDivByZero( Node n, std::map< Node, bool >& visited ); +private: + // stores root + std::map< Node, Node > d_measured_term; + std::map< Node, Node > d_measured_term_active_guard; + //information for sygus types + std::map< TypeNode, TypeNode > d_register; //stores sygus -> builtin type + std::map< TypeNode, std::vector< Node > > d_var_list; + std::map< TypeNode, std::map< int, Kind > > d_arg_kind; + std::map< TypeNode, std::map< Kind, int > > d_kinds; + std::map< TypeNode, std::map< int, Node > > d_arg_const; + std::map< TypeNode, std::map< Node, int > > d_consts; + std::map< TypeNode, std::map< Node, int > > d_ops; + std::map< TypeNode, std::map< int, Node > > d_arg_ops; + std::map< TypeNode, std::vector< int > > d_id_funcs; + std::map< TypeNode, std::vector< Node > > d_const_list; //sorted list of constants for type + std::map< TypeNode, unsigned > d_const_list_pos; + std::map< TypeNode, std::map< Node, Node > > d_semantic_skolem; + //information for builtin types + std::map< TypeNode, std::map< int, Node > > d_type_value; + std::map< TypeNode, Node > d_type_max_value; + std::map< TypeNode, std::map< Node, std::map< int, Node > > > d_type_value_offset; + std::map< TypeNode, std::map< Node, std::map< int, int > > > d_type_value_offset_status; + //normalized map + std::map< TypeNode, std::map< Node, Node > > d_normalized; + std::map< TypeNode, std::map< Node, Node > > d_sygus_to_builtin; + std::map< TypeNode, std::map< Node, Node > > d_builtin_const_to_sygus; + // grammar information + // root -> type -> _ + std::map< TypeNode, std::map< TypeNode, unsigned > > d_min_type_depth; + //std::map< TypeNode, std::map< Node, std::map< std::map< int, bool > > > d_consider_const; + // type -> cons -> _ + std::map< TypeNode, unsigned > d_min_term_size; + std::map< TypeNode, std::map< unsigned, unsigned > > d_min_cons_term_size; +public: + TermDbSygus( context::Context* c, QuantifiersEngine* qe ); + ~TermDbSygus(){} + bool reset( Theory::Effort e ); + std::string identify() const { return "TermDbSygus"; } +public: + /** register the sygus type */ + void registerSygusType( TypeNode tn ); + /** register a term that we will do enumerative search on */ + void registerMeasuredTerm( Node e, Node root, bool mkActiveGuard = false ); + /** is measured term */ + Node isMeasuredTerm( Node e ); + /** get active guard */ + Node getActiveGuardForMeasureTerm( Node e ); + /** get measured terms */ + void getMeasuredTerms( std::vector< Node >& mts ); +public: //general sygus utilities + bool isRegistered( TypeNode tn ); + // get the minimum depth of type in its parent grammar + unsigned getMinTypeDepth( TypeNode root_tn, TypeNode tn ); + // get the minimum size for a constructor term + unsigned getMinTermSize( TypeNode tn ); + unsigned getMinConsTermSize( TypeNode tn, unsigned cindex ); +public: + TypeNode sygusToBuiltinType( TypeNode tn ); + int getKindConsNum( TypeNode tn, Kind k ); + int getConstConsNum( TypeNode tn, Node n ); + int getOpConsNum( TypeNode tn, Node n ); + bool hasKind( TypeNode tn, Kind k ); + bool hasConst( TypeNode tn, Node n ); + bool hasOp( TypeNode tn, Node n ); + Node getConsNumConst( TypeNode tn, int i ); + Node getConsNumOp( TypeNode tn, int i ); + Kind getConsNumKind( TypeNode tn, int i ); + bool isKindArg( TypeNode tn, int i ); + bool isConstArg( TypeNode tn, int i ); + unsigned getNumIdFuncs( TypeNode tn ); + unsigned getIdFuncIndex( TypeNode tn, unsigned i ); + /** get arg type */ + TypeNode getArgType( const DatatypeConstructor& c, int i ); + /** get first occurrence */ + int getFirstArgOccurrence( const DatatypeConstructor& c, TypeNode tn ); + /** is type match */ + bool isTypeMatch( const DatatypeConstructor& c1, const DatatypeConstructor& c2 ); + /** isAntisymmetric */ + bool isAntisymmetric( Kind k, Kind& dk ); + /** is idempotent arg */ + bool isIdempotentArg( Node n, Kind ik, int arg ); + /** is singular arg */ + Node isSingularArg( Node n, Kind ik, int arg ); + /** get offset arg */ + bool hasOffsetArg( Kind ik, int arg, int& offset, Kind& ok ); + /** get value */ + Node getTypeValue( TypeNode tn, int val ); + /** get value */ + Node getTypeValueOffset( TypeNode tn, Node val, int offset, int& status ); + /** get value */ + Node getTypeMaxValue( TypeNode tn ); + TypeNode getSygusTypeForVar( Node v ); + Node getGenericBase( TypeNode tn, const Datatype& dt, int c ); + Node mkGeneric( const Datatype& dt, int c, std::map< TypeNode, int >& var_count, std::map< int, Node >& pre ); + Node sygusToBuiltin( Node n, TypeNode tn ); + Node sygusToBuiltin( Node n ) { return sygusToBuiltin( n, n.getType() ); } + Node sygusSubstituted( TypeNode tn, Node n, std::vector< Node >& args ); + Node builtinToSygusConst( Node c, TypeNode tn, int rcons_depth = 0 ); + Node getSygusNormalized( Node n, std::map< TypeNode, int >& var_count, std::map< Node, Node >& subs ); + Node getNormalized( TypeNode t, Node prog, bool do_pre_norm = false, bool do_post_norm = true ); + unsigned getSygusTermSize( Node n ); + // returns size + unsigned getSygusConstructors( Node n, std::vector< Node >& cons ); + /** given a term, construct an equivalent smaller one that respects syntax */ + Node minimizeBuiltinTerm( Node n ); + /** given a term, expand it into more basic components */ + Node expandBuiltinTerm( Node n ); + /** get comparison kind */ + Kind getComparisonKind( TypeNode tn ); + Kind getPlusKind( TypeNode tn, bool is_neg = false ); + bool doCompare( Node a, Node b, Kind k ); + // get semantic skolem for n (a sygus term whose builtin version is n) + Node getSemanticSkolem( TypeNode tn, Node n, bool doMk = true ); + /** involves div-by-zero */ + bool involvesDivByZero( Node n ); + + /** get operator kind */ + static Kind getOperatorKind( Node op ); + /** print sygus term */ + static void printSygusTerm( std::ostream& out, Node n, std::vector< Node >& lvs ); + + /** get anchor */ + static Node getAnchor( Node n ); + static unsigned getAnchorDepth( Node n ); + +public: // for symmetry breaking + bool considerArgKind( TypeNode tn, TypeNode tnp, Kind k, Kind pk, int arg ); + bool considerConst( TypeNode tn, TypeNode tnp, Node c, Kind pk, int arg ); + bool considerConst( const Datatype& pdt, TypeNode tnp, Node c, Kind pk, int arg ); + int solveForArgument( TypeNode tnp, unsigned cindex, unsigned arg ); + +//for eager instantiation +private: + std::map< Node, std::map< Node, bool > > d_subterms; + std::map< Node, std::vector< Node > > d_evals; + std::map< Node, std::vector< std::vector< Node > > > d_eval_args; + std::map< Node, std::vector< bool > > d_eval_args_const; + std::map< Node, std::map< Node, unsigned > > d_node_mv_args_proc; + + void getExplanationFor( TermRecBuild& trb, Node n, Node vn, std::vector< Node >& exp, std::map< TypeNode, int >& var_count, + SygusInvarianceTest& et, Node vnr, Node& vnr_exp, int& sz ); +public: + void registerEvalTerm( Node n ); + void registerModelValue( Node n, Node v, std::vector< Node >& exps, std::vector< Node >& terms, std::vector< Node >& vals ); + Node unfold( Node en, std::map< Node, Node >& vtm, std::vector< Node >& exp, bool track_exp = true ); + Node unfold( Node en ){ + std::map< Node, Node > vtm; + std::vector< Node > exp; + return unfold( en, vtm, exp, false ); + } + Node getEagerUnfold( Node n, std::map< Node, Node >& visited ); + // returns straightforward exp => n = vn + void getExplanationForConstantEquality( Node n, Node vn, std::vector< Node >& exp ); + void getExplanationForConstantEquality( Node n, Node vn, std::vector< Node >& exp, std::map< unsigned, bool >& cexc ); + Node getExplanationForConstantEquality( Node n, Node vn ); + Node getExplanationForConstantEquality( Node n, Node vn, std::map< unsigned, bool >& cexc ); + // we have n = vn => eval( n ) = bvr, returns exp => eval( n ) = bvr + // ensures the explanation still allows for vnr + void getExplanationFor( Node n, Node vn, std::vector< Node >& exp, SygusInvarianceTest& et, Node vnr, unsigned& sz ); + void getExplanationFor( Node n, Node vn, std::vector< Node >& exp, SygusInvarianceTest& et ); + // builtin evaluation, returns rewrite( bn [ args / vars(tn) ] ) + Node evaluateBuiltin( TypeNode tn, Node bn, std::vector< Node >& args ); + Node evaluateBuiltin( TypeNode tn, Node bn, Node ar, unsigned i ); + // evaluate with unfolding + Node evaluateWithUnfolding( Node n, std::map< Node, Node >& visited ); + Node evaluateWithUnfolding( Node n ); +//for calculating redundant operators +private: + //whether each constructor is redundant + // 0 : not redundant, 1 : redundant, 2 : partially redundant + std::map< TypeNode, std::vector< int > > d_sygus_red_status; + // type to (rewritten) to original + std::map< TypeNode, std::map< Node, Node > > d_gen_terms; + std::map< TypeNode, std::map< Node, bool > > d_gen_redundant; + //compute generic redundant + bool computeGenericRedundant( TypeNode tn, Node g ); +public: + bool isGenericRedundant( TypeNode tn, unsigned i ); + +//sygus pbe +private: + std::map< Node, std::vector< std::vector< Node > > > d_pbe_exs; + std::map< Node, std::vector< Node > > d_pbe_exos; + std::map< Node, unsigned > d_pbe_term_id; +private: + class PbeTrie { + private: + Node addPbeExampleEval( TypeNode etn, Node e, Node b, std::vector< Node >& ex, quantifiers::TermDbSygus * tds, unsigned index, unsigned ntotal ); + public: + PbeTrie(){} + ~PbeTrie(){} + Node d_lazy_child; + std::map< Node, PbeTrie > d_children; + void clear() { d_children.clear(); } + Node addPbeExample( TypeNode etn, Node e, Node b, TermDbSygus * tds, unsigned index, unsigned ntotal ); + }; + std::map< Node, std::map< TypeNode, PbeTrie > > d_pbe_trie; +public: + /** register examples for an enumerative search term. + This should be a comprehensive set of examples. */ + void registerPbeExamples( Node e, std::vector< std::vector< Node > >& exs, + std::vector< Node >& exos, std::vector< Node >& exts ); + /** get examples */ + bool hasPbeExamples( Node e ); + unsigned getNumPbeExamples( Node e ); + /** return value is the required value for the example */ + void getPbeExample( Node e, unsigned i, std::vector< Node >& ex ); + Node getPbeExampleOut( Node e, unsigned i ); + int getPbeExampleId( Node n ); + /** add the search val, returns an equivalent value (possibly the same) */ + Node addPbeSearchVal( TypeNode tn, Node e, Node bvr ); + +// extended rewriting +private: + std::map< Node, Node > d_ext_rewrite_cache; + Node extendedRewritePullIte( Node n ); +public: + Node extendedRewrite( Node n ); + +// for default grammar construction +private: + TypeNode mkUnresolvedType(const std::string& name, std::set<Type>& unres); + void mkSygusConstantsForType( TypeNode type, std::vector<CVC4::Node>& ops ); + void collectSygusGrammarTypesFor( TypeNode range, std::vector< TypeNode >& types, std::map< TypeNode, std::vector< DatatypeConstructorArg > >& sels ); + void mkSygusDefaultGrammar( TypeNode range, Node bvl, const std::string& fun, std::map< TypeNode, std::vector< Node > >& extra_cons, std::vector< CVC4::Datatype >& datatypes, std::set<Type>& unres ); +public: + TypeNode mkSygusDefaultType( TypeNode range, Node bvl, const std::string& fun, std::map< TypeNode, std::vector< Node > >& extra_cons ); + TypeNode mkSygusDefaultType( TypeNode range, Node bvl, const std::string& fun ){ + std::map< TypeNode, std::vector< Node > > extra_cons; + return mkSygusDefaultType( range, bvl, fun, extra_cons ); + } +}; + +}/* CVC4::theory::quantifiers namespace */ +}/* CVC4::theory namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_H */ diff --git a/src/theory/quantifiers/theory_quantifiers.cpp b/src/theory/quantifiers/theory_quantifiers.cpp index 7321f00c4..00a358e5f 100644 --- a/src/theory/quantifiers/theory_quantifiers.cpp +++ b/src/theory/quantifiers/theory_quantifiers.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -43,6 +43,8 @@ TheoryQuantifiers::TheoryQuantifiers(Context* c, context::UserContext* u, Output out.handleUserAttribute( "conjecture", this ); out.handleUserAttribute( "fun-def", this ); out.handleUserAttribute( "sygus", this ); + out.handleUserAttribute( "sygus-synth-fun", this ); + out.handleUserAttribute( "sygus-synth-fun-var-list", this ); out.handleUserAttribute( "synthesis", this ); out.handleUserAttribute( "quant-inst-max-level", this ); out.handleUserAttribute( "rr-priority", this ); diff --git a/src/theory/quantifiers/theory_quantifiers.h b/src/theory/quantifiers/theory_quantifiers.h index 38552d333..9c621dbd6 100644 --- a/src/theory/quantifiers/theory_quantifiers.h +++ b/src/theory/quantifiers/theory_quantifiers.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,25 +19,19 @@ #ifndef __CVC4__THEORY__QUANTIFIERS__THEORY_QUANTIFIERS_H #define __CVC4__THEORY__QUANTIFIERS__THEORY_QUANTIFIERS_H -#include <ext/hash_set> -#include <iostream> -#include <map> - #include "context/cdhashmap.h" +#include "context/context.h" +#include "expr/node.h" +#include "theory/output_channel.h" #include "theory/theory.h" -#include "util/hash.h" +#include "theory/theory_engine.h" +#include "theory/valuation.h" #include "util/statistics_registry.h" namespace CVC4 { -class TheoryEngine; - namespace theory { - namespace quantifiers { -class ModelEngine; -class InstantiationEngine; - class TheoryQuantifiers : public Theory { private: typedef context::CDHashMap< Node, bool, NodeHashFunction > BoolMap; diff --git a/src/theory/quantifiers/theory_quantifiers_type_rules.h b/src/theory/quantifiers/theory_quantifiers_type_rules.h index 6ba57afb4..f3e68b9f9 100644 --- a/src/theory/quantifiers/theory_quantifiers_type_rules.h +++ b/src/theory/quantifiers/theory_quantifiers_type_rules.h @@ -2,9 +2,9 @@ /*! \file theory_quantifiers_type_rules.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tim King + ** Andrew Reynolds, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/quantifiers/trigger.cpp b/src/theory/quantifiers/trigger.cpp index f2a4e6d17..20933c7f7 100644 --- a/src/theory/quantifiers/trigger.cpp +++ b/src/theory/quantifiers/trigger.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -398,49 +398,46 @@ bool Trigger::isSimpleTrigger( Node n ){ } //store triggers in reqPol, indicating their polarity (if any) they must appear to falsify the quantified formula -void Trigger::collectPatTerms2( Node q, Node n, std::map< Node, Node >& visited, std::map< Node, TriggerTermInfo >& tinfo, +void Trigger::collectPatTerms2( Node q, Node n, std::map< Node, std::vector< Node > >& visited, std::map< Node, TriggerTermInfo >& tinfo, quantifiers::TriggerSelMode tstrt, std::vector< Node >& exclude, std::vector< Node >& added, - bool pol, bool hasPol, bool epol, bool hasEPol ){ - std::map< Node, Node >::iterator itv = visited.find( n ); + bool pol, bool hasPol, bool epol, bool hasEPol, bool knowIsUsable ){ + std::map< Node, std::vector< Node > >::iterator itv = visited.find( n ); if( itv==visited.end() ){ - visited[ n ] = Node::null(); + visited[ n ].clear(); Trace("auto-gen-trigger-debug2") << "Collect pat terms " << n << " " << pol << " " << hasPol << " " << epol << " " << hasEPol << std::endl; if( n.getKind()!=FORALL && n.getKind()!=INST_CONSTANT ){ Node nu; bool nu_single = false; - if( n.getKind()!=NOT && std::find( exclude.begin(), exclude.end(), n )==exclude.end() ){ + if( knowIsUsable ){ + nu = n; + }else if( n.getKind()!=NOT && std::find( exclude.begin(), exclude.end(), n )==exclude.end() ){ nu = getIsUsableTrigger( n, q ); - if( !nu.isNull() ){ - Assert( nu.getKind()!=NOT ); - Trace("auto-gen-trigger-debug2") << "...found usable trigger : " << nu << std::endl; - Node reqEq; - if( nu.getKind()==EQUAL ){ - if( isAtomicTrigger( nu[0] ) && !quantifiers::TermDb::hasInstConstAttr(nu[1]) ){ - if( hasPol ){ - reqEq = nu[1]; - } - nu = nu[0]; - } - } - Assert( reqEq.isNull() || !quantifiers::TermDb::hasInstConstAttr( reqEq ) ); - Assert( isUsableTrigger( nu, q ) ); - //do not add if already visited - bool add = true; - if( n!=nu ){ - std::map< Node, Node >::iterator itvu = visited.find( nu ); - if( itvu!=visited.end() ){ - add = false; + if( !nu.isNull() && nu!=n ){ + collectPatTerms2( q, nu, visited, tinfo, tstrt, exclude, added, pol, hasPol, epol, hasEPol, true ); + // copy to n + visited[n].insert( visited[n].end(), added.begin(), added.end() ); + return; + } + } + if( !nu.isNull() ){ + Assert( nu==n ); + Assert( nu.getKind()!=NOT ); + Trace("auto-gen-trigger-debug2") << "...found usable trigger : " << nu << std::endl; + Node reqEq; + if( nu.getKind()==EQUAL ){ + if( isAtomicTrigger( nu[0] ) && !quantifiers::TermDb::hasInstConstAttr(nu[1]) ){ + if( hasPol ){ + reqEq = nu[1]; } - } - if( add ){ - Trace("auto-gen-trigger-debug2") << "...add usable trigger : " << nu << std::endl; - visited[ nu ] = nu; - tinfo[ nu ].init( q, nu, hasEPol ? ( epol ? 1 : -1 ) : 0, reqEq ); - nu_single = tinfo[ nu ].d_fv.size()==q[0].getNumChildren(); - }else{ - nu = Node::null(); + nu = nu[0]; } } + Assert( reqEq.isNull() || !quantifiers::TermDb::hasInstConstAttr( reqEq ) ); + Assert( isUsableTrigger( nu, q ) ); + //tinfo.find( nu )==tinfo.end() + Trace("auto-gen-trigger-debug2") << "...add usable trigger : " << nu << std::endl; + tinfo[ nu ].init( q, nu, hasEPol ? ( epol ? 1 : -1 ) : 0, reqEq ); + nu_single = tinfo[ nu ].d_fv.size()==q[0].getNumChildren(); } Node nrec = nu.isNull() ? n : nu; std::vector< Node > added2; @@ -451,6 +448,7 @@ void Trigger::collectPatTerms2( Node q, Node n, std::map< Node, Node >& visited, QuantPhaseReq::getEntailPolarity( nrec, i, hasEPol, epol, newHasEPol, newEPol ); collectPatTerms2( q, nrec[i], visited, tinfo, tstrt, exclude, added2, newPol, newHasPol, newEPol, newHasEPol ); } + // if this is not a usable trigger, don't worry about caching the results, since triggers do not contain non-usable subterms if( !nu.isNull() ){ bool rm_nu = false; for( unsigned i=0; i<added2.size(); i++ ){ @@ -461,7 +459,7 @@ void Trigger::collectPatTerms2( Node q, Node n, std::map< Node, Node >& visited, if( tstrt==quantifiers::TRIGGER_SEL_MAX || ( tstrt==quantifiers::TRIGGER_SEL_MIN_SINGLE_MAX && !nu_single ) ){ //discard all subterms Trace("auto-gen-trigger-debug2") << "......remove it." << std::endl; - visited[added2[i]] = Node::null(); + visited[ added2[i] ].clear(); tinfo.erase( added2[i] ); }else{ if( tinfo[ nu ].d_fv.size()==tinfo[ added2[i] ].d_fv.size() ){ @@ -476,18 +474,20 @@ void Trigger::collectPatTerms2( Node q, Node n, std::map< Node, Node >& visited, } } if( rm_nu && ( tstrt==quantifiers::TRIGGER_SEL_MIN || ( tstrt==quantifiers::TRIGGER_SEL_MIN_SINGLE_ALL && nu_single ) ) ){ - visited[nu] = Node::null(); tinfo.erase( nu ); }else{ - Assert( std::find( added.begin(), added.end(), nu )==added.end() ); - added.push_back( nu ); + if( std::find( added.begin(), added.end(), nu )==added.end() ){ + added.push_back( nu ); + } } + visited[n].insert( visited[n].end(), added.begin(), added.end() ); } } }else{ - if( !itv->second.isNull() ){ - if( std::find( added.begin(), added.end(), itv->second )==added.end() ){ - added.push_back( itv->second ); + for( unsigned i=0; i<itv->second.size(); ++i ){ + Node t = itv->second[i]; + if( std::find( added.begin(), added.end(), t )==added.end() ){ + added.push_back( t ); } } } @@ -573,7 +573,7 @@ bool Trigger::isLocalTheoryExt( Node n, std::vector< Node >& vars, std::vector< void Trigger::collectPatTerms( Node q, Node n, std::vector< Node >& patTerms, quantifiers::TriggerSelMode tstrt, std::vector< Node >& exclude, std::map< Node, TriggerTermInfo >& tinfo, bool filterInst ){ - std::map< Node, Node > visited; + std::map< Node, std::vector< Node > > visited; if( filterInst ){ //immediately do not consider any term t for which another term is an instance of t std::vector< Node > patTerms2; @@ -607,7 +607,7 @@ void Trigger::collectPatTerms( Node q, Node n, std::vector< Node >& patTerms, qu //do not consider terms that have instances for( unsigned i=0; i<patTerms2.size(); i++ ){ if( std::find( temp.begin(), temp.end(), patTerms2[i] )==temp.end() ){ - visited[ patTerms2[i] ] = Node::null(); + visited[ patTerms2[i] ].clear(); } } } @@ -615,9 +615,7 @@ void Trigger::collectPatTerms( Node q, Node n, std::vector< Node >& patTerms, qu std::vector< Node > added; collectPatTerms2( q, n, visited, tinfo, tstrt, exclude, added, true, true, false, true ); for( std::map< Node, TriggerTermInfo >::iterator it = tinfo.begin(); it != tinfo.end(); ++it ){ - if( !visited[it->first].isNull() ){ - patTerms.push_back( it->first ); - } + patTerms.push_back( it->first ); } } diff --git a/src/theory/quantifiers/trigger.h b/src/theory/quantifiers/trigger.h index 234025e7b..afab98cee 100644 --- a/src/theory/quantifiers/trigger.h +++ b/src/theory/quantifiers/trigger.h @@ -2,9 +2,9 @@ /*! \file trigger.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Andrew Reynolds + ** Andrew Reynolds, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -137,9 +137,9 @@ private: static Node getIsUsableEq( Node q, Node eq ); static bool isUsableEqTerms( Node q, Node n1, Node n2 ); /** collect all APPLY_UF pattern terms for f in n */ - static void collectPatTerms2( Node q, Node n, std::map< Node, Node >& visited, std::map< Node, TriggerTermInfo >& tinfo, + static void collectPatTerms2( Node q, Node n, std::map< Node, std::vector< Node > >& visited, std::map< Node, TriggerTermInfo >& tinfo, quantifiers::TriggerSelMode tstrt, std::vector< Node >& exclude, std::vector< Node >& added, - bool pol, bool hasPol, bool epol, bool hasEPol ); + bool pol, bool hasPol, bool epol, bool hasEPol, bool knowIsUsable = false ); std::vector< Node > d_nodes; diff --git a/src/theory/quantifiers_engine.cpp b/src/theory/quantifiers_engine.cpp index 501d77ecf..fa1394f39 100644 --- a/src/theory/quantifiers_engine.cpp +++ b/src/theory/quantifiers_engine.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -1882,7 +1882,7 @@ Node EqualityQueryQuantifiersEngine::getInternalRepresentative( Node a, Node f, r_best = r; } //now, make sure that no other member of the class is an instance - std::hash_map<TNode, Node, TNodeHashFunction> cache; + std::unordered_map<TNode, Node, TNodeHashFunction> cache; r_best = getInstance( r_best, eqc, cache ); //store that this representative was chosen at this point if( d_rep_score.find( r_best )==d_rep_score.end() ){ @@ -2001,7 +2001,7 @@ TNode EqualityQueryQuantifiersEngine::getCongruentTerm( Node f, std::vector< TNo //helper functions -Node EqualityQueryQuantifiersEngine::getInstance( Node n, const std::vector< Node >& eqc, std::hash_map<TNode, Node, TNodeHashFunction>& cache ){ +Node EqualityQueryQuantifiersEngine::getInstance( Node n, const std::vector< Node >& eqc, std::unordered_map<TNode, Node, TNodeHashFunction>& cache ){ if(cache.find(n) != cache.end()) { return cache[n]; } diff --git a/src/theory/quantifiers_engine.h b/src/theory/quantifiers_engine.h index fff446eda..7d8f5354b 100644 --- a/src/theory/quantifiers_engine.h +++ b/src/theory/quantifiers_engine.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,9 +17,9 @@ #ifndef __CVC4__THEORY__QUANTIFIERS_ENGINE_H #define __CVC4__THEORY__QUANTIFIERS_ENGINE_H -#include <ext/hash_set> #include <iostream> #include <map> +#include <unordered_map> #include "context/cdchunk_list.h" #include "context/cdhashset.h" @@ -449,7 +449,7 @@ private: /** processInferences : will merge equivalence classes in master equality engine, if possible */ bool processInferences( Theory::Effort e ); /** node contains */ - Node getInstance( Node n, const std::vector< Node >& eqc, std::hash_map<TNode, Node, TNodeHashFunction>& cache ); + Node getInstance( Node n, const std::vector< Node >& eqc, std::unordered_map<TNode, Node, TNodeHashFunction>& cache ); /** get score */ int getRepScore( Node n, Node f, int index, TypeNode v_tn ); /** flatten representatives */ diff --git a/src/theory/rep_set.cpp b/src/theory/rep_set.cpp index c308b9c67..cd1fac290 100644 --- a/src/theory/rep_set.cpp +++ b/src/theory/rep_set.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/rep_set.h b/src/theory/rep_set.h index 9368d3681..41044b526 100644 --- a/src/theory/rep_set.h +++ b/src/theory/rep_set.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/rewriter.cpp b/src/theory/rewriter.cpp index 0df122571..0c20c48a4 100644 --- a/src/theory/rewriter.cpp +++ b/src/theory/rewriter.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Morgan Deters, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -35,7 +35,7 @@ static TheoryId theoryOf(TNode node) { } #ifdef CVC4_ASSERTIONS -static CVC4_THREADLOCAL(std::hash_set<Node, NodeHashFunction>*) s_rewriteStack = NULL; +static CVC4_THREADLOCAL(std::unordered_set<Node, NodeHashFunction>*) s_rewriteStack = NULL; #endif /* CVC4_ASSERTIONS */ class RewriterInitializer { @@ -94,7 +94,7 @@ Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) { bool isEquality = node.getKind() == kind::EQUAL && (!node[0].getType().isBoolean()); if(s_rewriteStack == NULL) { - s_rewriteStack = new std::hash_set<Node, NodeHashFunction>(); + s_rewriteStack = new std::unordered_set<Node, NodeHashFunction>(); } #endif diff --git a/src/theory/rewriter.h b/src/theory/rewriter.h index aed93a451..ba8b12fb6 100644 --- a/src/theory/rewriter.h +++ b/src/theory/rewriter.h @@ -2,9 +2,9 @@ /*! \file rewriter.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/rewriter_attributes.h b/src/theory/rewriter_attributes.h index 5f709de6a..ec120ff0c 100644 --- a/src/theory/rewriter_attributes.h +++ b/src/theory/rewriter_attributes.h @@ -2,9 +2,9 @@ /*! \file rewriter_attributes.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/rewriter_tables_template.h b/src/theory/rewriter_tables_template.h index 4d41c023d..9ea9a9695 100644 --- a/src/theory/rewriter_tables_template.h +++ b/src/theory/rewriter_tables_template.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/sep/theory_sep.cpp b/src/theory/sep/theory_sep.cpp index 9d064d74d..93d4124d9 100644 --- a/src/theory/sep/theory_sep.cpp +++ b/src/theory/sep/theory_sep.cpp @@ -1,13 +1,13 @@ /********************* */ /*! \file theory_sep.cpp ** \verbatim - ** Original author: Andrew Reynolds - ** Major contributors: none - ** Minor contributors (to current version): none + ** Top contributors (to current version): + ** Andrew Reynolds, Tim King, Mathias Preiner ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** 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 Implementation of the theory of sep. ** diff --git a/src/theory/sep/theory_sep.h b/src/theory/sep/theory_sep.h index 8dd1ed356..1786584d4 100644 --- a/src/theory/sep/theory_sep.h +++ b/src/theory/sep/theory_sep.h @@ -1,13 +1,13 @@ /********************* */ /*! \file theory_sep.h ** \verbatim - ** Original author: Andrew Reynolds - ** Major contributors: Dejan Jovanovic, Clark Barrett - ** Minor contributors (to current version): Tim King, Andrew Reynolds + ** Top contributors (to current version): + ** Andrew Reynolds, Mathias Preiner, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** 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 Theory of sep ** diff --git a/src/theory/sep/theory_sep_rewriter.cpp b/src/theory/sep/theory_sep_rewriter.cpp index 0faf7b176..513eada3f 100644 --- a/src/theory/sep/theory_sep_rewriter.cpp +++ b/src/theory/sep/theory_sep_rewriter.cpp @@ -1,13 +1,13 @@ /********************* */ /*! \file theory_sep_rewriter.cpp ** \verbatim - ** Original author: Andrew Reynolds - ** Major contributors: none - ** Minor contributors (to current version): none + ** Top contributors (to current version): + ** Andrew Reynolds, Mathias Preiner ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** 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 [[ Add one-line brief description here ]] ** diff --git a/src/theory/sep/theory_sep_rewriter.h b/src/theory/sep/theory_sep_rewriter.h index 58b79c7fd..61b2ee36a 100644 --- a/src/theory/sep/theory_sep_rewriter.h +++ b/src/theory/sep/theory_sep_rewriter.h @@ -1,13 +1,13 @@ /********************* */ /*! \file theory_sep_rewriter.h ** \verbatim - ** Original author: Andrew Reynolds - ** Major contributors: none - ** Minor contributors (to current version): none + ** Top contributors (to current version): + ** Andrew Reynolds, Mathias Preiner ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** 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 [[ Add one-line brief description here ]] ** diff --git a/src/theory/sep/theory_sep_type_rules.h b/src/theory/sep/theory_sep_type_rules.h index 0eae782c8..e9177e004 100644 --- a/src/theory/sep/theory_sep_type_rules.h +++ b/src/theory/sep/theory_sep_type_rules.h @@ -1,13 +1,13 @@ /********************* */ /*! \file theory_sep_type_rules.h ** \verbatim - ** Original author: Andrew Reynolds - ** Major contributors: none - ** Minor contributors (to current version): none + ** Top contributors (to current version): + ** Andrew Reynolds, Mathias Preiner ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** 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 Typing and cardinality rules for the theory of sep ** diff --git a/src/theory/sets/normal_form.h b/src/theory/sets/normal_form.h index 6379fb299..bb715ff8c 100644 --- a/src/theory/sets/normal_form.h +++ b/src/theory/sets/normal_form.h @@ -2,9 +2,9 @@ /*! \file normal_form.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King + ** Kshitij Bansal, Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/sets/rels_utils.h b/src/theory/sets/rels_utils.h index df14bf53b..d179c447e 100644 --- a/src/theory/sets/rels_utils.h +++ b/src/theory/sets/rels_utils.h @@ -1,13 +1,13 @@ /********************* */ /*! \file rels_utils.h ** \verbatim - ** Original author: Paul Meng - ** Major contributors: none - ** Minor contributors (to current version): none + ** Top contributors (to current version): + ** Andrew Reynolds, Mathias Preiner ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** 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 Sets theory implementation. ** @@ -66,8 +66,9 @@ public: if( tuple.getKind() == kind::APPLY_CONSTRUCTOR ) { return tuple[n_th]; } - Datatype dt = tuple.getType().getDatatype(); - return NodeManager::currentNM()->mkNode(kind::APPLY_SELECTOR_TOTAL, dt[0][n_th].getSelector(), tuple); + TypeNode tn = tuple.getType(); + Datatype dt = tn.getDatatype(); + return NodeManager::currentNM()->mkNode(kind::APPLY_SELECTOR_TOTAL, dt[0].getSelectorInternal( tn.toType(), n_th ), tuple); } static Node reverseTuple( Node tuple ) { diff --git a/src/theory/sets/theory_sets.cpp b/src/theory/sets/theory_sets.cpp index 9cf355f15..4992f654f 100644 --- a/src/theory/sets/theory_sets.cpp +++ b/src/theory/sets/theory_sets.cpp @@ -2,9 +2,9 @@ /*! \file theory_sets.cpp ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King, Morgan Deters + ** Kshitij Bansal, Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/sets/theory_sets.h b/src/theory/sets/theory_sets.h index 8f81b9d2a..bbc6ae0c4 100644 --- a/src/theory/sets/theory_sets.h +++ b/src/theory/sets/theory_sets.h @@ -2,9 +2,9 @@ /*! \file theory_sets.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King + ** Kshitij Bansal, Paul Meng, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/sets/theory_sets_private.cpp b/src/theory/sets/theory_sets_private.cpp index a0748f2b9..a2a56e137 100644 --- a/src/theory/sets/theory_sets_private.cpp +++ b/src/theory/sets/theory_sets_private.cpp @@ -2,9 +2,9 @@ /*! \file theory_sets_private.cpp ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King, Andrew Reynolds + ** Andrew Reynolds, Kshitij Bansal, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,8 +17,6 @@ #include <algorithm> #include "theory/sets/theory_sets_private.h" -#include <boost/foreach.hpp> - #include "expr/emptyset.h" #include "options/sets_options.h" #include "smt/smt_statistics_registry.h" @@ -56,7 +54,7 @@ TheorySetsPrivate::TheorySetsPrivate(TheorySets& external, { d_rels = new TheorySetsRels(c, u, &d_equalityEngine, &d_conflict, external); - + d_true = NodeManager::currentNM()->mkConst( true ); d_false = NodeManager::currentNM()->mkConst( false ); d_zero = NodeManager::currentNM()->mkConst( Rational(0) ); @@ -79,9 +77,8 @@ TheorySetsPrivate::TheorySetsPrivate(TheorySets& external, TheorySetsPrivate::~TheorySetsPrivate(){ delete d_rels; - for(std::map< Node, EqcInfo* >::iterator i = d_eqc_info.begin(), iend = d_eqc_info.end(); i != iend; ++i){ - EqcInfo* current = (*i).second; - delete current; + for (std::pair<const Node, EqcInfo*>& current_pair : d_eqc_info) { + delete current_pair.second; } }/* TheorySetsPrivate::~TheorySetsPrivate() */ diff --git a/src/theory/sets/theory_sets_private.h b/src/theory/sets/theory_sets_private.h index 667b7f253..7bc17c927 100644 --- a/src/theory/sets/theory_sets_private.h +++ b/src/theory/sets/theory_sets_private.h @@ -2,9 +2,9 @@ /*! \file theory_sets_private.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King, Andrew Reynolds + ** Andrew Reynolds, Kshitij Bansal, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/sets/theory_sets_rels.cpp b/src/theory/sets/theory_sets_rels.cpp index 03e0c64f8..beb5e946c 100644 --- a/src/theory/sets/theory_sets_rels.cpp +++ b/src/theory/sets/theory_sets_rels.cpp @@ -1,13 +1,13 @@ /********************* */ /*! \file theory_sets_rels.cpp ** \verbatim - ** Original author: Paul Meng - ** Major contributors: none - ** Minor contributors (to current version): none + ** Top contributors (to current version): + ** Paul Meng, Andrew Reynolds, Mathias Preiner ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** 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 Sets theory implementation. ** @@ -27,9 +27,9 @@ namespace sets { typedef std::map< Node, std::vector< Node > >::iterator MEM_IT; typedef std::map< kind::Kind_t, std::vector< Node > >::iterator KIND_TERM_IT; -typedef std::map< Node, std::hash_set< Node, NodeHashFunction > >::iterator TC_GRAPH_IT; +typedef std::map< Node, std::unordered_set< Node, NodeHashFunction > >::iterator TC_GRAPH_IT; typedef std::map< Node, std::map< kind::Kind_t, std::vector< Node > > >::iterator TERM_IT; -typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > > >::iterator TC_IT; +typedef std::map< Node, std::map< Node, std::unordered_set< Node, NodeHashFunction > > >::iterator TC_IT; void TheorySetsRels::check(Theory::Effort level) { Trace("rels") << "\n[sets-rels] ******************************* Start the relational solver, effort = " << level << " *******************************\n" << std::endl; @@ -240,7 +240,7 @@ typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > } Node join_image_rel = join_image_term[0]; - std::hash_set< Node, NodeHashFunction > hasChecked; + std::unordered_set< Node, NodeHashFunction > hasChecked; Node join_image_rel_rep = getRepresentative( join_image_rel ); std::vector< Node >::iterator mem_rep_it = (*rel_mem_it).second.begin(); MEM_IT rel_mem_exp_it = d_rReps_memberReps_exp_cache.find( join_image_rel_rep ); @@ -480,14 +480,14 @@ typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > if( tc_graph_it != (tc_it->second).end() ) { (tc_graph_it->second).insert( mem_rep_snd ); } else { - std::hash_set< Node, NodeHashFunction > sets; + std::unordered_set< Node, NodeHashFunction > sets; sets.insert( mem_rep_snd ); (tc_it->second)[mem_rep_fst] = sets; } } else { std::map< Node, Node > exp_map; - std::hash_set< Node, NodeHashFunction > sets; - std::map< Node, std::hash_set<Node, NodeHashFunction> > element_map; + std::unordered_set< Node, NodeHashFunction > sets; + std::map< Node, std::unordered_set<Node, NodeHashFunction> > element_map; sets.insert( mem_rep_snd ); element_map[mem_rep_fst] = sets; d_tcr_tcGraph[tc_rel] = element_map; @@ -529,7 +529,7 @@ typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > TC_IT tc_it = d_rRep_tcGraph.find( getRepresentative(tc_rel[0]) ); if( tc_it != d_rRep_tcGraph.end() ) { bool isReachable = false; - std::hash_set<Node, NodeHashFunction> seen; + std::unordered_set<Node, NodeHashFunction> seen; isTCReachable( getRepresentative( RelsUtils::nthElementOfTuple(mem_rep, 0) ), getRepresentative( RelsUtils::nthElementOfTuple(mem_rep, 1) ), seen, tc_it->second, isReachable ); return isReachable; @@ -537,8 +537,8 @@ typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > return false; } - void TheorySetsRels::isTCReachable( Node start, Node dest, std::hash_set<Node, NodeHashFunction>& hasSeen, - std::map< Node, std::hash_set< Node, NodeHashFunction > >& tc_graph, bool& isReachable ) { + void TheorySetsRels::isTCReachable( Node start, Node dest, std::unordered_set<Node, NodeHashFunction>& hasSeen, + std::map< Node, std::unordered_set< Node, NodeHashFunction > >& tc_graph, bool& isReachable ) { if(hasSeen.find(start) == hasSeen.end()) { hasSeen.insert(start); } @@ -550,7 +550,7 @@ typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > isReachable = true; return; } else { - std::hash_set< Node, NodeHashFunction >::iterator set_it = pair_set_it->second.begin(); + std::unordered_set< Node, NodeHashFunction >::iterator set_it = pair_set_it->second.begin(); while( set_it != pair_set_it->second.end() ) { // need to check if *set_it has been looked already @@ -565,7 +565,7 @@ typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > void TheorySetsRels::buildTCGraphForRel( Node tc_rel ) { std::map< Node, Node > rel_tc_graph_exps; - std::map< Node, std::hash_set<Node, NodeHashFunction> > rel_tc_graph; + std::map< Node, std::unordered_set<Node, NodeHashFunction> > rel_tc_graph; Node rel_rep = getRepresentative( tc_rel[0] ); Node tc_rel_rep = getRepresentative( tc_rel ); @@ -576,10 +576,10 @@ typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > Node fst_element_rep = getRepresentative( RelsUtils::nthElementOfTuple( members[i], 0 )); Node snd_element_rep = getRepresentative( RelsUtils::nthElementOfTuple( members[i], 1 )); Node tuple_rep = RelsUtils::constructPair( rel_rep, fst_element_rep, snd_element_rep ); - std::map< Node, std::hash_set<Node, NodeHashFunction> >::iterator rel_tc_graph_it = rel_tc_graph.find( fst_element_rep ); + std::map< Node, std::unordered_set<Node, NodeHashFunction> >::iterator rel_tc_graph_it = rel_tc_graph.find( fst_element_rep ); if( rel_tc_graph_it == rel_tc_graph.end() ) { - std::hash_set< Node, NodeHashFunction > snd_elements; + std::unordered_set< Node, NodeHashFunction > snd_elements; snd_elements.insert( snd_element_rep ); rel_tc_graph[fst_element_rep] = snd_elements; rel_tc_graph_exps[tuple_rep] = exps[i]; @@ -596,13 +596,13 @@ typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > } } - void TheorySetsRels::doTCInference( std::map< Node, std::hash_set<Node, NodeHashFunction> > rel_tc_graph, std::map< Node, Node > rel_tc_graph_exps, Node tc_rel ) { + void TheorySetsRels::doTCInference( std::map< Node, std::unordered_set<Node, NodeHashFunction> > rel_tc_graph, std::map< Node, Node > rel_tc_graph_exps, Node tc_rel ) { Trace("rels-debug") << "[Theory::Rels] ****** doTCInference !" << std::endl; for( TC_GRAPH_IT tc_graph_it = rel_tc_graph.begin(); tc_graph_it != rel_tc_graph.end(); tc_graph_it++ ) { - for( std::hash_set< Node, NodeHashFunction >::iterator snd_elements_it = tc_graph_it->second.begin(); + for( std::unordered_set< Node, NodeHashFunction >::iterator snd_elements_it = tc_graph_it->second.begin(); snd_elements_it != tc_graph_it->second.end(); snd_elements_it++ ) { std::vector< Node > reasons; - std::hash_set<Node, NodeHashFunction> seen; + std::unordered_set<Node, NodeHashFunction> seen; Node tuple = RelsUtils::constructPair( tc_rel, getRepresentative( tc_graph_it->first ), getRepresentative( *snd_elements_it) ); Assert( rel_tc_graph_exps.find( tuple ) != rel_tc_graph_exps.end() ); Node exp = rel_tc_graph_exps.find( tuple )->second; @@ -615,8 +615,8 @@ typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > Trace("rels-debug") << "[Theory::Rels] ****** Done with doTCInference !" << std::endl; } - void TheorySetsRels::doTCInference(Node tc_rel, std::vector< Node > reasons, std::map< Node, std::hash_set< Node, NodeHashFunction > >& tc_graph, - std::map< Node, Node >& rel_tc_graph_exps, Node start_node_rep, Node cur_node_rep, std::hash_set< Node, NodeHashFunction >& seen ) { + void TheorySetsRels::doTCInference(Node tc_rel, std::vector< Node > reasons, std::map< Node, std::unordered_set< Node, NodeHashFunction > >& tc_graph, + std::map< Node, Node >& rel_tc_graph_exps, Node start_node_rep, Node cur_node_rep, std::unordered_set< Node, NodeHashFunction >& seen ) { Node tc_mem = RelsUtils::constructPair( tc_rel, RelsUtils::nthElementOfTuple((reasons.front())[0], 0), RelsUtils::nthElementOfTuple((reasons.back())[0], 1) ); std::vector< Node > all_reasons( reasons ); @@ -646,7 +646,7 @@ typedef std::map< Node, std::map< Node, std::hash_set< Node, NodeHashFunction > seen.insert( cur_node_rep ); TC_GRAPH_IT cur_set = tc_graph.find( cur_node_rep ); if( cur_set != tc_graph.end() ) { - for( std::hash_set< Node, NodeHashFunction >::iterator set_it = cur_set->second.begin(); + for( std::unordered_set< Node, NodeHashFunction >::iterator set_it = cur_set->second.begin(); set_it != cur_set->second.end(); set_it++ ) { Node new_pair = RelsUtils::constructPair( tc_rel, cur_node_rep, *set_it ); std::vector< Node > new_reasons( reasons ); diff --git a/src/theory/sets/theory_sets_rels.h b/src/theory/sets/theory_sets_rels.h index 576430eb1..eb97405dc 100644 --- a/src/theory/sets/theory_sets_rels.h +++ b/src/theory/sets/theory_sets_rels.h @@ -1,13 +1,13 @@ /********************* */ /*! \file theory_sets_rels.h ** \verbatim - ** Original author: Paul Meng - ** Major contributors: none - ** Minor contributors (to current version): none + ** Top contributors (to current version): + ** Andrew Reynolds, Paul Meng, Mathias Preiner ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2014 New York University and The University of Iowa - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim + ** 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 Sets theory implementation. ** @@ -17,11 +17,13 @@ #ifndef SRC_THEORY_SETS_THEORY_SETS_RELS_H_ #define SRC_THEORY_SETS_THEORY_SETS_RELS_H_ -#include "theory/theory.h" -#include "theory/uf/equality_engine.h" -#include "context/cdhashset.h" +#include <unordered_set> + #include "context/cdchunk_list.h" +#include "context/cdhashset.h" #include "theory/sets/rels_utils.h" +#include "theory/theory.h" +#include "theory/uf/equality_engine.h" namespace CVC4 { namespace theory { @@ -103,12 +105,12 @@ private: std::map< Node, Node > d_pending_facts; - std::hash_set< Node, NodeHashFunction > d_rel_nodes; + std::unordered_set< Node, NodeHashFunction > d_rel_nodes; std::map< Node, std::vector<Node> > d_tuple_reps; std::map< Node, TupleTrie > d_membership_trie; /** Symbolic tuple variables that has been reduced to concrete ones */ - std::hash_set< Node, NodeHashFunction > d_symbolic_tuples; + std::unordered_set< Node, NodeHashFunction > d_symbolic_tuples; /** Mapping between relation and its member representatives */ std::map< Node, std::vector< Node > > d_rReps_memberReps_cache; @@ -120,8 +122,8 @@ private: std::map< Node, std::map<kind::Kind_t, std::vector<Node> > > d_terms_cache; /** Mapping between transitive closure relation TC(r) and its TC graph constructed based on the members of r*/ - std::map< Node, std::map< Node, std::hash_set<Node, NodeHashFunction> > > d_rRep_tcGraph; - std::map< Node, std::map< Node, std::hash_set<Node, NodeHashFunction> > > d_tcr_tcGraph; + std::map< Node, std::map< Node, std::unordered_set<Node, NodeHashFunction> > > d_rRep_tcGraph; + std::map< Node, std::map< Node, std::unordered_set<Node, NodeHashFunction> > > d_tcr_tcGraph; std::map< Node, std::map< Node, Node > > d_tcr_tcGraph_exps; std::map< Node, std::vector< Node > > d_tc_lemmas_last; @@ -154,9 +156,9 @@ private: void applyTCRule( Node mem, Node rel, Node rel_rep, Node exp); void buildTCGraphForRel( Node tc_rel ); void doTCInference(); - void doTCInference( std::map< Node, std::hash_set<Node, NodeHashFunction> > rel_tc_graph, std::map< Node, Node > rel_tc_graph_exps, Node tc_rel ); - void doTCInference(Node tc_rel, std::vector< Node > reasons, std::map< Node, std::hash_set< Node, NodeHashFunction > >& tc_graph, - std::map< Node, Node >& rel_tc_graph_exps, Node start_node_rep, Node cur_node_rep, std::hash_set< Node, NodeHashFunction >& seen ); + void doTCInference( std::map< Node, std::unordered_set<Node, NodeHashFunction> > rel_tc_graph, std::map< Node, Node > rel_tc_graph_exps, Node tc_rel ); + void doTCInference(Node tc_rel, std::vector< Node > reasons, std::map< Node, std::unordered_set< Node, NodeHashFunction > >& tc_graph, + std::map< Node, Node >& rel_tc_graph_exps, Node start_node_rep, Node cur_node_rep, std::unordered_set< Node, NodeHashFunction >& seen ); void composeMembersForRels( Node ); void computeMembersForBinOpRel( Node ); @@ -165,8 +167,8 @@ private: void computeMembersForJoinImageTerm( Node ); bool isTCReachable( Node mem_rep, Node tc_rel ); - void isTCReachable( Node start, Node dest, std::hash_set<Node, NodeHashFunction>& hasSeen, - std::map< Node, std::hash_set< Node, NodeHashFunction > >& tc_graph, bool& isReachable ); + void isTCReachable( Node start, Node dest, std::unordered_set<Node, NodeHashFunction>& hasSeen, + std::map< Node, std::unordered_set< Node, NodeHashFunction > >& tc_graph, bool& isReachable ); void addSharedTerm( TNode n ); diff --git a/src/theory/sets/theory_sets_rewriter.cpp b/src/theory/sets/theory_sets_rewriter.cpp index e42a3347d..8c3fe67d3 100644 --- a/src/theory/sets/theory_sets_rewriter.cpp +++ b/src/theory/sets/theory_sets_rewriter.cpp @@ -2,9 +2,9 @@ /*! \file theory_sets_rewriter.cpp ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King + ** Andrew Reynolds, Paul Meng, Kshitij Bansal ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -25,7 +25,7 @@ namespace theory { namespace sets { typedef std::set<TNode> Elements; -typedef std::hash_map<TNode, Elements, TNodeHashFunction> SettermElementsMap; +typedef std::unordered_map<TNode, Elements, TNodeHashFunction> SettermElementsMap; struct FlattenedNodeTag {}; typedef expr::Attribute<FlattenedNodeTag, bool> flattened; @@ -50,7 +50,7 @@ RewriteResponse flattenNode(TNode n, TNode trivialNode, TNode skipNode) return RewriteResponse(REWRITE_DONE, n); } - typedef std::hash_set<TNode, TNodeHashFunction> node_set; + typedef std::unordered_set<TNode, TNodeHashFunction> node_set; node_set visited; visited.insert(skipNode); diff --git a/src/theory/sets/theory_sets_rewriter.h b/src/theory/sets/theory_sets_rewriter.h index 50128b63d..5cf0f8e19 100644 --- a/src/theory/sets/theory_sets_rewriter.h +++ b/src/theory/sets/theory_sets_rewriter.h @@ -2,9 +2,9 @@ /*! \file theory_sets_rewriter.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King + ** Kshitij Bansal, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/sets/theory_sets_type_enumerator.h b/src/theory/sets/theory_sets_type_enumerator.h index f2d6bae68..f261ac3fa 100644 --- a/src/theory/sets/theory_sets_type_enumerator.h +++ b/src/theory/sets/theory_sets_type_enumerator.h @@ -2,9 +2,9 @@ /*! \file theory_sets_type_enumerator.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Morgan Deters, Andrew Reynolds + ** Kshitij Bansal, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/sets/theory_sets_type_rules.h b/src/theory/sets/theory_sets_type_rules.h index a5a78e691..23b185230 100644 --- a/src/theory/sets/theory_sets_type_rules.h +++ b/src/theory/sets/theory_sets_type_rules.h @@ -2,9 +2,9 @@ /*! \file theory_sets_type_rules.h ** \verbatim ** Top contributors (to current version): - ** Kshitij Bansal, Tim King, Morgan Deters + ** Kshitij Bansal, Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -115,8 +115,29 @@ struct MemberTypeRule { throw TypeCheckingExceptionPrivate(n, "checking for membership in a non-set"); } TypeNode elementType = n[0].getType(check); + // TODO : still need to be flexible here due to situations like: + // + // T : (Set Int) + // S : (Set Real) + // (= (as T (Set Real)) S) + // (member 0.5 S) + // ...where (member 0.5 T) is inferred + // + // or + // + // S : (Set Real) + // (not (member 0.5 s)) + // (member 0.0 s) + // ...find model M where M( s ) = { 0 }, check model will generate (not (member 0.5 (singleton 0))) + // if(!elementType.isComparableTo(setType.getSetElementType())) { - throw TypeCheckingExceptionPrivate(n, "member operating on sets of different types"); + //if(!elementType.isSubtypeOf(setType.getSetElementType())) { //FIXME:typing + std::stringstream ss; + ss << "member operating on sets of different types:\n" + << "child type: " << elementType << "\n" + << "not subtype: " << setType.getSetElementType() << "\n" + << "in term : " << n; + throw TypeCheckingExceptionPrivate(n, ss.str()); } } return nodeManager->booleanType(); diff --git a/src/theory/shared_terms_database.cpp b/src/theory/shared_terms_database.cpp index b78109dfb..8e4bd5399 100644 --- a/src/theory/shared_terms_database.cpp +++ b/src/theory/shared_terms_database.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Morgan Deters, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/shared_terms_database.h b/src/theory/shared_terms_database.h index cc8959165..5ca625751 100644 --- a/src/theory/shared_terms_database.h +++ b/src/theory/shared_terms_database.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Morgan Deters, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,6 +17,8 @@ #pragma once +#include <unordered_map> + #include "context/cdhashset.h" #include "expr/node.h" #include "theory/theory.h" @@ -43,7 +45,7 @@ private: IntStat d_statSharedTerms; // Needs to be a map from Nodes as after a backtrack they might not exist - typedef std::hash_map<Node, shared_terms_list, TNodeHashFunction> SharedTermsMap; + typedef std::unordered_map<Node, shared_terms_list, TNodeHashFunction> SharedTermsMap; /** A map from atoms to a list of shared terms */ SharedTermsMap d_atomsToTerms; diff --git a/src/theory/sort_inference.cpp b/src/theory/sort_inference.cpp index 6dabf9a13..73a50bc7a 100644 --- a/src/theory/sort_inference.cpp +++ b/src/theory/sort_inference.cpp @@ -2,9 +2,9 @@ /*! \file sort_inference.cpp ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tim King + ** Andrew Reynolds, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/sort_inference.h b/src/theory/sort_inference.h index ae3342f92..ae4131fa8 100644 --- a/src/theory/sort_inference.h +++ b/src/theory/sort_inference.h @@ -2,9 +2,9 @@ /*! \file sort_inference.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Morgan Deters, Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/strings/regexp_operation.cpp b/src/theory/strings/regexp_operation.cpp index a665a02c1..ec788fa78 100644 --- a/src/theory/strings/regexp_operation.cpp +++ b/src/theory/strings/regexp_operation.cpp @@ -2,9 +2,9 @@ /*! \file regexp_operation.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tianyi Liang, Tim King + ** Morgan Deters, Tianyi Liang, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/strings/regexp_operation.h b/src/theory/strings/regexp_operation.h index 075391370..4a0ce150c 100644 --- a/src/theory/strings/regexp_operation.h +++ b/src/theory/strings/regexp_operation.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tianyi Liang, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/strings/theory_strings.cpp b/src/theory/strings/theory_strings.cpp index 6526b68cf..9b74c3513 100644 --- a/src/theory/strings/theory_strings.cpp +++ b/src/theory/strings/theory_strings.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tianyi Liang, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/strings/theory_strings.h b/src/theory/strings/theory_strings.h index a905189af..ac45bb731 100644 --- a/src/theory/strings/theory_strings.h +++ b/src/theory/strings/theory_strings.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tianyi Liang, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/strings/theory_strings_preprocess.cpp b/src/theory/strings/theory_strings_preprocess.cpp index d8d8e393c..ca49727ef 100644 --- a/src/theory/strings/theory_strings_preprocess.cpp +++ b/src/theory/strings/theory_strings_preprocess.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Tianyi Liang, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/strings/theory_strings_preprocess.h b/src/theory/strings/theory_strings_preprocess.h index faaeb53c3..60bfd6fab 100644 --- a/src/theory/strings/theory_strings_preprocess.h +++ b/src/theory/strings/theory_strings_preprocess.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/strings/theory_strings_rewriter.cpp b/src/theory/strings/theory_strings_rewriter.cpp index 6daaddcd7..de9b60d87 100644 --- a/src/theory/strings/theory_strings_rewriter.cpp +++ b/src/theory/strings/theory_strings_rewriter.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tianyi Liang, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/strings/theory_strings_rewriter.h b/src/theory/strings/theory_strings_rewriter.h index e166bfaeb..d5a35926e 100644 --- a/src/theory/strings/theory_strings_rewriter.h +++ b/src/theory/strings/theory_strings_rewriter.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tianyi Liang, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/strings/theory_strings_type_rules.h b/src/theory/strings/theory_strings_type_rules.h index 6dc207b6b..b02257d38 100644 --- a/src/theory/strings/theory_strings_type_rules.h +++ b/src/theory/strings/theory_strings_type_rules.h @@ -2,9 +2,9 @@ /*! \file theory_strings_type_rules.h ** \verbatim ** Top contributors (to current version): - ** Tianyi Liang, Tim King, Morgan Deters + ** Tianyi Liang, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/strings/type_enumerator.h b/src/theory/strings/type_enumerator.h index 22dc903ab..c7a36f2f5 100644 --- a/src/theory/strings/type_enumerator.h +++ b/src/theory/strings/type_enumerator.h @@ -2,9 +2,9 @@ /*! \file type_enumerator.h ** \verbatim ** Top contributors (to current version): - ** Tianyi Liang, Tim King, Andrew Reynolds + ** Tianyi Liang, Paul Meng, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/substitutions.cpp b/src/theory/substitutions.cpp index 7dbfb2678..ffb1cd1cb 100644 --- a/src/theory/substitutions.cpp +++ b/src/theory/substitutions.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Clark Barrett, Dejan Jovanovic, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/substitutions.h b/src/theory/substitutions.h index 019fbd17e..cca39a62e 100644 --- a/src/theory/substitutions.h +++ b/src/theory/substitutions.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,9 +19,10 @@ #ifndef __CVC4__THEORY__SUBSTITUTIONS_H #define __CVC4__THEORY__SUBSTITUTIONS_H +//#include <algorithm> #include <utility> #include <vector> -#include <algorithm> +#include <unordered_map> #include "expr/node.h" #include "context/context.h" @@ -51,7 +52,7 @@ public: private: - typedef std::hash_map<Node, Node, NodeHashFunction> NodeCache; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeCache; /** The variables, in order of addition */ NodeMap d_substitutions; diff --git a/src/theory/term_registration_visitor.cpp b/src/theory/term_registration_visitor.cpp index e758002fa..1e1a2e8e6 100644 --- a/src/theory/term_registration_visitor.cpp +++ b/src/theory/term_registration_visitor.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Andrew Reynolds, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/term_registration_visitor.h b/src/theory/term_registration_visitor.h index 6d04910f6..2a84a7995 100644 --- a/src/theory/term_registration_visitor.h +++ b/src/theory/term_registration_visitor.h @@ -2,9 +2,9 @@ /*! \file term_registration_visitor.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,7 +20,7 @@ #include "context/context.h" #include "theory/shared_terms_database.h" -#include <ext/hash_map> +#include <unordered_map> namespace CVC4 { @@ -105,7 +105,7 @@ class SharedTermsVisitor { /** * Cache from preprocessing of atoms. */ - typedef std::hash_map<TNode, theory::Theory::Set, TNodeHashFunction> TNodeVisitedMap; + typedef std::unordered_map<TNode, theory::Theory::Set, TNodeHashFunction> TNodeVisitedMap; TNodeVisitedMap d_visited; /** diff --git a/src/theory/theory.cpp b/src/theory/theory.cpp index 37d65972e..8509e84ab 100644 --- a/src/theory/theory.cpp +++ b/src/theory/theory.cpp @@ -2,9 +2,9 @@ /*! \file theory.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Dejan Jovanovic, Clark Barrett + ** Tim King, Andrew Reynolds, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -220,8 +220,8 @@ void Theory::debugPrintFacts() const{ printFacts(DebugChannel.getStream()); } -std::hash_set<TNode, TNodeHashFunction> Theory::currentlySharedTerms() const{ - std::hash_set<TNode, TNodeHashFunction> currentlyShared; +std::unordered_set<TNode, TNodeHashFunction> Theory::currentlySharedTerms() const{ + std::unordered_set<TNode, TNodeHashFunction> currentlyShared; for (shared_terms_iterator i = shared_terms_begin(), i_end = shared_terms_end(); i != i_end; ++i) { currentlyShared.insert (*i); diff --git a/src/theory/theory.h b/src/theory/theory.h index 37d818eac..73102a6e2 100644 --- a/src/theory/theory.h +++ b/src/theory/theory.h @@ -2,9 +2,9 @@ /*! \file theory.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Morgan Deters, Dejan Jovanovic, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -19,11 +19,11 @@ #ifndef __CVC4__THEORY__THEORY_H #define __CVC4__THEORY__THEORY_H -#include <ext/hash_set> #include <iosfwd> #include <map> #include <set> #include <string> +#include <unordered_set> #include "context/cdlist.h" #include "context/cdhashset.h" @@ -243,9 +243,6 @@ public: static inline TheoryId theoryOf(TypeNode typeNode) { Trace("theory::internal") << "theoryOf(" << typeNode << ")" << std::endl; TheoryId id; - while (typeNode.isPredicateSubtype()) { - typeNode = typeNode.getSubtypeParentType(); - } if (typeNode.getKind() == kind::TYPE_CONSTANT) { id = typeConstantToTheoryId(typeNode.getConst<TypeConstant>()); } else { @@ -763,7 +760,7 @@ public: * This is a utility function for constructing a copy of the currently shared terms * in a queriable form. As this is */ - std::hash_set<TNode, TNodeHashFunction> currentlySharedTerms() const; + std::unordered_set<TNode, TNodeHashFunction> currentlySharedTerms() const; /** * This allows the theory to be queried for whether a literal, lit, is diff --git a/src/theory/theory_engine.cpp b/src/theory/theory_engine.cpp index f99de0c3b..1023071dc 100644 --- a/src/theory/theory_engine.cpp +++ b/src/theory/theory_engine.cpp @@ -2,9 +2,9 @@ /*! \file theory_engine.cpp ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Tim King + ** Dejan Jovanovic, Morgan Deters, Guy Katz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -1645,7 +1645,7 @@ Node TheoryEngine::getExplanation(TNode node) { struct AtomsCollect { std::vector<TNode> d_atoms; - std::hash_set<TNode, TNodeHashFunction> d_visited; + std::unordered_set<TNode, TNodeHashFunction> d_visited; public: diff --git a/src/theory/theory_engine.h b/src/theory/theory_engine.h index e821b4017..408bff228 100644 --- a/src/theory/theory_engine.h +++ b/src/theory/theory_engine.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -21,6 +21,7 @@ #include <deque> #include <set> +#include <unordered_map> #include <vector> #include <utility> @@ -189,8 +190,8 @@ class TheoryEngine { theory::TheoryEngineModelBuilder* d_curr_model_builder; bool d_aloc_curr_model_builder; - typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap; - typedef std::hash_map<TNode, Node, TNodeHashFunction> TNodeMap; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeMap; + typedef std::unordered_map<TNode, Node, TNodeHashFunction> TNodeMap; /** * Cache for theory-preprocessing of assertions diff --git a/src/theory/theory_model.cpp b/src/theory/theory_model.cpp index c064040d9..0f92f976e 100644 --- a/src/theory/theory_model.cpp +++ b/src/theory/theory_model.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Clark Barrett, Andrew Reynolds, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -132,7 +132,7 @@ Cardinality TheoryModel::getCardinality( Type t ) const{ Node TheoryModel::getModelValue(TNode n, bool hasBoundVars, bool useDontCares) const { - std::hash_map<Node, Node, NodeHashFunction>::iterator it = d_modelCache.find(n); + std::unordered_map<Node, Node, NodeHashFunction>::iterator it = d_modelCache.find(n); if (it != d_modelCache.end()) { return (*it).second; } diff --git a/src/theory/theory_model.h b/src/theory/theory_model.h index 1d3906eee..c1c57795b 100644 --- a/src/theory/theory_model.h +++ b/src/theory/theory_model.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Clark Barrett, Morgan Deters, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,6 +17,9 @@ #ifndef __CVC4__THEORY__THEORY_MODEL_H #define __CVC4__THEORY__THEORY_MODEL_H +#include <unordered_map> +#include <unordered_set> + #include "smt/model.h" #include "theory/uf/equality_engine.h" #include "theory/rep_set.h" @@ -52,7 +55,7 @@ public: /** true/false nodes */ Node d_true; Node d_false; - mutable std::hash_map<Node, Node, NodeHashFunction> d_modelCache; + mutable std::unordered_map<Node, Node, NodeHashFunction> d_modelCache; public: /** comment stream to include in printing */ std::stringstream d_comment_str; @@ -140,8 +143,8 @@ public: */ class TypeSet { public: - typedef std::hash_map<TypeNode, std::set<Node>*, TypeNodeHashFunction> TypeSetMap; - typedef std::hash_map<TypeNode, TypeEnumerator*, TypeNodeHashFunction> TypeToTypeEnumMap; + typedef std::unordered_map<TypeNode, std::set<Node>*, TypeNodeHashFunction> TypeSetMap; + typedef std::unordered_map<TypeNode, TypeEnumerator*, TypeNodeHashFunction> TypeToTypeEnumMap; typedef TypeSetMap::iterator iterator; typedef TypeSetMap::const_iterator const_iterator; private: @@ -265,9 +268,9 @@ class TheoryEngineModelBuilder : public ModelBuilder protected: /** pointer to theory engine */ TheoryEngine* d_te; - typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap; + typedef std::unordered_map<Node, Node, NodeHashFunction> NodeMap; NodeMap d_normalizedCache; - typedef std::hash_set<Node, NodeHashFunction> NodeSet; + typedef std::unordered_set<Node, NodeHashFunction> NodeSet; std::map< Node, Node > d_constantReps; /** process build model */ diff --git a/src/theory/theory_registrar.h b/src/theory/theory_registrar.h index d0e3a5b0d..df576a694 100644 --- a/src/theory/theory_registrar.h +++ b/src/theory/theory_registrar.h @@ -2,9 +2,9 @@ /*! \file theory_registrar.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Liana Hadarean + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/theory_test_utils.h b/src/theory/theory_test_utils.h index 031c51d22..f5c85fc35 100644 --- a/src/theory/theory_test_utils.h +++ b/src/theory/theory_test_utils.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/theory_traits_template.h b/src/theory/theory_traits_template.h index 0d2d0b8e2..5fbf10e93 100644 --- a/src/theory/theory_traits_template.h +++ b/src/theory/theory_traits_template.h @@ -2,9 +2,9 @@ /*! \file theory_traits_template.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Morgan Deters, Dejan Jovanovic, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/type_enumerator.h b/src/theory/type_enumerator.h index 258bf6a3a..197363c1f 100644 --- a/src/theory/type_enumerator.h +++ b/src/theory/type_enumerator.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/type_enumerator_template.cpp b/src/theory/type_enumerator_template.cpp index 2dfefa1a8..a2bc8ab86 100644 --- a/src/theory/type_enumerator_template.cpp +++ b/src/theory/type_enumerator_template.cpp @@ -2,9 +2,9 @@ /*! \file type_enumerator_template.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Andrew Reynolds + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/uf/equality_engine.cpp b/src/theory/uf/equality_engine.cpp index f7084bec3..a73425a80 100644 --- a/src/theory/uf/equality_engine.cpp +++ b/src/theory/uf/equality_engine.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Guy Katz, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/uf/equality_engine.h b/src/theory/uf/equality_engine.h index 46ec7403b..5be32ab90 100644 --- a/src/theory/uf/equality_engine.h +++ b/src/theory/uf/equality_engine.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Morgan Deters, Guy Katz ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,8 +20,8 @@ #pragma once #include <deque> -#include <ext/hash_map> #include <queue> +#include <unordered_map> #include <vector> #include "base/output.h" @@ -234,10 +234,10 @@ private: std::map<unsigned, const PathReconstructionNotify*> d_pathReconstructionTriggers; /** Map from nodes to their ids */ - __gnu_cxx::hash_map<TNode, EqualityNodeId, TNodeHashFunction> d_nodeIds; + std::unordered_map<TNode, EqualityNodeId, TNodeHashFunction> d_nodeIds; /** Map from function applications to their ids */ - typedef __gnu_cxx::hash_map<FunctionApplication, EqualityNodeId, FunctionApplicationHashFunction> ApplicationIdsMap; + typedef std::unordered_map<FunctionApplication, EqualityNodeId, FunctionApplicationHashFunction> ApplicationIdsMap; /** * A map from a pair (a', b') to a function application f(a, b), where a' and b' are the current representatives @@ -611,7 +611,7 @@ private: */ std::vector<TriggerTermSetRef> d_nodeIndividualTrigger; - typedef std::hash_map<EqualityPair, DisequalityReasonRef, EqualityPairHashFunction> DisequalityReasonsMap; + typedef std::unordered_map<EqualityPair, DisequalityReasonRef, EqualityPairHashFunction> DisequalityReasonsMap; /** * A map from pairs of disequal terms, to the reason why we deduced they are disequal. diff --git a/src/theory/uf/equality_engine_types.h b/src/theory/uf/equality_engine_types.h index 346aebca7..ed0afa904 100644 --- a/src/theory/uf/equality_engine_types.h +++ b/src/theory/uf/equality_engine_types.h @@ -2,9 +2,9 @@ /*! \file equality_engine_types.h ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Andrew Reynolds, Guy Katz + ** Dejan Jovanovic, Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/uf/symmetry_breaker.cpp b/src/theory/uf/symmetry_breaker.cpp index ca7284689..8a1c30ba6 100644 --- a/src/theory/uf/symmetry_breaker.cpp +++ b/src/theory/uf/symmetry_breaker.cpp @@ -2,9 +2,9 @@ /*! \file symmetry_breaker.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Liana Hadarean, Tim King + ** Morgan Deters, Liana Hadarean, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -61,7 +61,7 @@ SymmetryBreaker::Template::Template() : } TNode SymmetryBreaker::Template::find(TNode n) { - hash_map<TNode, TNode, TNodeHashFunction>::iterator i = d_reps.find(n); + unordered_map<TNode, TNode, TNodeHashFunction>::iterator i = d_reps.find(n); if(i == d_reps.end()) { return n; } else { @@ -400,8 +400,8 @@ void SymmetryBreaker::assertFormula(TNode phi) { break; } } - hash_map<TNode, set<TNode>, TNodeHashFunction>& ps = t.partitions(); - for(hash_map<TNode, set<TNode>, TNodeHashFunction>::iterator i = ps.begin(); + unordered_map<TNode, set<TNode>, TNodeHashFunction>& ps = t.partitions(); + for(unordered_map<TNode, set<TNode>, TNodeHashFunction>::iterator i = ps.begin(); i != ps.end(); ++i) { Debug("ufsymm") << "UFSYMM partition*: " << (*i).first; @@ -421,9 +421,9 @@ void SymmetryBreaker::assertFormula(TNode phi) { } if(!d_template.match(phi)) { // we hit a bad match, extract the partitions and reset the template - hash_map<TNode, set<TNode>, TNodeHashFunction>& ps = d_template.partitions(); + unordered_map<TNode, set<TNode>, TNodeHashFunction>& ps = d_template.partitions(); Debug("ufsymm") << "UFSYMM hit a bad match---have " << ps.size() << " partitions:" << endl; - for(hash_map<TNode, set<TNode>, TNodeHashFunction>::iterator i = ps.begin(); + for(unordered_map<TNode, set<TNode>, TNodeHashFunction>::iterator i = ps.begin(); i != ps.end(); ++i) { Debug("ufsymm") << "UFSYMM partition: " << (*i).first; diff --git a/src/theory/uf/symmetry_breaker.h b/src/theory/uf/symmetry_breaker.h index b706f340f..64ca41df2 100644 --- a/src/theory/uf/symmetry_breaker.h +++ b/src/theory/uf/symmetry_breaker.h @@ -2,9 +2,9 @@ /*! \file symmetry_breaker.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Liana Hadarean, Tim King + ** Morgan Deters, Liana Hadarean, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -46,6 +46,7 @@ #include <iostream> #include <list> +#include <unordered_map> #include <vector> #include "context/cdlist.h" @@ -64,8 +65,8 @@ class SymmetryBreaker : public context::ContextNotifyObj { class Template { Node d_template; NodeBuilder<> d_assertions; - std::hash_map<TNode, std::set<TNode>, TNodeHashFunction> d_sets; - std::hash_map<TNode, TNode, TNodeHashFunction> d_reps; + std::unordered_map<TNode, std::set<TNode>, TNodeHashFunction> d_sets; + std::unordered_map<TNode, TNode, TNodeHashFunction> d_reps; TNode find(TNode n); bool matchRecursive(TNode t, TNode n); @@ -73,7 +74,7 @@ class SymmetryBreaker : public context::ContextNotifyObj { public: Template(); bool match(TNode n); - std::hash_map<TNode, std::set<TNode>, TNodeHashFunction>& partitions() { return d_sets; } + std::unordered_map<TNode, std::set<TNode>, TNodeHashFunction>& partitions() { return d_sets; } Node assertions() { switch(d_assertions.getNumChildren()) { case 0: return Node::null(); @@ -91,7 +92,7 @@ public: typedef TNode Term; typedef std::list<Term> Terms; typedef std::set<Term> TermEq; - typedef std::hash_map<Term, TermEq, TNodeHashFunction> TermEqs; + typedef std::unordered_map<Term, TermEq, TNodeHashFunction> TermEqs; private: @@ -113,7 +114,7 @@ private: Permutations d_permutations; Terms d_terms; Template d_template; - std::hash_map<Node, Node, NodeHashFunction> d_normalizationCache; + std::unordered_map<Node, Node, NodeHashFunction> d_normalizationCache; TermEqs d_termEqs; TermEqs d_termEqsOnly; diff --git a/src/theory/uf/theory_uf.cpp b/src/theory/uf/theory_uf.cpp index 8166e3574..6d4d96a87 100644 --- a/src/theory/uf/theory_uf.cpp +++ b/src/theory/uf/theory_uf.cpp @@ -2,9 +2,9 @@ /*! \file theory_uf.cpp ** \verbatim ** Top contributors (to current version): - ** Dejan Jovanovic, Morgan Deters, Andrew Reynolds + ** Morgan Deters, Andrew Reynolds, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -300,7 +300,7 @@ void TheoryUF::ppStaticLearn(TNode n, NodeBuilder<>& learned) { vector<TNode> workList; workList.push_back(n); - __gnu_cxx::hash_set<TNode, TNodeHashFunction> processed; + std::unordered_set<TNode, TNodeHashFunction> processed; while(!workList.empty()) { n = workList.back(); diff --git a/src/theory/uf/theory_uf.h b/src/theory/uf/theory_uf.h index 28db0195d..bd10f5961 100644 --- a/src/theory/uf/theory_uf.h +++ b/src/theory/uf/theory_uf.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Dejan Jovanovic, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/uf/theory_uf_model.cpp b/src/theory/uf/theory_uf_model.cpp index f6568ad7f..b7572eaa1 100644 --- a/src/theory/uf/theory_uf_model.cpp +++ b/src/theory/uf/theory_uf_model.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/uf/theory_uf_model.h b/src/theory/uf/theory_uf_model.h index 39e7ee6f0..0b55c926e 100644 --- a/src/theory/uf/theory_uf_model.h +++ b/src/theory/uf/theory_uf_model.h @@ -2,9 +2,9 @@ /*! \file theory_uf_model.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Andrew Reynolds, Tim King + ** Morgan Deters, Andrew Reynolds, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/uf/theory_uf_rewriter.h b/src/theory/uf/theory_uf_rewriter.h index bce6003eb..0bd502205 100644 --- a/src/theory/uf/theory_uf_rewriter.h +++ b/src/theory/uf/theory_uf_rewriter.h @@ -2,9 +2,9 @@ /*! \file theory_uf_rewriter.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Morgan Deters, Dejan Jovanovic, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/uf/theory_uf_strong_solver.cpp b/src/theory/uf/theory_uf_strong_solver.cpp index 51648fb26..77459715f 100644 --- a/src/theory/uf/theory_uf_strong_solver.cpp +++ b/src/theory/uf/theory_uf_strong_solver.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Andrew Reynolds, Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/uf/theory_uf_strong_solver.h b/src/theory/uf/theory_uf_strong_solver.h index 4130a7d41..b477a7eb5 100644 --- a/src/theory/uf/theory_uf_strong_solver.h +++ b/src/theory/uf/theory_uf_strong_solver.h @@ -2,9 +2,9 @@ /*! \file theory_uf_strong_solver.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tim King + ** Tim King, Andrew Reynolds, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/uf/theory_uf_type_rules.h b/src/theory/uf/theory_uf_type_rules.h index 5d97dda38..c31de403c 100644 --- a/src/theory/uf/theory_uf_type_rules.h +++ b/src/theory/uf/theory_uf_type_rules.h @@ -2,9 +2,9 @@ /*! \file theory_uf_type_rules.h ** \verbatim ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Dejan Jovanovic + ** Tim King, Morgan Deters, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -45,13 +45,14 @@ class UfTypeRule { ++argument_it, ++argument_type_it) { TypeNode currentArgument = (*argument_it).getType(); TypeNode currentArgumentType = *argument_type_it; - if (!currentArgument.isComparableTo(currentArgumentType)) { + if (!currentArgument.isSubtypeOf(currentArgumentType)) { std::stringstream ss; ss << "argument type is not a subtype of the function's argument " << "type:\n" << "argument: " << *argument_it << "\n" << "has type: " << (*argument_it).getType() << "\n" - << "not subtype: " << *argument_type_it; + << "not subtype: " << *argument_type_it << "\n" + << "in term : " << n; throw TypeCheckingExceptionPrivate(n, ss.str()); } } diff --git a/src/theory/unconstrained_simplifier.cpp b/src/theory/unconstrained_simplifier.cpp index 57d95d801..6c2c791cf 100644 --- a/src/theory/unconstrained_simplifier.cpp +++ b/src/theory/unconstrained_simplifier.cpp @@ -2,9 +2,9 @@ /*! \file unconstrained_simplifier.cpp ** \verbatim ** Top contributors (to current version): - ** Clark Barrett, Peter Collingbourne, Tim King + ** Clark Barrett, Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/unconstrained_simplifier.h b/src/theory/unconstrained_simplifier.h index e10be1a8f..04c32f408 100644 --- a/src/theory/unconstrained_simplifier.h +++ b/src/theory/unconstrained_simplifier.h @@ -2,9 +2,9 @@ /*! \file unconstrained_simplifier.h ** \verbatim ** Top contributors (to current version): - ** Clark Barrett, Tim King + ** Clark Barrett, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,8 +20,10 @@ #ifndef __CVC4__UNCONSTRAINED_SIMPLIFIER_H #define __CVC4__UNCONSTRAINED_SIMPLIFIER_H -#include <vector> +#include <unordered_map> +#include <unordered_set> #include <utility> +#include <vector> #include "expr/node.h" #include "theory/substitutions.h" @@ -37,9 +39,9 @@ class UnconstrainedSimplifier { /** number of expressions eliminated due to unconstrained simplification */ IntStat d_numUnconstrainedElim; - typedef std::hash_map<TNode, unsigned, TNodeHashFunction> TNodeCountMap; - typedef std::hash_map<TNode, TNode, TNodeHashFunction> TNodeMap; - typedef std::hash_set<TNode, TNodeHashFunction> TNodeSet; + typedef std::unordered_map<TNode, unsigned, TNodeHashFunction> TNodeCountMap; + typedef std::unordered_map<TNode, TNode, TNodeHashFunction> TNodeMap; + typedef std::unordered_set<TNode, TNodeHashFunction> TNodeSet; TNodeCountMap d_visited; TNodeMap d_visitedOnce; diff --git a/src/theory/valuation.cpp b/src/theory/valuation.cpp index 7e13668cd..7151b4aaf 100644 --- a/src/theory/valuation.cpp +++ b/src/theory/valuation.cpp @@ -2,9 +2,9 @@ /*! \file valuation.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/theory/valuation.h b/src/theory/valuation.h index 54af14fdd..e78a629e1 100644 --- a/src/theory/valuation.h +++ b/src/theory/valuation.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/Makefile.am b/src/util/Makefile.am index cd6f0e11c..877525de7 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -34,6 +34,7 @@ libutil_la_SOURCES = \ floatingpoint.h \ gmp_util.h \ hash.h \ + index.cpp \ index.h \ maybe.h \ ntuple.h \ diff --git a/src/util/abstract_value.cpp b/src/util/abstract_value.cpp index c80569034..123d568cb 100644 --- a/src/util/abstract_value.cpp +++ b/src/util/abstract_value.cpp @@ -2,9 +2,9 @@ /*! \file abstract_value.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/abstract_value.h b/src/util/abstract_value.h index d85a62c72..9c8e1cb37 100644 --- a/src/util/abstract_value.h +++ b/src/util/abstract_value.h @@ -2,9 +2,9 @@ /*! \file abstract_value.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/bin_heap.h b/src/util/bin_heap.h index 4f2b25c39..86f7b8771 100644 --- a/src/util/bin_heap.h +++ b/src/util/bin_heap.h @@ -2,9 +2,9 @@ /*! \file bin_heap.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/bitvector.h b/src/util/bitvector.h index 4a74c1c53..8d4618994 100644 --- a/src/util/bitvector.h +++ b/src/util/bitvector.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Dejan Jovanovic, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/bool.h b/src/util/bool.h index 99db6a4a6..386315fe7 100644 --- a/src/util/bool.h +++ b/src/util/bool.h @@ -2,9 +2,9 @@ /*! \file bool.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/cache.h b/src/util/cache.h index 8dd3cd0ae..38dc0fc99 100644 --- a/src/util/cache.h +++ b/src/util/cache.h @@ -2,9 +2,9 @@ /*! \file cache.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -21,8 +21,10 @@ #ifndef __CVC4__CACHE_H #define __CVC4__CACHE_H -#include <utility> #include <functional> +#include <unordered_map> +#include <utility> +#include <vector> namespace CVC4 { @@ -33,7 +35,7 @@ namespace CVC4 { */ template <class T, class U, class Hasher = std::hash<T> > class Cache { - typedef std::hash_map<T, U, Hasher> Map; + typedef std::unordered_map<T, U, Hasher> Map; Map d_map; std::vector<T> d_current; typename Map::iterator d_result; diff --git a/src/util/cardinality.cpp b/src/util/cardinality.cpp index 17c790731..48a1329f9 100644 --- a/src/util/cardinality.cpp +++ b/src/util/cardinality.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/cardinality.h b/src/util/cardinality.h index b16f84324..0bc1fef57 100644 --- a/src/util/cardinality.h +++ b/src/util/cardinality.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/channel.h b/src/util/channel.h index 39aed425b..5a5610410 100644 --- a/src/util/channel.h +++ b/src/util/channel.h @@ -1,9 +1,8 @@ /********************* */ /*! \file channel.h ** \verbatim - ** Original author: Morgan Deters - ** Major contributors: none - ** Minor contributors (to current version): none + ** Top contributors (to current version): + ** none ** This file is part of the CVC4 project but is excluded from the ** standard CVC4 licensing because it is a derivative work of ** circular_buffer.hpp in the BOOST 1.46.1 distribution. @@ -13,6 +12,7 @@ ** The combined work is: ** Copyright (c) 2009-2014 New York University and The University of Iowa ** Copyright (c) 2003-2008 Jan Gaspar + ** \endverbatim ** ** \brief [[ Add one-line brief description here ]] ** diff --git a/src/util/debug.h b/src/util/debug.h index 665fa99a2..585140855 100644 --- a/src/util/debug.h +++ b/src/util/debug.h @@ -2,9 +2,9 @@ /*! \file debug.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/dense_map.h b/src/util/dense_map.h index 7fa3832ef..c7d872d09 100644 --- a/src/util/dense_map.h +++ b/src/util/dense_map.h @@ -2,9 +2,9 @@ /*! \file dense_map.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Dejan Jovanovic + ** Tim King, Paul Meng, Dejan Jovanovic ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/divisible.cpp b/src/util/divisible.cpp index 4e0d9815d..060c6861b 100644 --- a/src/util/divisible.cpp +++ b/src/util/divisible.cpp @@ -2,9 +2,9 @@ /*! \file divisible.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/divisible.h b/src/util/divisible.h index d5651ae41..dd3c2f0e5 100644 --- a/src/util/divisible.h +++ b/src/util/divisible.h @@ -2,9 +2,9 @@ /*! \file divisible.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/dynamic_array.h b/src/util/dynamic_array.h index 2ec85a025..9126c39e7 100644 --- a/src/util/dynamic_array.h +++ b/src/util/dynamic_array.h @@ -2,9 +2,9 @@ /*! \file dynamic_array.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/floatingpoint.cpp b/src/util/floatingpoint.cpp index 678d3a45a..8c446d9d2 100644 --- a/src/util/floatingpoint.cpp +++ b/src/util/floatingpoint.cpp @@ -2,10 +2,10 @@ /*! \file floatingpoint.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Martin Brain + ** Martin Brain, Tim King, Paul Meng ** Copyright (c) 2013 University of Oxford ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/floatingpoint.h b/src/util/floatingpoint.h index af909dfa4..b3be84f13 100644 --- a/src/util/floatingpoint.h +++ b/src/util/floatingpoint.h @@ -2,10 +2,10 @@ /*! \file floatingpoint.h ** \verbatim ** Top contributors (to current version): - ** Martin Brain, Tim King + ** Martin Brain, Tim King, Paul Meng ** Copyright (c) 2013 University of Oxford ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/gmp_util.h b/src/util/gmp_util.h index 776d8a38a..2e1ccbc6a 100644 --- a/src/util/gmp_util.h +++ b/src/util/gmp_util.h @@ -2,9 +2,9 @@ /*! \file gmp_util.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Dejan Jovanovic, Tim King + ** Morgan Deters, Dejan Jovanovic, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/hash.h b/src/util/hash.h index 4797b5f02..b04fb8bb5 100644 --- a/src/util/hash.h +++ b/src/util/hash.h @@ -2,9 +2,9 @@ /*! \file hash.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Christopher L. Conway, Tim King + ** Morgan Deters, Christopher L. Conway, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,13 +20,10 @@ #ifndef __CVC4__HASH_H #define __CVC4__HASH_H -// in case it's not been declared as a namespace yet -namespace __gnu_cxx {} +#include <functional> +#include <string> -#include <ext/hash_map> -#include <ext/hash_set> - -namespace __gnu_cxx { +namespace std { #ifdef CVC4_NEED_HASH_UINT64_T // on some versions and architectures of GNU C++, we need a @@ -39,18 +36,10 @@ struct hash<uint64_t> { };/* struct hash<uint64_t> */ #endif /* CVC4_NEED_HASH_UINT64_T */ -}/* __gnu_cxx namespace */ - -// hackish: treat hash stuff as if it were in std namespace -namespace std { using namespace __gnu_cxx; } +}/* std namespace */ namespace CVC4 { -struct StringHashFunction { - size_t operator()(const std::string& str) const { - return __gnu_cxx::hash<const char*>()(str.c_str()); - } -};/* struct StringHashFunction */ template <class T, class U, class HashT = std::hash<T>, class HashU = std::hash<U> > struct PairHashFunction { diff --git a/src/util/hash.i b/src/util/hash.i index 470447fc3..f2f1e6652 100644 --- a/src/util/hash.i +++ b/src/util/hash.i @@ -2,6 +2,4 @@ #include "util/hash.h" %} -%rename(apply) CVC4::StringHashFunction::operator()(const std::string&) const; - %include "util/hash.h" diff --git a/src/util/index.cpp b/src/util/index.cpp new file mode 100644 index 000000000..bd15e2d80 --- /dev/null +++ b/src/util/index.cpp @@ -0,0 +1,21 @@ +#include "util/index.h" + +#include <cstddef> +#include <limits> + +namespace CVC4 { + +static_assert(sizeof(Index) <= sizeof(size_t), + "Index cannot be larger than size_t"); +static_assert(!std::numeric_limits<Index>::is_signed, + "Index must be unsigned"); + +/* Discussion: Why is Index a uint32_t instead of size_t (or uint_fast32_t)? + * + * size_t is a more appropriate choice than uint32_t as the choice is dictated + * by uniqueness in arrays and vectors. These correspond to size_t. However, the + * using size_t with a sizeof == 8 on 64 bit platforms is noticeably slower. + * (Limited testing suggests a ~1/16 of running time.) Interestingly, + * uint_fast32_t also has a sizeof == 8 on x86_64. + */ +}/* CVC4 namespace */ diff --git a/src/util/index.h b/src/util/index.h index 6c11343b5..7329e3f8d 100644 --- a/src/util/index.h +++ b/src/util/index.h @@ -2,46 +2,30 @@ /*! \file index.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Liana Hadarean + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 [[ Add one-line brief description here ]] + ** \brief Standardized type for efficient array indexing. ** - ** [[ Add lengthier description here ]] - ** \todo document this file + ** Standardized type for efficient array indexing. **/ #include "cvc4_private.h" -#pragma once +#ifndef __CVC4__INDEX_H +#define __CVC4__INDEX_H -#include <stdint.h> -#include <boost/static_assert.hpp> -#include <limits> +#include <cstdint> namespace CVC4 { -/** - * Index is an unsigned integer used for array indexing. - * - * This gives a standardized type for independent pieces of code to use as an agreement. - */ -typedef uint32_t Index; - -BOOST_STATIC_ASSERT(sizeof(Index) <= sizeof(size_t)); -BOOST_STATIC_ASSERT(!std::numeric_limits<Index>::is_signed); - -/* Discussion: Why is Index a uint32_t instead of size_t (or uint_fast32_t)? - * - * size_t is a more appropriate choice than uint32_t as the choice is dictated by - * uniqueness in arrays and vectors. These correspond to size_t. - * However, the using size_t with a sizeof == 8 on 64 bit platforms is noticeably - * slower. (Limited testing suggests a ~1/16 of running time.) - * (Interestingly, uint_fast32_t also has a sizeof == 8 on x86_64. Filthy Liars!) - */ +/** Index is a standardized unsigned integer used for efficient indexing. */ +using Index = uint32_t; }/* CVC4 namespace */ + +#endif /* __CVC4__INDEX_H */ diff --git a/src/util/integer.h.in b/src/util/integer.h.in index 13ae1392b..f8e0a2f92 100644 --- a/src/util/integer.h.in +++ b/src/util/integer.h.in @@ -2,9 +2,9 @@ /*! \file integer.h.in ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/integer_cln_imp.cpp b/src/util/integer_cln_imp.cpp index a7412b503..b09d2429c 100644 --- a/src/util/integer_cln_imp.cpp +++ b/src/util/integer_cln_imp.cpp @@ -2,9 +2,9 @@ /*! \file integer_cln_imp.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Clark Barrett, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/integer_cln_imp.h b/src/util/integer_cln_imp.h index 12619520f..86cf649d0 100644 --- a/src/util/integer_cln_imp.h +++ b/src/util/integer_cln_imp.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/integer_gmp_imp.cpp b/src/util/integer_gmp_imp.cpp index e0472ac4c..e24e8bad1 100644 --- a/src/util/integer_gmp_imp.cpp +++ b/src/util/integer_gmp_imp.cpp @@ -2,9 +2,9 @@ /*! \file integer_gmp_imp.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Clark Barrett ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/integer_gmp_imp.h b/src/util/integer_gmp_imp.h index 5af902ac6..8426ac6cf 100644 --- a/src/util/integer_gmp_imp.h +++ b/src/util/integer_gmp_imp.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Liana Hadarean ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/maybe.h b/src/util/maybe.h index 7ede6f512..b2c8b9797 100644 --- a/src/util/maybe.h +++ b/src/util/maybe.h @@ -2,9 +2,9 @@ /*! \file maybe.h ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/ntuple.h b/src/util/ntuple.h index 21af4f423..712275234 100644 --- a/src/util/ntuple.h +++ b/src/util/ntuple.h @@ -2,9 +2,9 @@ /*! \file ntuple.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/proof.h b/src/util/proof.h index b4a8a3d29..b34e4aed9 100644 --- a/src/util/proof.h +++ b/src/util/proof.h @@ -2,9 +2,9 @@ /*! \file proof.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Guy Katz, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -21,7 +21,7 @@ #define __CVC4__PROOF_H #include <iosfwd> -#include <ext/hash_map> +#include <unordered_map> namespace CVC4 { @@ -29,7 +29,7 @@ class Expr; class ProofLetCount; struct ExprHashFunction; -typedef __gnu_cxx::hash_map<Expr, ProofLetCount, ExprHashFunction> ProofLetMap; +typedef std::unordered_map<Expr, ProofLetCount, ExprHashFunction> ProofLetMap; class CVC4_PUBLIC Proof { public: diff --git a/src/util/rational.h.in b/src/util/rational.h.in index 08c4003e9..196cae574 100644 --- a/src/util/rational.h.in +++ b/src/util/rational.h.in @@ -2,9 +2,9 @@ /*! \file rational.h.in ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/rational_cln_imp.cpp b/src/util/rational_cln_imp.cpp index bee944531..09e3c8168 100644 --- a/src/util/rational_cln_imp.cpp +++ b/src/util/rational_cln_imp.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Christopher L. Conway, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/rational_cln_imp.h b/src/util/rational_cln_imp.h index 9b4a8efa7..23b733214 100644 --- a/src/util/rational_cln_imp.h +++ b/src/util/rational_cln_imp.h @@ -2,9 +2,9 @@ /*! \file rational_cln_imp.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Dejan Jovanovic + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/rational_gmp_imp.cpp b/src/util/rational_gmp_imp.cpp index 17bce0201..527222f7a 100644 --- a/src/util/rational_gmp_imp.cpp +++ b/src/util/rational_gmp_imp.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Christopher L. Conway, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/rational_gmp_imp.h b/src/util/rational_gmp_imp.h index 6a1c8b4b8..e0eba8ad9 100644 --- a/src/util/rational_gmp_imp.h +++ b/src/util/rational_gmp_imp.h @@ -2,9 +2,9 @@ /*! \file rational_gmp_imp.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters, Dejan Jovanovic + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/regexp.cpp b/src/util/regexp.cpp index a6f0de4b3..c32b42bad 100644 --- a/src/util/regexp.cpp +++ b/src/util/regexp.cpp @@ -2,9 +2,9 @@ /*! \file regexp.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tianyi Liang, Tim King + ** Morgan Deters, Tianyi Liang, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -17,6 +17,7 @@ #include "util/regexp.h" +#include <algorithm> #include <iomanip> #include <iostream> diff --git a/src/util/regexp.h b/src/util/regexp.h index 06766e046..e7c8c5806 100644 --- a/src/util/regexp.h +++ b/src/util/regexp.h @@ -2,9 +2,9 @@ /*! \file regexp.h ** \verbatim ** Top contributors (to current version): - ** Tianyi Liang, Tim King, Morgan Deters + ** Tianyi Liang, Andrew Reynolds, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -20,11 +20,13 @@ #ifndef __CVC4__REGEXP_H #define __CVC4__REGEXP_H -#include <vector> -#include <string> +#include <algorithm> +#include <cassert> +#include <functional> #include <set> #include <sstream> -#include <cassert> +#include <string> +#include <vector> #include "base/exception.h" #include "util/hash.h" @@ -333,7 +335,7 @@ namespace strings { struct CVC4_PUBLIC StringHashFunction { size_t operator()(const ::CVC4::String& s) const { - return __gnu_cxx::hash<const char*>()(s.toString().c_str()); + return std::hash<std::string>()(s.toString()); } };/* struct StringHashFunction */ diff --git a/src/util/resource_manager.cpp b/src/util/resource_manager.cpp index 7a739a779..b2adb4aba 100644 --- a/src/util/resource_manager.cpp +++ b/src/util/resource_manager.cpp @@ -2,9 +2,9 @@ /*! \file resource_manager.cpp ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King, Morgan Deters + ** Liana Hadarean, Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/resource_manager.h b/src/util/resource_manager.h index d21122cae..35315559f 100644 --- a/src/util/resource_manager.h +++ b/src/util/resource_manager.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Liana Hadarean, Tim King, Morgan Deters ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/result.cpp b/src/util/result.cpp index c23813a51..27d82bb6f 100644 --- a/src/util/result.cpp +++ b/src/util/result.cpp @@ -2,9 +2,9 @@ /*! \file result.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Tim King, Morgan Deters, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/result.h b/src/util/result.h index 80fbc0cf7..b08cd57c4 100644 --- a/src/util/result.h +++ b/src/util/result.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/sexpr.cpp b/src/util/sexpr.cpp index 59d12d81f..61dbccbee 100644 --- a/src/util/sexpr.cpp +++ b/src/util/sexpr.cpp @@ -2,9 +2,9 @@ /*! \file sexpr.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Andrew Reynolds ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/sexpr.h b/src/util/sexpr.h index 0b517570e..7e326247b 100644 --- a/src/util/sexpr.h +++ b/src/util/sexpr.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King, Morgan Deters, Christopher L. Conway ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/smt2_quote_string.cpp b/src/util/smt2_quote_string.cpp index 578be99e5..6f4ba4e89 100644 --- a/src/util/smt2_quote_string.cpp +++ b/src/util/smt2_quote_string.cpp @@ -2,9 +2,9 @@ /*! \file smt2_quote_string.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/smt2_quote_string.h b/src/util/smt2_quote_string.h index 2d7f0b2f0..e6617d242 100644 --- a/src/util/smt2_quote_string.h +++ b/src/util/smt2_quote_string.h @@ -2,9 +2,9 @@ /*! \file smt2_quote_string.h ** \verbatim ** Top contributors (to current version): - ** Tim King, Morgan Deters + ** Tim King, Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/statistics.cpp b/src/util/statistics.cpp index 9423c9379..9273f2167 100644 --- a/src/util/statistics.cpp +++ b/src/util/statistics.cpp @@ -2,9 +2,9 @@ /*! \file statistics.cpp ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Andres Noetzli, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/statistics.h b/src/util/statistics.h index bdc8ad6a2..9401e09c4 100644 --- a/src/util/statistics.h +++ b/src/util/statistics.h @@ -2,9 +2,9 @@ /*! \file statistics.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/statistics_registry.cpp b/src/util/statistics_registry.cpp index 4b0626048..f20a554e1 100644 --- a/src/util/statistics_registry.cpp +++ b/src/util/statistics_registry.cpp @@ -2,9 +2,9 @@ /*! \file statistics_registry.cpp ** \verbatim ** Top contributors (to current version): - ** Tim King + ** Tim King, Paul Meng, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/statistics_registry.h b/src/util/statistics_registry.h index bd7f87b44..30f330cd7 100644 --- a/src/util/statistics_registry.h +++ b/src/util/statistics_registry.h @@ -2,9 +2,9 @@ /*! \file statistics_registry.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King, Kshitij Bansal + ** Morgan Deters, Tim King, Andres Noetzli ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 @@ -225,6 +225,9 @@ public: /** Get the value of the statistic. */ virtual T getData() const = 0; + /** Get a reference to the data value of the statistic. */ + virtual const T& getDataRef() const = 0; + /** Flush the value of the statistic to the given output stream. */ void flushInformation(std::ostream& out) const { if(__CVC4_USE_STATISTICS) { @@ -234,7 +237,7 @@ public: virtual void safeFlushInformation(int fd) const { if (__CVC4_USE_STATISTICS) { - safe_print<T>(fd, getData()); + safe_print<T>(fd, getDataRef()); } } @@ -320,9 +323,10 @@ public: } /** Get the value of the referenced data cell. */ - T getData() const { - return *d_data; - } + virtual T getData() const { return *d_data; } + + /** Get a reference to the value of the referenced data cell. */ + virtual const T& getDataRef() const { return *d_data; } };/* class ReferenceStat<T> */ @@ -361,9 +365,10 @@ public: } /** Get the underlying data value. */ - T getData() const { - return d_data; - } + virtual T getData() const { return d_data; } + + /** Get a reference to the underlying data value. */ + virtual const T& getDataRef() const { return d_data; } };/* class BackedStat<T> */ @@ -402,8 +407,16 @@ public: } /** Get the data of the underlying (wrapped) statistic. */ - T getData() const { - return d_stat.getData(); + virtual T getData() const { return d_stat.getData(); } + + /** Get a reference to the data of the underlying (wrapped) statistic. */ + virtual const T& getDataRef() const { return d_stat.getDataRef(); } + + virtual void safeFlushInformation(int fd) const { + // ReadOnlyDataStat uses getDataRef() to get the information to print, + // which might not be appropriate for all wrapped statistics. Delegate the + // printing to the wrapped statistic instead. + d_stat.safeFlushInformation(fd); } SExpr getValue() const { @@ -728,10 +741,14 @@ public: /** If the timer is currently running */ bool running() const; - timespec getData() const; + virtual timespec getData() const; virtual void safeFlushInformation(int fd) const { - safe_print<timespec>(fd, d_data); + // Overwrite the implementation in the superclass because we cannot use + // getDataRef(): it might return stale data if the timer is currently + // running. + ::timespec data = getData(); + safe_print<timespec>(fd, data); } SExpr getValue() const; diff --git a/src/util/subrange_bound.cpp b/src/util/subrange_bound.cpp index a33c22f72..b49a3ef27 100644 --- a/src/util/subrange_bound.cpp +++ b/src/util/subrange_bound.cpp @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/subrange_bound.h b/src/util/subrange_bound.h index 91c91af41..1f1cb84d7 100644 --- a/src/util/subrange_bound.h +++ b/src/util/subrange_bound.h @@ -4,7 +4,7 @@ ** Top contributors (to current version): ** Morgan Deters, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/tuple.h b/src/util/tuple.h index 14763d2d5..8d7eca3fd 100644 --- a/src/util/tuple.h +++ b/src/util/tuple.h @@ -2,9 +2,9 @@ /*! \file tuple.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/unsafe_interrupt_exception.h b/src/util/unsafe_interrupt_exception.h index 345daf674..7c6d06630 100644 --- a/src/util/unsafe_interrupt_exception.h +++ b/src/util/unsafe_interrupt_exception.h @@ -2,9 +2,9 @@ /*! \file unsafe_interrupt_exception.h ** \verbatim ** Top contributors (to current version): - ** Liana Hadarean, Tim King + ** Liana Hadarean, Paul Meng, Tim King ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 diff --git a/src/util/utility.h b/src/util/utility.h index 1d51d42ee..adfd2bc64 100644 --- a/src/util/utility.h +++ b/src/util/utility.h @@ -2,9 +2,9 @@ /*! \file utility.h ** \verbatim ** Top contributors (to current version): - ** Morgan Deters, Tim King + ** Morgan Deters, Paul Meng ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS + ** 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 |