34 #include <boost/bind.hpp>
52 #include <opencog/util/exceptions.h>
53 #include <opencog/util/functional.h>
54 #include <opencog/util/Logger.h>
60 using namespace opencog;
65 : _index_queue(this, &
AtomTable::put_atom_into_index)
86 std::lock_guard<std::recursive_mutex> lck(
_mtx);
106 DPRINTF(
"AtomTable::size is not 0\n");
110 std::lock_guard<std::recursive_mutex> lck(
_mtx);
119 throw opencog::RuntimeException(TRACE_INFO,
120 "AtomTable - Cannot copy an object of this class");
124 :_index_queue(this, &
AtomTable::put_atom_into_index)
126 throw opencog::RuntimeException(TRACE_INFO,
127 "AtomTable - Cannot copy an object of this class");
134 if (NUMBER_NODE == t) {
136 }
else if (TYPE_NODE == t) {
142 std::lock_guard<std::recursive_mutex> lck(
_mtx);
157 if (n->_atomTable == env)
return Handle(n);
161 return getHandle(n->getType(), n->getName());
176 bool operator()(
const Handle& h1,
const Handle& h2)
const {
183 std::lock_guard<std::recursive_mutex> lck(
_mtx);
197 if (l->_atomTable == env)
return Handle(l);
201 return getHandle(l->getType(), l->getOutgoingSet());
233 if (
this == h.
_ptr->_atomTable)
238 if (henv)
return henv;
244 std::lock_guard<std::recursive_mutex> lck(
_mtx);
261 if (atab == env)
return true;
272 if (NUMBER_NODE == atom_type) {
275 }
else if (TYPE_NODE == atom_type) {
280 }
else if (BIND_LINK == atom_type) {
283 }
else if (DEFINE_LINK == atom_type) {
293 }
else if (EVALUATION_LINK == atom_type) {
298 }
else if (EXECUTION_OUTPUT_LINK == atom_type) {
303 }
else if (GET_LINK == atom_type) {
306 }
else if (PUT_LINK == atom_type) {
309 }
else if (SATISFACTION_LINK == atom_type) {
312 }
else if (LAMBDA_LINK == atom_type) {
315 }
else if (VARIABLE_LIST == atom_type) {
318 }
else if (
classserver().isA(atom_type, FUNCTION_LINK)) {
331 if (NUMBER_NODE == atom_type)
333 if (TYPE_NODE == atom_type)
339 if (BIND_LINK == atom_type)
341 if (DEFINE_LINK == atom_type)
349 if (EVALUATION_LINK == atom_type)
352 if (EXECUTION_OUTPUT_LINK == atom_type)
355 if (GET_LINK == atom_type)
357 if (PUT_LINK == atom_type)
359 if (SATISFACTION_LINK == atom_type)
361 if (LAMBDA_LINK == atom_type)
363 if (VARIABLE_LIST == atom_type)
372 throw RuntimeException(TRACE_INFO,
373 "AtomTable - failed factory call!");
378 Logger::Level save = logger().getBackTraceLevel();
379 logger().setBackTraceLevel(Logger::Level::NONE);
380 logger().error() <<
"AtomTable - Insert link with "
381 "invalid outgoing members";
382 logger().error() <<
"Failing index i=" << i
383 <<
" and arity=" << arity;
384 logger().error() <<
"Failing outset is this:";
385 for (
unsigned int fk=0; fk<arity; fk++)
386 logger().error() <<
"outset i=" << fk
387 <<
" uuid=" << ogs[fk].value();
389 logger().error() <<
"link is " << atom->toString();
391 logger().setBackTraceLevel(save);
407 throw RuntimeException(TRACE_INFO,
408 "AtomTable - Attempting to insert atom with handle already set!");
414 std::unique_lock<std::recursive_mutex> lck(
_mtx);
418 return atom->getHandle();
421 Type atom_type = atom->getType();
422 atom =
factory(atom_type, atom);
429 if (hexist)
return hexist;
443 for (
const Handle& h : lll->getOutgoingSet()) {
444 closet.push_back(
add(h, async));
447 atom->getTruthValue(),
448 atom->getAttentionValue());
455 atom->unsetRemovalFlag();
464 const HandleSeq& ogs(lll->getOutgoingSet());
465 size_t arity = ogs.size();
470 bool need_copy =
false;
471 for (
size_t i = 0; i < arity; i++) {
480 if (NULL == h.
_ptr.get()) {
483 throw RuntimeException(TRACE_INFO,
484 "AtomTable - Attempting to insert link with "
485 "invalid outgoing members");
502 lll->_outgoing[i] = h;
522 throw RuntimeException(TRACE_INFO,
523 "AtomTable - Atom in outgoing set isn't known!");
539 for (
size_t i = 0; i < arity; i++) {
542 Handle ho(llc->_outgoing[i]);
545 llc->_outgoing[i] =
add(ho, async);
552 llc->_outgoing[i] = ((
AtomPtr) llc->_outgoing[i]);
555 llc->_outgoing[i]->insert_atom(llc);
563 if (
classserver().isA(llc->getType(), UNORDERED_LINK)) {
579 Handle h(atom->getHandle());
583 atom->keep_incoming_set();
584 atom->setAtomTable(
this);
601 DPRINTF(
"Atom added: %ld => %s\n", atom->_uuid, atom->toString().c_str());
607 std::unique_lock<std::recursive_mutex> lck(
_mtx);
608 Atom* pat = atom.operator->();
627 std::lock_guard<std::recursive_mutex> lck(
_mtx);
633 std::lock_guard<std::recursive_mutex> lck(
_mtx);
639 std::lock_guard<std::recursive_mutex> lck(
_mtx);
650 size_t x = rng->randint(
getSize());
660 if (0 == x) randy = h;
675 if (!atom || atom->isMarkedForRemoval())
return result;
681 if (atom->getAtomTable() !=
this)
return result;
687 std::unique_lock<std::recursive_mutex> lck(
_mtx);
689 if (atom->isMarkedForRemoval())
return result;
690 atom->markForRemoval();
700 IncomingSet::iterator is_it = is.begin();
701 IncomingSet::iterator is_end = is.end();
702 for (; is_it != is_end; ++is_it)
705 DPRINTF(
"[AtomTable::extract] incoming set: %s",
706 (his) ? his->
toString().c_str() :
"INVALID HANDLE");
713 if (other and other !=
this and not other->inEnviron(handle)) {
714 logger().warn() <<
"AtomTable::extract() internal error, "
715 <<
"non-DAG membership.";
718 DPRINTF(
"[AtomTable::extract] marked for removal is false");
721 result.insert(ex.begin(), ex.end());
746 size_t ilen = iset.size();
747 for (
size_t i=0; i<ilen; i++)
766 if (iset[i]->getAtomTable() != NULL and
767 (not iset[i]->getAtomTable()->
inEnviron(handle) or
768 not iset[i]->isMarkedForRemoval()))
770 Logger::Level lev = logger().getBackTraceLevel();
771 logger().setBackTraceLevel(Logger::ERROR);
772 logger().warn() <<
"AtomTable::extract() internal error";
773 logger().warn() <<
"Non-empty incoming set of size "
774 << ilen <<
" First trouble at " << i;
775 logger().warn() <<
"This atomtable=" << ((
void*)
this)
776 <<
" other atomtale=" << ((
void*) iset[i]->getAtomTable())
777 <<
" inEnviron=" << iset[i]->getAtomTable()->inEnviron(handle);
778 logger().warn() <<
"This atom: " << handle->
toString();
779 for (
size_t j=0; j<ilen; j++) {
780 logger().warn() <<
"Atom j=" << j <<
" " << iset[j]->toString();
781 logger().warn() <<
"Marked: " << iset[j]->isMarkedForRemoval()
782 <<
" Table: " << ((
void*) iset[j]->getAtomTable());
784 logger().setBackTraceLevel(lev);
785 atom->unsetRemovalFlag();
786 throw RuntimeException(TRACE_INFO,
787 "Internal Error: Cannot extract an atom with "
788 "a non-empty incoming set!");
806 Atom* pat = atom.operator->();
822 atom->setAtomTable(NULL);
831 std::lock_guard<std::recursive_mutex> lck(
_mtx);
boost::signals2::connection addedTypeConnection
static TypeNodePtr TypeNodeCast(const Handle &h)
static PutLinkPtr PutLinkCast(const Handle &h)
static DefineLinkPtr DefineLinkCast(const Handle &h)
static AtomPtr clone_factory(Type atom_type, AtomPtr atom)
IncomingSet getIncomingSet()
std::vector< Handle > HandleSeq
a list of handles
std::shared_ptr< Atom > AtomPtr
AtomTable * getAtomTable() const
Returns the AtomTable in which this Atom is inserted.
size_t size(size_t i) const
static std::string validate(const std::string &str)
std::unordered_set< Handle, handle_hash > _atom_set
void removeAtom(const AtomPtr &)
#define createPatternLink
static std::recursive_mutex _mtx
Atom * getAtom(Type type, const std::string &str) const
AtomTable(const AtomTable &)
void unsetRemovalFlag()
Unsets removal flag.
static BindLinkPtr BindLinkCast(const Handle &h)
virtual std::string toString(std::string indent="")=0
Handle add(AtomPtr, bool async)
static void prt_diag(AtomPtr atom, size_t i, size_t arity, const HandleSeq &ogs)
std::shared_ptr< Link > LinkPtr
static void reserve_upto(UUID hi)
AtomPtrSet extract(Handle &handle, bool recursive=true)
ClassServer & classserver(ClassServerFactory *=ClassServer::createInstance)
size_t getNumAtomsOfType(Type type, bool subclass) const
Handle getRandom(RandGen *rng) const
static NodePtr NodeCast(const Handle &h)
async_caller< AtomTable, AtomPtr > _index_queue
bool isMarkedForRemoval() const
void remove_atom(LinkPtr)
Remove an atom from the incoming set.
static const Handle UNDEFINED
Handle getHandle(Type, std::string) const
size_t getNumNodes() const
static void validate(const std::string &str)
unsigned long UUID
UUID == Universally Unique Identifier.
#define createVariableList
TypeSignal & addTypeSignal()
void insertAtom(const AtomPtr &)
void foreachHandleByType(Function func, Type type, bool subclass=false, bool parent=true) const
size_t getNumAtomsOfType(Type type, bool subclass=true) const
static VariableListPtr VariableListCast(const Handle &h)
size_t getNumLinks() const
static LinkPtr LinkCast(const Handle &h)
static PatternLinkPtr PatternLinkCast(const Handle &h)
static NumberNodePtr NumberNodeCast(const Handle &h)
AtomTable & operator=(const AtomTable &)
std::vector< LinkPtr > IncomingSet
AtomSignal _addAtomSignal
std::shared_ptr< Node > NodePtr
void put_atom_into_index(AtomPtr &)
static LambdaLinkPtr LambdaLinkCast(const Handle &h)
static AtomPtr factory(Type atom_type, AtomPtr atom)
static UUID reserve_extent(UUID extent)
void insert_atom(LinkPtr)
Add an atom to the incoming set.
static void set_resolver(const AtomTable *)
std::set< AtomPtr > AtomPtrSet
ImportanceIndex importanceIndex
unsigned short Type
type of Atoms, represented as short integer (16 bits)
size_t getIncomingSetSize()
Get the size of the incoming set.
static void clear_resolver(const AtomTable *)
Handle getHandle(Type type, const HandleSeq &) const
AtomPtrSignal _removeAtomSignal
static int compare(const Handle &h1, const Handle &h2)
static void addAtom(AtomPtr atom)