/********************* */ /*! \file theory_bv.h ** \verbatim ** Top contributors (to current version): ** Liana Hadarean, Morgan Deters, Tim King ** This file is part of the CVC4 project. ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS ** in the top-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 Bitvector theory. ** ** Bitvector theory. **/ #include "cvc4_private.h" #ifndef __CVC4__THEORY__BV__THEORY_BV_H #define __CVC4__THEORY__BV__THEORY_BV_H #include #include #include "context/cdhashset.h" #include "context/cdlist.h" #include "context/context.h" #include "theory/bv/bv_subtheory.h" #include "theory/bv/theory_bv_utils.h" #include "theory/theory.h" #include "util/hash.h" #include "util/statistics_registry.h" namespace CVC4 { namespace theory { namespace bv { class CoreSolver; class InequalitySolver; class AlgebraicSolver; class BitblastSolver; class EagerBitblastSolver; class AbstractionModule; class TheoryBV : public Theory { /** The context we are using */ context::Context* d_context; /** Context dependent set of atoms we already propagated */ context::CDHashSet d_alreadyPropagatedSet; context::CDHashSet d_sharedTermsSet; std::vector> d_subtheories; std::unordered_map > d_subtheoryMap; public: TheoryBV(context::Context* c, context::UserContext* u, OutputChannel& out, Valuation valuation, const LogicInfo& logicInfo, std::string name = ""); ~TheoryBV(); void setMasterEqualityEngine(eq::EqualityEngine* eq) override; void finishInit() override; Node expandDefinition(LogicRequest& logicRequest, Node node) override; void preRegisterTerm(TNode n) override; void check(Effort e) override; bool needsCheckLastEffort() override; void propagate(Effort e) override; Node explain(TNode n) override; bool collectModelInfo(TheoryModel* m) override; std::string identify() const override { return std::string("TheoryBV"); } /** equality engine */ eq::EqualityEngine* getEqualityEngine() override; bool getCurrentSubstitution(int effort, std::vector& vars, std::vector& subs, std::map >& exp) override; int getReduction(int effort, Node n, Node& nr) override; PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions) override; void enableCoreTheorySlicer(); Node ppRewrite(TNode t) override; void ppStaticLearn(TNode in, NodeBuilder<>& learned) override; void presolve() override; bool applyAbstraction(const std::vector& assertions, std::vector& new_assertions); void setResolutionProofLog(proof::ResolutionBitVectorProof* bvp); private: class Statistics { public: AverageStat d_avgConflictSize; IntStat d_solveSubstitutions; TimerStat d_solveTimer; IntStat d_numCallsToCheckFullEffort; IntStat d_numCallsToCheckStandardEffort; TimerStat d_weightComputationTimer; IntStat d_numMultSlice; Statistics(); ~Statistics(); }; Statistics d_statistics; void spendResource(unsigned amount); /** * Return the uninterpreted function symbol corresponding to division-by-zero * for this particular bit-width * @param k should be UREM or UDIV * @param width * * @return */ Node getBVDivByZero(Kind k, unsigned width); typedef std::unordered_set TNodeSet; typedef std::unordered_set NodeSet; NodeSet d_staticLearnCache; /** * Maps from bit-vector width to division-by-zero uninterpreted * function symbols. */ std::unordered_map d_BVDivByZero; std::unordered_map d_BVRemByZero; typedef std::unordered_map NodeToNode; context::CDO d_lemmasAdded; // Are we in conflict? context::CDO d_conflict; // Invalidate the model cache if check was called context::CDO d_invalidateModelCache; /** The conflict node */ Node d_conflictNode; /** Literals to propagate */ context::CDList d_literalsToPropagate; /** Index of the next literal to propagate */ context::CDO d_literalsToPropagateIndex; /** * Keeps a map from nodes to the subtheory that propagated it so that we can explain it * properly. */ typedef context::CDHashMap PropagatedMap; PropagatedMap d_propagatedBy; std::unique_ptr d_eagerSolver; std::unique_ptr d_abstractionModule; bool d_isCoreTheory; bool d_calledPreregister; //for extended functions bool d_needsLastCallCheck; context::CDHashSet d_extf_range_infer; context::CDHashSet d_extf_collapse_infer; /** do extended function inferences * * This method adds lemmas on the output channel of TheoryBV based on * reasoning about extended functions, such as bv2nat and int2bv. Examples * of lemmas added by this method include: * 0 <= ((_ int2bv w) x) < 2^w * ((_ int2bv w) (bv2nat x)) = x * (bv2nat ((_ int2bv w) x)) == x + k*2^w * The purpose of these lemmas is to recognize easy conflicts before fully * reducing extended functions based on their full semantics. */ bool doExtfInferences( std::vector< Node >& terms ); /** do extended function reductions * * This method adds lemmas on the output channel of TheoryBV based on * reducing all extended function applications that are preregistered to * this theory and have not already been reduced by context-dependent * simplification (see theory/ext_theory.h). Examples of lemmas added by * this method include: * (bv2nat x) = (ite ((_ extract w w-1) x) 2^{w-1} 0) + ... + * (ite ((_ extract 1 0) x) 1 0) */ bool doExtfReductions( std::vector< Node >& terms ); bool wasPropagatedBySubtheory(TNode literal) const { return d_propagatedBy.find(literal) != d_propagatedBy.end(); } SubTheory getPropagatingSubtheory(TNode literal) const { Assert(wasPropagatedBySubtheory(literal)); PropagatedMap::const_iterator find = d_propagatedBy.find(literal); return (*find).second; } /** Should be called to propagate the literal. */ bool storePropagation(TNode literal, SubTheory subtheory); /** * Explains why this literal (propagated by subtheory) is true by adding assumptions. */ void explain(TNode literal, std::vector& assumptions); void addSharedTerm(TNode t) override; bool isSharedTerm(TNode t) { return d_sharedTermsSet.contains(t); } EqualityStatus getEqualityStatus(TNode a, TNode b) override; Node getModelValue(TNode var) override; inline std::string indent() { std::string indentStr(getSatContext()->getLevel(), ' '); return indentStr; } void setConflict(Node conflict = Node::null()); bool inConflict() { return d_conflict; } void sendConflict(); void lemma(TNode node) { d_out->lemma(node, RULE_CONFLICT); d_lemmasAdded = true; } void checkForLemma(TNode node); friend class LazyBitblaster; friend class TLazyBitblaster; friend class EagerBitblaster; friend class BitblastSolver; friend class EqualitySolver; friend class CoreSolver; friend class InequalitySolver; friend class AlgebraicSolver; friend class EagerBitblastSolver; };/* class TheoryBV */ }/* CVC4::theory::bv namespace */ }/* CVC4::theory namespace */ }/* CVC4 namespace */ #endif /* __CVC4__THEORY__BV__THEORY_BV_H */