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)
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
65 #ifndef LUMIERA_ADVICE_BINDING_H
66 #define LUMIERA_ADVICE_BINDING_H
67 
68 
69 #include "lib/error.hpp"
70 #include "lib/symbol.hpp"
71 #include "lib/hash-value.h"
72 #include "lib/query-util.hpp"
73 
74 #include <string>
75 #include <set>
76 
77 
78 namespace lumiera{
79 namespace advice {
80 
81  using lib::Literal;
82  using std::string;
83  using lib::HashVal;
84 
85  LUMIERA_ERROR_DECLARE (BINDING_PATTERN_SYNTAX);
86 
87 
88 
99  class Binding
100  {
101 
106  class Atom
107  {
108  uint ari_;
109  string sym_;
110  string arg_;
111 
112  public:
113  explicit
114  Atom (string const& symbol ="nil", uint arity =0, string const& arg ="")
115  : ari_(arity), sym_(symbol), arg_(arg)
116  { }
117 
118  string const& sym() const { return sym_; }
119  string const& arg() const { return arg_; }
120  uint arity() const { return ari_; }
121 
122  operator string() const;
123 
124  bool
125  identical (Atom const& oa) const
126  {
127  return ari_ == oa.ari_
128  && sym_ == oa.sym_
129  && arg_ == oa.arg_;
130  }
131 
132  int
133  compare (Atom const& oa) const
134  {
135  int res;
136  if (0 != (res=sym().compare (oa.sym()))) return res;
137  if (0 != (res=arity() - (oa.arity()))) return res;
138  return arg().compare (oa.arg());
139  }
140  friend bool
142  operator< (Atom const& a1, Atom const& a2)
143  {
144  return a1.compare(a2) < 0;
145  }
146  };
147 
148 
149  typedef std::set<Atom> NormalisedAtoms;
150 
151  NormalisedAtoms atoms_;
152 
153 
154  public:
161  class Matcher
162  {
163  HashVal bindingHash_;
164 
165 
166  Matcher (HashVal ha)
167  : bindingHash_(ha)
168  { }
169 
170  friend class Binding;
171 
172 
173  public:
174  bool matches (Binding const& obi) const;
175  bool matches (Binding::Matcher const& oma) const;
176 
177  friend HashVal hash_value (Matcher const&);
178  };
179 
180 
181 
182 
184  Binding();
185 
188  Binding (Literal spec);
189 
190  /*-- Binding is default copyable --*/
191 
195  void addPredicate (Literal spec);
196 
197  template<typename TY>
198  Binding const& addTypeGuard();
199 
200 
201  Matcher buildMatcher() const;
202  HashVal calculateHash() const;
203 
204  operator string() const;
205 
206  friend bool operator== (Binding const&, Binding const&);
207 
208 
209  private:
211  void parse_and_append (Literal def);
212  };
213 
214 
215  template<typename TY>
216  inline Binding const&
217  Binding::addTypeGuard()
218  {
219  atoms_.insert (Atom ("advice.type."+lib::query::buildTypeID<TY>()));
220  return *this;
221  }
222 
223 
224 
225 
226  /* === equality comparison and matching === */
227 
228 
229  inline bool
230  operator!= (Binding const& b1, Binding const& b2)
231  {
232  return not (b1 == b2);
233  }
234 
235 
236  inline bool
237  matches (Binding const& b1, Binding const& b2)
238  {
239  return b1.buildMatcher().matches (b2);
240  }
241 
242  inline bool
243  matches (Binding::Matcher const& m1, Binding::Matcher const& m2)
244  {
245  return m1.matches (m2);
246  }
247 
248 
249  inline Binding::Matcher
250  Binding::buildMatcher() const
251  {
252  return Matcher (this->calculateHash());
253  }
254 
255 
256 
257  /* == access hash values used for matching == */
258 
259  inline bool
260  Binding::Matcher::matches (Binding const& obi) const
261  {
262  return bindingHash_ == obi.calculateHash();
263  }
264 
265  inline bool
266  Binding::Matcher::matches (Binding::Matcher const& oma) const
267  {
268  return bindingHash_ == hash_value(oma);
269  }
270 
271  inline HashVal
272  hash_value (Binding::Matcher const& bm)
273  {
274  return bm.bindingHash_;
275  }
276 
277  inline HashVal
278  hash_value (Binding const& bi)
279  {
280  return bi.calculateHash();
281  }
282 
283 
284 
285 
286 
287 
288 }} // namespace lumiera::advice
289 #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:76
#define LUMIERA_ERROR_DECLARE(err)
Forward declare an error constant.
Definition: error.h:62
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:52
Lumiera public interface.
Definition: advice.cpp:104
int compare(Atom const &oa) const
<
Binding()
create the empty binding, equivalent to true