solver/InteractionManager.h
00001 /*
00002  * ComparableTerms.h
00003  *
00004  *  Created on: Sep 6, 2008
00005  *      Author: tdillig
00006  */
00007 
00008 #ifndef INTERACTIONMANAGER_H_
00009 #define INTERACTIONMANAGER_H_
00010 
00011 #include <map>
00012 #include <set>
00013 #include <vector>
00014 #include <iostream>
00015 #include "bignum.h"
00016 using namespace std;
00017 
00018 #include "Term.h"
00019 class ClauseSolve;
00020 class FunctionTerm;
00021 class VarMap;
00022 class EqLeaf;
00023 class Matrix;
00024 class Equation;
00025 class VariableTerm;
00026 
00027 class TermComparator {
00028 private:
00029         Term* find_representative(Term* t)
00030         {
00031                 while(t!=t->representative)
00032                 {
00033                         if(t->representative == NULL) return t;
00034                         t = t->representative;
00035                 }
00036                 return t;
00037         }
00038 
00039 public:
00040     bool operator()(const Term* const & _q1, const Term* const & _q2)
00041     {
00042         Term* t1 = (Term*&)_q1;
00043         Term* t2 = (Term*&)_q2;
00044         Term* rep1 = find_representative(t1);
00045         Term* rep2 = find_representative(t2);
00046         return rep1<rep2;
00047     }
00048 
00049 };
00050 
00051 /*
00052  * Represents a set of ILP queries that need to be
00053  * made in order to merge equaivalence classes
00054  * class1 and class2. An ILP query with terms t1 and t2
00055  * represents the query t1 = t2
00056  * that will allow equivalence classes of t1 and t2
00057  * to merge.
00058  */
00059 class ILPQuery {
00060 public:
00061         ILPQuery(Term* rhs, Term* lhs);
00062         string to_string();
00063         Term* t1;
00064         Term* t2;
00065 };
00066 
00067 class InteractionManager {
00068 private:
00069         ClauseSolve* s;
00070 
00071         /*
00072          * A set of ILP queries we need to make (in the worst case)
00073          * until the decision procedure can decide SAT or UNSAT.
00074          */
00075         set<ILPQuery*> queries;
00076 
00077         set<Term*> representatives;
00078         set<EqLeaf*>& inequalities;
00079         map<Term*, set<Term*> >& eq_members;
00080         map<Term*, int >& eq_size;
00081         map<Term*, int> eq_constants;
00082 
00083 
00084         /*
00085          * Existing (i.e., already known) equalities and inequalities.
00086          * Note that inequalities are represented as a set of sets because the
00087          * inner set corresponds to a disjunction of inequalities obtained from
00088          * e.g., f(a, b)!= f(c,d) -> a!=c | b!=d.
00089          */
00090         set<pair<Term*, Term*> > existing_equalities;
00091         set< set<pair<Term*, Term*> > > existing_inequalities;
00092 
00093 public:
00094         InteractionManager(ClauseSolve* s,
00095                         set<Term*> & equality_terms,
00096                         set<int>& function_terms);
00097         virtual ~InteractionManager();
00098         bool add_inferred_equalities();
00099         bool add_inferred_inequalities();
00100 
00101         /*
00102          * Queries should be built once the initial set of implied
00103          * equalities and inequalities are added.
00104          */
00105         void build_queries();
00106 
00107         set<ILPQuery*> & get_queries();
00108         set<ILPQuery*> & refine_queries();
00109         string queries_to_string();
00110 private:
00111         bool add_inequality(Term* lhs, Term* rhs);
00112 
00113 
00114         Term* get_shared_member(VariableTerm* vt);
00115         bool eq_class_contains_fn_term(Term* t);
00116 
00117         /*
00118          * Makes a canonical pair such that if we call
00119          * make_term_pair(t1, t2) and make_term_pair(t2, t1),
00120          * we get the same pair back.
00121          */
00122         inline pair<Term*, Term*> make_term_pair(Term* t1, Term* t2);
00123 
00124         void get_inferred_equalities(set<Term*>& relevant_classes,
00125                         set<pair<Term*, Term*> >& inferred_eqs);
00126         void get_inferred_inequalities(set<Term*>& relevant_classes,
00127                         set<pair<Term*, Term*> >& inferred_ineqs);
00128 
00129         /*
00130          * Are the given pair of relevant congruence classes relevant for making a
00131          * query? A pair of classes is relevant to a query if their union
00132          * can either (a) result in a contradiction, (b) may lead to
00133          * inference of equalities between ilp variables, and (c) may
00134          * lead to inference of disequalities between ilp variables.
00135          */
00136         inline bool is_relevant_pair(Term* t1, Term* t2);
00137 
00138         /*
00139          * A term is relevant to the ilp domain if it's either a constant
00140          * or a variable used in the ilp domain.
00141          */
00142         inline bool is_relevant_term_to_ilp_domain(Term* t);
00143 
00144         /*
00145          * Add the query t1 = t2? to the set of queries after doing
00146          * some redundancy checks.
00147          */
00148         inline void add_query(Term* t1, Term* t2);
00149 
00150 
00151 
00152 
00153 
00154         void find_disequality_terms(Term* t1, Term* t2,
00155                         set<pair<Term*, Term*> >& terms);
00156         void find_disequality_terms_internal(Term* t1, Term* t2,
00157                         set<pair<Term*, Term*> >& terms,
00158                         map<pair<Term*, Term*>, set<pair<Term*, Term*> > >& visited,
00159                         bool check_visited);
00160 
00161         void add_disequality(Term* t1, Term* t2,
00162                         set<pair<Term*, Term*> >& to_add);
00163 
00164 
00165 
00166 };
00167 
00168 #endif /* INTERACTIONMANAGER_H_ */