/*****************************************************************************/
/*!
* \file theory_quant.h
*
* Author: Sergey Berezin, Yeting Ge
*
* Created: Jun 24 21:13:59 GMT 2003
*
*
*
* License to use, copy, modify, sell and/or distribute this software
* and its documentation for any purpose is hereby granted without
* royalty, subject to the terms and conditions defined in the \ref
* LICENSE file provided with this distribution.
*
*
*
* ! Author: Daniel Wichs
* ! Created: Wednesday July 2, 2003
*
*
*/
/*****************************************************************************/
#ifndef _cvc3__include__theory_quant_h_
#define _cvc3__include__theory_quant_h_
#include "theory.h"
#include "cdmap.h"
#include "statistics.h"
#include
namespace CVC3 {
class QuantProofRules;
/*****************************************************************************/
/*!
*\class TheoryQuant
*\ingroup Theories
*\brief This theory handles quantifiers.
*
* Author: Daniel Wichs
*
* Created: Wednesday July 2, 2003
*/
/*****************************************************************************/
typedef enum{ Ukn, Pos, Neg, PosNeg} Polarity;
class Trigger {
public:
Expr trig;
Polarity polarity;
std::vector bvs;
Expr head;
bool hasRWOp;
bool hasTrans;
bool hasT2; //if has trans of 2,
bool isSimple; //if of the form g(x,a);
bool isSuperSimple; //if of the form g(x,y);
bool isMulti;
size_t multiIndex;
size_t multiId;
Trigger(TheoryCore* core, Expr e, Polarity pol, std::set);
bool isPos();
bool isNeg();
Expr getEx();
std::vector getBVs();
void setHead(Expr h);
Expr getHead();
void setRWOp(bool b);
bool hasRW();
void setTrans(bool b);
bool hasTr();
void setTrans2(bool b);
bool hasTr2();
void setSimp();
bool isSimp();
void setSuperSimp();
bool isSuperSimp();
void setMultiTrig();
bool isMultiTrig();
};
typedef struct dynTrig{
Trigger trig;
size_t univ_id;
ExprMap binds;
dynTrig(Trigger t, ExprMap b, size_t id);
} dynTrig;
class TheoryQuant :public Theory {
class TypeComp { //!< needed for typeMap
public:
bool operator() (const Type t1, const Type t2) const
{return (t1.getExpr() < t2.getExpr()); }
};
//! used to facilitate instantiation of universal quantifiers
typedef std::map, TypeComp > typeMap;
//! database of universally quantified theorems
CDList d_univs;
CDList d_rawUnivs;
CDList d_arrayTrigs;
CDO d_lastArrayPos;
//! universally quantified formulas to be instantiated, the var bindings is in d_bingQueue and the ground term matched with the trigger is in d_gtermQueue
std::queue d_univsQueue;
std::queue d_simplifiedThmQueue;
ExprMap > > d_tempBinds;
//!tracks the possition of preds
CDO d_lastPredsPos;
//!tracks the possition of terms
CDO d_lastTermsPos;
//!tracks the positions of preds for partial instantiation
CDO d_lastPartPredsPos;
//!tracks the possition of terms for partial instantiation
CDO d_lastPartTermsPos;
//!tracks a possition in the database of universals for partial instantiation
CDO d_univsPartSavedPos;
//! the last decision level on which partial instantion is called
CDO d_lastPartLevel;
//!useful gterms for matching
CDList d_usefulGterms;
//!tracks the position in d_usefulGterms
CDO d_lastUsefulGtermsPos;
//!tracks a possition in the savedTerms map
CDO d_savedTermsPos;
//!tracks a possition in the database of universals
CDO d_univsSavedPos;
CDO d_rawUnivsSavedPos;
//!tracks a possition in the database of universals
CDO d_univsPosFull;
//!tracks a possition in the database of universals if fulleffort mode, the d_univsSavedPos now uesed when fulleffort=0 only.
CDO d_univsContextPos;
CDO d_instCount; //!< number of instantiations made in given context
//! set if the fullEffort = 1
int d_inEnd;
int d_allout;
//! a map of types to posisitions in the d_contextTerms list
std::map* ,TypeComp> d_contextMap;
//! a list of all the terms appearing in the current context
CDList d_contextTerms;
//!< chache of expressions
CDMap d_contextCache;
//! a map of types to positions in the d_savedTerms vector
typeMap d_savedMap;
ExprMap d_savedCache; //!< cache of expressions
//! a vector of all of the terms that have produced conflicts.
std::vector d_savedTerms;
//! a map of instantiated universals to a vector of their instantiations
ExprMap > d_insts;
//! quantifier theorem production rules
QuantProofRules* d_rules;
const int* d_maxQuantInst; //!< Command line option
/*! \brief categorizes all the terms contained in an expressions by
*type.
*
* Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
* returns true if the expression does not contain bound variables, false
* otherwise.
*/
bool recursiveMap(const Expr& term);
/*! \brief categorizes all the terms contained in a vector of expressions by
* type.
*
* Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
*/
void mapTermsByType(const CDList& terms);
/*! \brief Queues up all possible instantiations of bound
* variables.
*
* The savedMap boolean indicates whether to use savedMap or
* d_contextMap the all boolean indicates weather to use all
* instantiation or only new ones and newIndex is the index where
* new instantiations begin.
*/
void instantiate(Theorem univ, bool all, bool savedMap,
size_t newIndex);
//! does most of the work of the instantiate function.
void recInstantiate(Theorem& univ , bool all, bool savedMap,size_t newIndex,
std::vector& varReplacements);
/*! \brief A recursive function used to find instantiated universals
* in the hierarchy of assumptions.
*/
void findInstAssumptions(const Theorem& thm);
// CDO usedup;
const bool* d_useNew;//!use new way of instantiation
const bool* d_useLazyInst;//!use lazy instantiation
const bool* d_useSemMatch;//!use semantic matching
const bool* d_useAtomSem;
const bool* d_translate;//!translate only
const bool* d_useTrigNew;//!use new trig class, to be deleted
const bool* d_usePart;//!use partial instantiaion
const bool* d_useMult;//use
const bool* d_useInstEnd;
const bool* d_useInstLCache;
const bool* d_useInstGCache;
const bool* d_useInstTrue;
const bool* d_usePullVar;
const bool* d_useExprScore;
const int* d_useTrigLoop;
const int* d_maxInst;
// const int* d_maxUserScore;
const bool* d_useTrans;
const bool* d_useTrans2;
const bool* d_useInstAll;
const bool* d_usePolarity;
const bool* d_useEqu;
const int* d_maxNaiveCall;
CDO d_curMaxExprScore;
bool d_useFullTrig;
bool d_usePartTrig;
bool d_useMultTrig;
//ExprMap > d_arrayIndic; //map array name to a list of indics
CDMap > d_arrayIndic; //map array name to a list of indics
void arrayIndexName(const Expr& e);
std::vector d_allInsts; //! all instantiations
int d_initMaxScore;
int d_offset_multi_trig ;
int d_instThisRound;
int d_callThisRound;
int partial_called;
// ExprMap > d_fullTriggers;
//for multi-triggers, now we only have one set of multi-triggers.
ExprMap > d_multTriggers;
ExprMap > d_partTriggers;
ExprMap > d_fullTrigs;
//for multi-triggers, now we only have one set of multi-triggers.
ExprMap > d_multTrigs;
ExprMap > d_partTrigs;
CDO d_exprLastUpdatedPos ;//the position of the last expr updated in d_exprUpdate
std::map d_indexScore;
std::map d_indexExpr;
int getExprScore(const Expr& e);
//!the score for a full trigger
ExprMap d_hasTriggers;
ExprMap d_hasMoreBVs;
int d_trans_num;
int d_trans2_num;
typedef struct{
std::vector > common_pos;
std::vector > var_pos;
std::vector* > var_binds_found;
std::vector* >* > uncomm_list; //
} multTrigsInfo ;
ExprMap d_multitrigs_maps;
std::vector d_all_multTrigsInfo;
ExprMap* > d_trans_back;
ExprMap* > d_trans_forw;
CDMap d_trans_found;
CDMap d_trans2_found;
inline bool transFound(const Expr& comb);
inline void setTransFound(const Expr& comb);
inline bool trans2Found(const Expr& comb);
inline void setTrans2Found(const Expr& comb);
inline CDList & backList(const Expr& ex);
inline CDList & forwList(const Expr& ex);
CDList null_cdlist;
inline void pushBackList(const Expr& node, Expr ex);
inline void pushForwList(const Expr& node, Expr ex);
ExprMap >* > d_mtrigs_inst; //map expr to bindings
ExprMap* > d_same_head_expr; //map an expr to a list of expres shard the same head
ExprMap* > d_eq_list; //the equalities list
CDList d_eqs; //the equalities list
CDO d_eqs_pos; //the equalities list
ExprMap* > d_eq_pos;
ExprMap* > d_parent_list;
void collectChangedTerms(CDList& changed_terms);
ExprMap > d_mtrigs_bvorder;
int loc_gterm(const std::vector& border,
const Expr& gterm,
int pos);
void recSearchCover(const std::vector& border,
const std::vector& mtrigs,
int cur_depth,
std::vector >& instSet,
std::vector& cur_inst
);
void searchCover(const Expr& thm,
const std::vector& border,
std::vector >& instSet
);
std::map,TypeComp > d_typeExprMap;
std::set cacheHead;
StatCounter d_allInstCount ;
CDO d_partCalled;;
std::vector d_cacheTheorem;
size_t d_cacheThmPos;
void addNotify(const Expr& e);
int sendInstNew();
CDMap > > d_instHistory;//the history of instantiations
//map univ to the trig, gterm and result
ExprMap* > d_bindHistory; //the history of instantiations
ExprMap > > d_instHistoryGlobal;//the history of instantiations
ExprMap > d_subTermsMap;
//std::map > d_subTermsMap;
const std::vector& getSubTerms(const Expr& e);
//ExprMap d_thmTimes;
void enqueueInst(const Theorem, const Theorem);
void enqueueInst(const Theorem& univ, const std::vector& bind, const Expr& gterm);
void enqueueInst(size_t univ_id , const std::vector& bind, const Expr& gterm);
void enqueueInst(const Theorem& univ,
Trigger& trig,
const std::vector& binds,
const Expr& gterm
);
void synCheckSat(ExprMap* >* >& , bool);
void synCheckSat(bool);
void semCheckSat(bool);
void naiveCheckSat(bool);
bool insted(const Theorem & univ, const std::vector& binds);
void synInst(const Theorem & univ, const CDList& allterms, size_t tBegin);
void synFullInst(const Theorem & univ, const CDList& allterms, size_t tBegin);
void arrayHeuristic(const Trigger& trig, size_t univid);
void synNewInst(size_t univ_id, const std::vector& binds, const Expr& gterm, const Trigger& trig );
void synMultInst(const Theorem & univ, const CDList& allterms, size_t tBegin);
void synPartInst(const Theorem & univ, const CDList& allterms, size_t tBegin);
void semInst(const Theorem & univ, size_t tBegin);
void goodSynMatch(const Expr& e,
const std::vector & boundVars,
std::vector >& instBindsTerm,
std::vector& instGterm,
const CDList& allterms,
size_t tBegin);
void goodSynMatchNewTrig(const Trigger& trig,
const std::vector & boundVars,
std::vector >& instBinds,
std::vector& instGterms,
const CDList& allterms,
size_t tBegin);
bool goodSynMatchNewTrig(const Trigger& trig,
const std::vector & boundVars,
std::vector >& instBinds,
std::vector& instGterms,
const Expr& gterm);
void matchListOld(const CDList& list, size_t gbegin, size_t gend);
// void matchListOld(const Expr& gterm);
void matchListNew(ExprMap*>*>& new_trigs,
const CDList& list,
size_t gbegin,
size_t gend);
void delNewTrigs(ExprMap*>*>& new_trigs);
void combineOldNewTrigs(ExprMap*>*>& new_trigs);
void newTopMatch(const Expr& gterm,
const Expr& vterm,
std::vector >& binds,
const Trigger& trig);
bool synMatchTopPred(const Expr& gterm, const Trigger trig, ExprMap& env);
inline bool matchChild(const Expr& gterm, const Expr& vterm, ExprMap& env);
inline void matchChild(const Expr& gterm, const Expr& vterm, std::vector >& env);
inline void add_parent(const Expr& parent);
bool recSynMatch(const Expr& gterm, const Expr& vterm, ExprMap& env);
bool hasGoodSynInstNewTrigOld(Trigger& trig,
std::vector & boundVars,
std::vector >& instBinds,
std::vector& instGterms,
const CDList& allterms,
size_t tBegin);
bool hasGoodSynInstNewTrig(Trigger& trig,
const std::vector & boundVars,
std::vector >& instBinds,
std::vector& instGterms,
const CDList& allterms,
size_t tBegin);
bool hasGoodSynMultiInst(const Expr& e,
std::vector& bVars,
std::vector >& instSet,
const CDList& allterms,
size_t tBegin);
void recGoodSemMatch(const Expr& e,
const std::vector& bVars,
std::vector& newInst,
std::set >& instSet);
bool hasGoodSemInst(const Expr& e,
std::vector& bVars,
std::set >& instSet,
size_t tBegin);
bool isTransLike (const std::vector& cur_trig);
bool isTrans2Like (const std::vector& all_terms, const Expr& tr2);
static const size_t MAX_TRIG_BVS=15;
Expr d_mybvs[MAX_TRIG_BVS];
Expr recGeneralTrig(const Expr& trig, ExprMap& bvs, size_t& mybvs_count);
Expr generalTrig(const Expr& trig, ExprMap& bvs);
ExprMap* >* > d_allmap_trigs;
CDList d_alltrig_list;
void registerTrig(ExprMap* >* >& cur_trig_map,
Trigger trig,
const std::vector thmBVs,
size_t univ_id);
void registerTrigReal(Trigger trig, const std::vector, size_t univ_id);
bool canMatch(const Expr& t1, const Expr& t2, ExprMap& env);
void setGround(const Expr& gterm, const Expr& trig, const Theorem& univ, const std::vector& subTerms) ;
// std::string getHead(const Expr& e) ;
void setupTriggers(const Theorem& thm, size_t univ_id);
void setupTriggers(ExprMap* >*>& trig_maps,
const Theorem& thm,
size_t univs_id);
void saveContext();
/*! \brief categorizes all the terms contained in an expressions by
*type.
*
* Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
* returns true if the expression does not contain bound variables, false
* otherwise.
*/
public:
TheoryQuant(TheoryCore* core); //!< Constructor
~TheoryQuant(); //! Destructor
QuantProofRules* createProofRules();
void addSharedTerm(const Expr& e) {} //!< Theory interface
/*! \brief Theory interface function to assert quantified formulas
*
* pushes in negations and converts to either universally or existentially
* quantified theorems. Universals are stored in a database while
* existentials are enqueued to be handled by the search engine.
*/
void assertFact(const Theorem& e);
/* \brief Checks the satisfiability of the universal theorems stored in a
* databse by instantiating them.
*
* There are two algorithms that the checkSat function uses to find
* instnatiations. The first algortihm looks for instanitations in a saved
* database of previous instantiations that worked in proving an earlier
* theorem unsatifiable. All of the class variables with the word saved in
* them are for the use of this algorithm. The other algorithm uses terms
* found in the assertions that exist in the particular context when
* checkSat is called. All of the class variables with the word context in
* them are used for the second algorithm.
*/
void checkSat(bool fullEffort);
void setup(const Expr& e);
void update(const Theorem& e, const Expr& d);
/*!\brief Used to notify the quantifier algorithm of possible
* instantiations that were used in proving a context inconsistent.
*/
void notifyInconsistent(const Theorem& thm);
//! computes the type of a quantified term. Always a boolean.
void computeType(const Expr& e);
Expr computeTCC(const Expr& e);
virtual Expr parseExprOp(const Expr& e);
ExprStream& print(ExprStream& os, const Expr& e);
};
}
#endif