OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Atom.h
Go to the documentation of this file.
1 /*
2  * opencog/atomspace/Atom.h
3  *
4  * Copyright (C) 2002-2007 Novamente LLC
5  * All Rights Reserved
6  *
7  * Written by Thiago Maia <thiago@vettatech.com>
8  * Andre Senna <senna@vettalabs.com>
9  * Welter Silva <welter@vettalabs.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU Affero General Public License v3 as
13  * published by the Free Software Foundation and including the exceptions
14  * at http://opencog.org/wiki/Licenses
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU Affero General Public License
22  * along with this program; if not, write to:
23  * Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  */
26 
27 #ifndef _OPENCOG_ATOM_H
28 #define _OPENCOG_ATOM_H
29 
30 #include <memory>
31 #include <mutex>
32 #include <set>
33 #include <string>
34 
35 #include <boost/signals2.hpp>
36 
37 #include <opencog/util/exceptions.h>
38 
43 
44 class AtomUTest;
45 
46 namespace opencog
47 {
48 
53 class Link;
54 typedef std::shared_ptr<Link> LinkPtr;
55 typedef std::vector<LinkPtr> IncomingSet; // use vector; see below.
56 typedef std::weak_ptr<Link> WinkPtr;
57 typedef std::set<WinkPtr, std::owner_less<WinkPtr> > WincomingSet;
58 typedef boost::signals2::signal<void (AtomPtr, LinkPtr)> AtomPairSignal;
59 
60 // We use a std:vector instead of std::set for IncomingSet, because
61 // virtually all access will be either insert, or iterate, so we get
62 // O(1) performance. We use std::set for WincomingSet, because we want
63 // both good insert and good remove performance. Note that sometimes
64 // incoming sets can be huge (millions of atoms).
65 
72 class Atom
73  : public std::enable_shared_from_this<Atom>
74 {
75  friend class ::AtomUTest; // Needs to call setFlag()
76  friend class AtomStorage; // Needs to set _uuid
77  friend class AtomTable; // Needs to call MarkedForRemoval()
78  friend class ImportanceIndex; // Needs to call setFlag()
79  friend class Handle; // Needs to view _uuid
80  friend class SavingLoading; // Needs to set _uuid
81  friend class TLB; // Needs to view _uuid
82  friend class CreateLink; // Needs to call getAtomTable();
83  friend class DeleteLink; // Needs to call getAtomTable();
84 
85 private:
87  void setAtomTable(AtomTable *);
88 
90  AtomTable *getAtomTable() const { return _atomTable; }
91 
92 protected:
95 
97 
98  // Byte of bitflags (each bit is a flag, see AtomSpaceDefinites.h)
99  char _flags;
100 
103 
104  // Lock, used to serialize changes.
105  // This costs 40 bytes per atom. Tried using a single, global lock,
106  // but there seemed to be too much contention for it, so instead,
107  // we are using a lock-per-atom, even though this makes the atom
108  // kind-of fat.
109  std::mutex _mtx;
110 
123  : _uuid(Handle::UNDEFINED.value()),
124  _atomTable(NULL),
125  _type(t),
126  _flags(0),
127  _truthValue(tv),
129  {}
130 
131  struct InSet
132  {
133  // The incoming set is not tracked by the garbage collector;
134  // this is required, in order to avoid cyclic references.
135  // That is, we use weak pointers here, not strong ones.
136  // std::set<ptr> uses 48 bytes (per atom). See the README file
137  // in this directory for a slightly longer explanation for why
138  // weak pointers are needed, and why bdgc cannot be used.
140 #ifdef INCOMING_SET_SIGNALS
141  // Some people want to know if the incoming set has changed...
142  // However, these make the atom quite fat, so this is disabled
143  // just right now. If users really start clamoring, then we can
144  // turn this on.
145  AtomPairSignal _addAtomSignal;
146  AtomPairSignal _removeAtomSignal;
147 #endif /* INCOMING_SET_SIGNALS */
148  };
149  typedef std::shared_ptr<InSet> InSetPtr;
151  void keep_incoming_set();
152  void drop_incoming_set();
153 
154  // Insert and remove links from the incoming set.
155  void insert_atom(LinkPtr);
156  void remove_atom(LinkPtr);
157 
158 private:
163  bool isMarkedForRemoval() const;
164 
171  bool getFlag(int) const;
172 
178  void setFlag(int, bool);
179 
181  void markForRemoval();
182 
184  void unsetRemovalFlag();
185 
187  void chgVLTI(int unit);
188 
189 public:
190 
191  virtual ~Atom();
192 
197  inline Type getType() const { return _type; }
198 
200  bool isType(Type t, bool subclass) const
201  {
202  Type at(getType());
203  if (not subclass) return t == at;
204  return classserver().isA(at, t);
205  }
206 
211  inline Handle getHandle() {
212  return Handle(shared_from_this());
213  }
214 
221 
224 
227  {
228  return getAttentionValue()->getSTI();
229  }
230 
232  {
233  return getAttentionValue()->getLTI();
234  }
235 
237  {
238  return getAttentionValue()->getVLTI();
239  }
240 
243  {
244  /* Make a copy */
246  AttentionValuePtr new_av = createAV(
247  stiValue,
248  old_av->getLTI(),
249  old_av->getVLTI());
250  setAttentionValue(new_av);
251  }
252 
255  {
257  AttentionValuePtr new_av = createAV(
258  old_av->getSTI(),
259  ltiValue,
260  old_av->getVLTI());
261  setAttentionValue(new_av);
262  }
263 
265  void incVLTI() { chgVLTI(+1); }
266 
268  void decVLTI() { chgVLTI(-1); }
269 
275 
278 
280  void merge(TruthValuePtr);
281 
288  merge(tv);
289  return Handle(shared_from_this());
290  }
291 
293  size_t getIncomingSetSize();
294 
300 
308  template <typename OutputIterator> OutputIterator
309  getIncomingSet(OutputIterator result)
310  {
311  if (NULL == _incoming_set) return result;
312  std::lock_guard<std::mutex> lck(_mtx);
313  // Sigh. I need to compose copy_if with transform. I could
314  // do this wih boost range adaptors, but I don't feel like it.
315  auto end = _incoming_set->_iset.end();
316  for (auto w = _incoming_set->_iset.begin(); w != end; w++)
317  {
318  Handle h(w->lock());
319  if (h) { *result = h; result ++; }
320  }
321  return result;
322  }
323 
328  template<class T>
329  inline bool foreach_incoming(bool (T::*cb)(const Handle&), T *data)
330  {
331  // We make a copy of the set, so that we don't call the
332  //callback with locks held.
334 
335  for (const LinkPtr& lp : vh)
336  if ((data->*cb)(Handle(lp))) return true;
337  return false;
338  }
339 
352  template <typename OutputIterator> OutputIterator
353  getIncomingSetByType(OutputIterator result,
354  Type type, bool subclass = false)
355  {
356  if (NULL == _incoming_set) return result;
357  std::lock_guard<std::mutex> lck(_mtx);
358  // Sigh. I need to compose copy_if with transform. I could
359  // do this wih boost range adaptors, but I don't feel like it.
360  auto end = _incoming_set->_iset.end();
361  for (auto w = _incoming_set->_iset.begin(); w != end; w++)
362  {
363  Handle h(w->lock());
364  if (h and h->isType(type, subclass)) {
365  *result = h;
366  result ++;
367  }
368  }
369  return result;
370  }
371 
375  IncomingSet getIncomingSetByType(Type type, bool subclass = false);
376 
382  virtual std::string toString(std::string indent = "") = 0;
383  virtual std::string toShortString(std::string indent = "") = 0;
384 
389  virtual bool operator==(const Atom&) const = 0;
390 
395  virtual bool operator!=(const Atom&) const = 0;
396 
397 
398 };
399 
401 } // namespace opencog
402 
403 #endif // _OPENCOG_ATOM_H
AttentionValuePtr getAttentionValue()
Definition: Atom.cc:146
OutputIterator getIncomingSet(OutputIterator result)
Definition: Atom.h:309
UUID _uuid
Definition: Atom.h:93
void setFlag(int, bool)
Definition: Atom.cc:218
virtual bool operator==(const Atom &) const =0
Atom(Type t, TruthValuePtr tv=TruthValue::DEFAULT_TV(), AttentionValuePtr av=AttentionValue::DEFAULT_AV())
Definition: Atom.h:121
void setSTI(AttentionValue::sti_t stiValue)
Definition: Atom.h:242
void decVLTI()
Definition: Atom.h:268
friend class Handle
Definition: Atom.h:79
IncomingSet getIncomingSet()
Definition: Atom.cc:321
void setLTI(AttentionValue::lti_t ltiValue)
Definition: Atom.h:254
AtomTable * getAtomTable() const
Returns the AtomTable in which this Atom is inserted.
Definition: Atom.h:90
short vlti_t
very long-term importance type
void chgVLTI(int unit)
Definition: Atom.cc:196
bool foreach_incoming(bool(T::*cb)(const Handle &), T *data)
Definition: Atom.h:329
std::shared_ptr< TruthValue > TruthValuePtr
Definition: TruthValue.h:85
void drop_incoming_set()
Definition: Atom.cc:279
std::shared_ptr< AttentionValue > AttentionValuePtr
friend class CreateLink
Definition: Atom.h:82
void markForRemoval()
Marks the atom for removal.
Definition: Atom.cc:232
virtual std::string toShortString(std::string indent="")=0
Handle getHandle()
Definition: Atom.h:211
void unsetRemovalFlag()
Unsets removal flag.
Definition: Atom.cc:227
char _flags
Definition: Atom.h:99
short lti_t
long-term importance type
virtual std::string toString(std::string indent="")=0
boost::signals2::signal< void(AtomPtr, LinkPtr)> AtomPairSignal
Definition: Atom.h:58
Type getType() const
Definition: Atom.h:197
AttentionValue::lti_t getLTI()
Definition: Atom.h:231
std::shared_ptr< Link > LinkPtr
Definition: Atom.h:53
void setTruthValue(TruthValuePtr)
Sets the TruthValue object of the atom.
Definition: Atom.cc:81
ClassServer & classserver(ClassServerFactory *=ClassServer::createInstance)
Definition: ClassServer.cc:159
AttentionValue::vlti_t getVLTI()
Definition: Atom.h:236
virtual bool operator!=(const Atom &) const =0
bool isType(Type t, bool subclass) const
Definition: Atom.h:200
bool isMarkedForRemoval() const
Definition: Atom.cc:208
void setAttentionValue(AttentionValuePtr)
Sets the AttentionValue object of the atom.
Definition: Atom.cc:163
void remove_atom(LinkPtr)
Remove an atom from the incoming set.
Definition: Atom.cc:300
std::weak_ptr< Link > WinkPtr
Definition: Atom.h:56
std::mutex _mtx
Definition: Atom.h:109
short sti_t
short-term importance type
unsigned long UUID
UUID == Universally Unique Identifier.
Definition: Handle.h:46
WincomingSet _iset
Definition: Atom.h:139
friend class SavingLoading
Definition: Atom.h:80
void merge(TruthValuePtr)
Definition: Atom.cc:122
static TruthValuePtr DEFAULT_TV()
Definition: TruthValue.cc:52
bool isA(Type sub, Type super)
Definition: ClassServer.h:144
std::shared_ptr< InSet > InSetPtr
Definition: Atom.h:149
bool getFlag(int) const
Definition: Atom.cc:213
std::vector< LinkPtr > IncomingSet
Definition: Atom.h:55
void incVLTI()
Definition: Atom.h:265
TruthValuePtr _truthValue
Definition: Atom.h:101
virtual ~Atom()
Definition: Atom.cc:62
static AttentionValuePtr DEFAULT_AV()
to be used as default attention value
InSetPtr _incoming_set
Definition: Atom.h:150
std::set< WinkPtr, std::owner_less< WinkPtr > > WincomingSet
Definition: Atom.h:57
TruthValuePtr getTruthValue()
Definition: Atom.cc:104
void insert_atom(LinkPtr)
Add an atom to the incoming set.
Definition: Atom.cc:289
AttentionValue::sti_t getSTI()
Handy-dandy convenience getters for attention values.
Definition: Atom.h:226
Type _type
Definition: Atom.h:96
void setAtomTable(AtomTable *)
Sets the AtomTable in which this Atom is inserted.
Definition: Atom.cc:239
unsigned short Type
type of Atoms, represented as short integer (16 bits)
Definition: types.h:40
size_t getIncomingSetSize()
Get the size of the incoming set.
Definition: Atom.cc:310
void keep_incoming_set()
Definition: Atom.cc:270
#define createAV
OutputIterator getIncomingSetByType(OutputIterator result, Type type, bool subclass=false)
Definition: Atom.h:353
Handle tvmerge(TruthValuePtr tv)
Definition: Atom.h:287
AttentionValuePtr _attentionValue
Definition: Atom.h:102
AtomTable * _atomTable
Definition: Atom.h:94