term/ArithmeticTerm.h
00001 /*
00002  * ArithmeticTerm.h
00003  *
00004  *  Created on: Oct 5, 2008
00005  *      Author: isil
00006  */
00007 
00008 #ifndef ARITHMETICTERM_H_
00009 #define ARITHMETICTERM_H_
00010 #include <boost/serialization/map.hpp>
00011 #include "Term.h"
00012 
00013 
00014 
00015 Term* _make_ap(const map<Term*, long int>& elems, long int c);
00016 
00017 class ArithmeticTerm: public Term {
00018         friend class boost::serialization::access;
00019 private:
00020         map<Term*, long int > elems;
00021         long int constant;
00022         int elem_gcd;
00023         template<class Archive>
00024         void save(Archive & ar, const unsigned int version) const
00025         {
00026                 ar & boost::serialization::base_object<Term>(*this);
00027                 ar & elems;
00028                 ar & constant;
00029                 ar & elem_gcd;
00030         }
00031         template<class Archive>
00032         void load(Archive & ar, const unsigned int version)
00033         {
00034                 ar & boost::serialization::base_object<Term>(*this);
00035                 map<Term*, long int > cur_elems;
00036                 ar & cur_elems;
00037                 ar & constant;
00038                 ar & elem_gcd;
00039                 map<Term*, long int >::iterator it = cur_elems.begin();
00040                 for(; it!= cur_elems.end(); it++)
00041                 {
00042                         Term* t = it->first;
00043                         t = get_term_nodelete(t);
00044                         elems[t]+=it->second;
00045                 }
00046                 compute_hash_code();
00047 
00048         }
00049         BOOST_SERIALIZATION_SPLIT_MEMBER()
00050 protected:
00051         ArithmeticTerm(){}
00052 public:
00053         ArithmeticTerm(const map<Term*, long int>& elems,long int constant);
00054 protected:
00058         ArithmeticTerm(Term* t1, long int c1, Term* t2, long int c2);
00059 
00063         ArithmeticTerm(Term* t, long int c);
00064         virtual ~ArithmeticTerm();
00065 public:
00066         static Term* make(const map<Term*, long int>& elems,long int constant)
00067         {
00068                 ArithmeticTerm* at;
00069 #ifdef COMPASS
00070                 Term* t = _make_ap(elems, constant);
00071                 if(t->get_term_type() != ARITHMETIC_TERM) return t;
00072                 at = (ArithmeticTerm*) t;
00073 #endif
00074 #ifndef COMPASS
00075                 at = _make(elems, constant);
00076 #endif
00077 
00078                 return canonicalize(at);
00079         }
00080         static Term* make(const map<Term*, long int>& elems)
00081         {
00082                 ArithmeticTerm* at;
00083 #ifdef COMPASS
00084                 Term* t = _make_ap(elems, 0);
00085                 if(t->get_term_type() != ARITHMETIC_TERM) return t;
00086                 at = (ArithmeticTerm*) t;
00087 #endif
00088 #ifndef COMPASS
00089                 at = _make(elems, 0);
00090 #endif
00091 
00092                 return canonicalize(at);
00093         }
00094 
00095 
00096 
00097         static ArithmeticTerm* _make(const map<Term*, long int>& elems,long int constant);
00098         inline const map<Term*, long int>& get_elems()
00099         {
00100                 return elems;
00101         }
00102         inline long int get_constant()
00103         {
00104                 return constant;
00105         }
00106         virtual bool operator==(const Term& other);
00107         virtual string to_string();
00108         virtual Term* substitute(map<Term*, Term*>& subs);
00109         long int get_gcd(bool include_constant);
00110         /*
00111          * Are the coefficients of all elements negative?
00112          */
00113         bool has_only_negative_coefficients();
00114 
00115         /*
00116          * Base of an arithmetic term is the same arithmetic term, but constant is 0.
00117          */
00118         Term* get_base();
00119 private:
00120         void compute_hash_code();
00121         void add_elem(Term* t, long int constant);
00122         static Term* canonicalize(ArithmeticTerm* at);
00123 
00124 };
00125 
00126 
00127 #endif /* ARITHMETICTERM_H_ */