00001
00027
00028
00029
00030
00031
00032
00033 #ifndef __Substitution__
00034 #define __Substitution__
00035
00036
00037 #include "Term.hpp"
00038 #include "Lst.hpp"
00039
00040
00041 class Binding {
00042 public:
00043 Binding (Var v, const Term& t);
00044 Binding (const Binding&);
00045 ~Binding ();
00046 void operator= (const Binding& rhs);
00047
00048 Var var () const;
00049 const Term& term () const;
00050 private:
00051 class Data;
00052
00053
00054 Data* _data;
00055 };
00056
00057
00058 class Substitution
00059 : public Lst<Binding>
00060 {
00061 public:
00062 Substitution ();
00063 Substitution (const Substitution& sbst);
00064 void operator= (const Lst<Binding>& rhs);
00065
00066 void bind (Var v, Term t);
00067 bool bound (Var v, Term& t) const;
00068 void undoBinding (Var v);
00069 void domain (VarList& vs) const;
00070 void range (TermList& ts) const;
00071 bool inRange (Term t) const;
00072
00073 private:
00074 void domain (VarList& vs, Lst<Binding>) const;
00075 void range (TermList& ts, Lst<Binding>) const;
00076 Lst<Binding> undoBinding (Var v, Lst<Binding>);
00077 };
00078
00079
00080 class Binding::Data {
00081 public:
00082 Data (Var v, const Term& t);
00083
00084 Var var () const;
00085 const Term& term () const;
00086
00087 void ref ();
00088 void deref ();
00089
00090 private:
00091 int _counter;
00092 Var _var;
00093 Term _term;
00094 };
00095
00096
00097
00098
00099
00100 inline
00101 Binding::Binding (Var v, const Term& t)
00102 : _data (new Data (v,t))
00103 {
00104 }
00105
00106
00107 inline
00108 Binding::~Binding ()
00109 {
00110 if (_data) {
00111 _data->deref ();
00112 }
00113 }
00114
00115
00116 inline
00117 Binding::Binding (const Binding& t)
00118 :
00119 _data (t._data)
00120 {
00121 if (_data) {
00122 _data->ref ();
00123 }
00124 }
00125
00126
00127 inline
00128 Var Binding::var () const
00129 {
00130 return _data->var();
00131 }
00132
00133
00134 inline
00135 const Term& Binding::term () const
00136 {
00137 return _data->term();
00138 }
00139
00140
00141
00142
00143
00144 inline
00145 Binding::Data::Data (Var v, const Term& term)
00146 :
00147 _counter (1),
00148 _var (v),
00149 _term (term)
00150 {
00151 }
00152
00153
00154 inline
00155 Var Binding::Data::var () const
00156 {
00157 return _var;
00158 }
00159
00160
00161 inline
00162 const Term& Binding::Data::term () const
00163 {
00164 return _term;
00165 }
00166
00167
00168 inline
00169 void Binding::Data::ref ()
00170 {
00171 ASS (this);
00172
00173 _counter++;
00174 }
00175
00176
00177 inline
00178 void Binding::Data::deref ()
00179 {
00180 ASS (this);
00181 ASS (_counter > 0);
00182 _counter--;
00183
00184 if (_counter == 0) {
00185 delete this;
00186 }
00187 }
00188
00189
00190
00191
00192
00193 inline
00194 Substitution::Substitution ()
00195 {
00196 }
00197
00198
00199 inline
00200 Substitution::Substitution (const Substitution& sbst)
00201 : Lst<Binding> (sbst)
00202 {
00203 }
00204
00205
00206
00207
00208 inline
00209 void Substitution::operator = (const Lst<Binding>& b)
00210 {
00211 Lst<Binding>::operator= (b);
00212 }
00213
00214
00215 inline
00216 void Substitution::bind (Var v, Term t)
00217 {
00218 push (Binding(v,t));
00219 }
00220
00221
00222 inline
00223 void Substitution::domain (VarList& vs) const
00224 {
00225 domain (vs, *this);
00226 }
00227
00228
00229 inline
00230 void Substitution::range (TermList& ts) const
00231 {
00232 range (ts, *this);
00233 }
00234
00235
00236 #endif // __Substitution__
00237