cnode/ILPLeaf.h
00001 /*
00002  * ILPLeaf.h
00003  *
00004  *  Created on: Sep 1, 2008
00005  *      Author: tdillig
00006  */
00007 
00008 #ifndef ILPLEAF_H_
00009 #define ILPLEAF_H_
00010 #include "CNode.h"
00011 #include "Leaf.h"
00012 #include <vector>
00013 #include <set>
00014 #include<string>
00015 #include <map>
00016 #include <boost/serialization/map.hpp>
00017 #include "Term.h"
00018 using namespace std;
00019 
00020 enum ilp_leaf_type{
00021         ILP_EQ,
00022         ILP_LEQ,
00023         ILP_LT,
00024         ILP_GEQ,
00025         ILP_GT
00026 };
00027 
00028 class VarMap;
00029 class Term;
00030 class ArithmeticTerm;
00031 
00032 
00033 class CompareILPLeaf:public binary_function<pair<Term*, int> , pair<Term*, int>, bool> {
00034 public:
00035         bool operator()(const pair<Term*, int> b1, const pair<Term*, int> b2) const;
00036 };
00037 
00038 class ILPLeaf: public Leaf {
00039         friend class boost::serialization::access;
00040 private:
00041         /*
00042          * We maintain the invariant that the terms nested inside an ILPLeaf
00043          * are only Variable or Function terms, but not constants or
00044          * arithmetic terms.
00045          */
00046         map<Term*, long int> elems;
00047         long int constant;
00048         ilp_leaf_type kind;
00049         template<class Archive>
00050         void save(Archive & ar, const unsigned int version) const
00051         {
00052                 ar & boost::serialization::base_object<Leaf>(*this);
00053                 ar & elems;
00054                 ar & constant;
00055                 ar & kind;
00056         }
00057         template<class Archive>
00058         void load(Archive & ar, const unsigned int version)
00059         {
00060                 map<Term*, long int> cur_elems;
00061                 ar & boost::serialization::base_object<Leaf>(*this);
00062                 ar & cur_elems;
00063                 ar & constant;
00064                 ar & kind;
00065                 map<Term*, long int>::iterator it = cur_elems.begin();
00066                 for(; it != cur_elems.end(); it++)
00067                 {
00068                         Term* cur = it->first;
00069                         cur = Term::get_term_nodelete(cur);
00070                         elems[cur]+=it->second;
00071                 }
00072                 compute_hash_code();
00073 
00074         }
00075         BOOST_SERIALIZATION_SPLIT_MEMBER()
00076 protected:
00077         ILPLeaf(ilp_leaf_type kind, const map<Term*, long int> & elems,
00078                         long int constant);
00079 
00080 
00081 public:
00082         ILPLeaf(){}
00083         virtual ~ILPLeaf();
00084         static CNode* make(ilp_leaf_type kind, const map<Term*, long int>& elems,
00085                         long int constant);
00086         static CNode* make(Term* t1, Term* t2, ilp_leaf_type kind);
00087 
00088         virtual bool operator==(const CNode& other);
00089         virtual string to_string();
00090         static string ilp_leaf_type_to_string(ilp_leaf_type t);
00091 
00092         inline ilp_leaf_type get_operator()
00093         {
00094                 return kind;
00095         }
00096         inline const map<Term*, long int >& get_elems()
00097         {
00098                 return elems;
00099         }
00100         inline long int get_constant()
00101         {
00102                 return constant;
00103         }
00104         long get_coefficient(Term* t);
00105         bool contains_elem(Term* t);
00106         CNode* remove_elem(Term* t);
00107         CNode* negate(bool remove_all_negations = false);
00108         virtual CNode* substitute(map<Term*, Term*>& subs);
00109         CNode* multiply(long int factor);
00110         CNode* add(ILPLeaf* other);
00111         string pretty_print_ilp(bool neg);
00112         virtual CNode*  divide(long int c, Term* t);
00113 private:
00114         void compute_hash_code();
00115         void add_term(Term* t, long int coef);
00116         static CNode* _make(ilp_leaf_type kind, const map<Term*, long int>& elems,
00117                                         long int constant, bool force_canonical);
00118 };
00119 
00120 
00121 
00122 #endif /* ILPLEAF_H_ */