Lumiera  0.pre.03
»edit your freedom«
common/advice/binding.hpp
Go to the documentation of this file.
1 /*
2  BINDING.hpp - pattern defining a specific attachment to the Advice system
3 
4  Copyright (C) Lumiera.org
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
74 #ifndef LUMIERA_ADVICE_BINDING_H
75 #define LUMIERA_ADVICE_BINDING_H
76 
77 
78 #include "lib/error.hpp"
79 #include "lib/symbol.hpp"
80 #include "lib/hash-value.h"
81 #include "lib/query-util.hpp"
82 
83 #include <string>
84 #include <set>
85 
86 
87 namespace lumiera{
88 namespace advice {
89 
90  using lib::Literal;
91  using std::string;
92  using lib::HashVal;
93 
94  LUMIERA_ERROR_DECLARE (BINDING_PATTERN_SYNTAX);
95 
96 
97 
108  class Binding
109  {
110 
115  class Atom
116  {
117  uint ari_;
118  string sym_;
119  string arg_;
120 
121  public:
122  explicit
123  Atom (string const& symbol ="nil", uint arity =0, string const& arg ="")
124  : ari_(arity), sym_(symbol), arg_(arg)
125  { }
126 
127  string const& sym() const { return sym_; }
128  string const& arg() const { return arg_; }
129  uint arity() const { return ari_; }
130 
131  operator string() const;
132 
133  bool
134  identical (Atom const& oa) const
135  {
136  return ari_ == oa.ari_
137  && sym_ == oa.sym_
138  && arg_ == oa.arg_;
139  }
140 
141  int
142  compare (Atom const& oa) const
143  {
144  int res;
145  if (0 != (res=sym().compare (oa.sym()))) return res;
146  if (0 != (res=arity() - (oa.arity()))) return res;
147  return arg().compare (oa.arg());
148  }
149  friend bool
151  operator< (Atom const& a1, Atom const& a2)
152  {
153  return a1.compare(a2) < 0;
154  }
155  };
156 
157 
158  typedef std::set<Atom> NormalisedAtoms;
159 
160  NormalisedAtoms atoms_;
161 
162 
163  public:
170  class Matcher
171  {
172  HashVal bindingHash_;
173 
174 
175  Matcher (HashVal ha)
176  : bindingHash_(ha)
177  { }
178 
179  friend class Binding;
180 
181 
182  public:
183  bool matches (Binding const& obi) const;
184  bool matches (Binding::Matcher const& oma) const;
185 
186  friend HashVal hash_value (Matcher const&);
187  };
188 
189 
190 
191 
193  Binding();
194 
197  Binding (Literal spec);
198 
199  /*-- Binding is default copyable --*/
200 
204  void addPredicate (Literal spec);
205 
206  template<typename TY>
207  Binding const& addTypeGuard();
208 
209 
210  Matcher buildMatcher() const;
211  HashVal calculateHash() const;
212 
213  operator string() const;
214 
215  friend bool operator== (Binding const&, Binding const&);
216 
217 
218  private:
220  void parse_and_append (Literal def);
221  };
222 
223 
224  template<typename TY>
225  inline Binding const&
226  Binding::addTypeGuard()
227  {
228  atoms_.insert (Atom ("advice.type."+lib::query::buildTypeID<TY>()));
229  return *this;
230  }
231 
232 
233 
234 
235  /* === equality comparison and matching === */
236 
237 
238  inline bool
239  operator!= (Binding const& b1, Binding const& b2)
240  {
241  return not (b1 == b2);
242  }
243 
244 
245  inline bool
246  matches (Binding const& b1, Binding const& b2)
247  {
248  return b1.buildMatcher().matches (b2);
249  }
250 
251  inline bool
252  matches (Binding::Matcher const& m1, Binding::Matcher const& m2)
253  {
254  return m1.matches (m2);
255  }
256 
257 
258  inline Binding::Matcher
259  Binding::buildMatcher() const
260  {
261  return Matcher (this->calculateHash());
262  }
263 
264 
265 
266  /* == access hash values used for matching == */
267 
268  inline bool
269  Binding::Matcher::matches (Binding const& obi) const
270  {
271  return bindingHash_ == obi.calculateHash();
272  }
273 
274  inline bool
275  Binding::Matcher::matches (Binding::Matcher const& oma) const
276  {
277  return bindingHash_ == hash_value(oma);
278  }
279 
280  inline HashVal
281  hash_value (Binding::Matcher const& bm)
282  {
283  return bm.bindingHash_;
284  }
285 
286  inline HashVal
287  hash_value (Binding const& bi)
288  {
289  return bi.calculateHash();
290  }
291 
292 
293 
294 
295 
296 
297 }} // namespace lumiera::advice
298 #endif
Utilities to support working with predicate queries.
Conjunction of predicates to be matched against a collaboration partner for establishing an Advice co...
friend bool operator==(Binding const &, Binding const &)
bindings are considered equivalent if, after normalisation, their respective definitions are identica...
void parse_and_append(Literal def)
internal: parse into atoms, and insert them
Functor object for matching against another Binding.
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:85
#define LUMIERA_ERROR_DECLARE(err)
Forward declare an error constant.
Definition: error.h:71
single predicate as part of an advice binding pattern
Marker types to indicate a literal string and a Symbol.
Lumiera error handling (C++ interface).
Hash value types and utilities.
void addPredicate(Literal spec)
extend the definition of this binding by adding a predicate according to the given textual definition...
size_t HashVal
a STL compatible hash value
Definition: hash-value.h:56
Lumiera public interface.
Definition: advice.cpp:113
int compare(Atom const &oa) const
<
Binding()
create the empty binding, equivalent to true