<commit_before>/*
 * opencog/atomspace/AtomSpace.cc
 *
 * Copyright (C) 2002-2007 Novamente LLC
 * All Rights Reserved
 *
 * Written by <NAME> <<EMAIL>>
 *            <NAME> <<EMAIL>>
 *            <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "AtomSpace.h"

#include <string>
#include <iostream>
#include <list>

#include <stdlib.h>

#include <opencog/atomspace/ClassServer.h>
#include <opencog/atomspace/CompositeTruthValue.h>
#include <opencog/atomspace/HandleEntry.h>
#include <opencog/atomspace/IndefiniteTruthValue.h>
#include <opencog/atomspace/Link.h>
#include <opencog/atomspace/Node.h>
#include <opencog/atomspace/SimpleTruthValue.h>
#include <opencog/atomspace/StatisticsMonitor.h>
#include <opencog/atomspace/TLB.h>
#include <opencog/atomspace/types.h>
#include <opencog/util/Config.h>
#include <opencog/util/Logger.h>
#include <opencog/util/oc_assert.h>

//#define DPRINTF printf
#define DPRINTF(...)

using std::string;
using std::cerr;
using std::cout;
using std::endl;
using std::min;
using std::max;
using namespace opencog;

// ====================================================================

AtomSpace::AtomSpace(void) : 
    type_itr(0,false)
{
    _handle_iterator = NULL;
    emptyName = "";
    backing_store = NULL;

    // XXX this is wrong, the space server should live in its own
    // directory, and not here. It needs to use the addAtom, removeAtom
    // signals to get its work done.
    spaceServer = new SpaceServer(*this);

    fundsSTI = config().get_int("STARTING_STI_FUNDS");
    fundsLTI = config().get_int("STARTING_LTI_FUNDS");
    attentionalFocusBoundary = 1;

    //connect signals
    addedAtomConnection = addAtomSignal().connect(boost::bind(&AtomSpace::atomAdded, this, _1));
    removedAtomConnection = removeAtomSignal().connect(boost::bind(&AtomSpace::atomRemoved, this, _1));

    logger().fine("Max load factor for handle map is: %f", TLB::handle_map.max_load_factor());

}

AtomSpace::~AtomSpace()
{
    //disconnect signals
    addedAtomConnection.disconnect();
    removedAtomConnection.disconnect();


    // Check if has already been deleted. See in code where it can be delete.
    if (_handle_iterator) {
        delete _handle_iterator;
         _handle_iterator = NULL;
    }
    delete spaceServer;
    spaceServer = NULL;
}

// ====================================================================

void AtomSpace::registerBackingStore(BackingStore *bs)
{
    backing_store = bs;
}

void AtomSpace::unregisterBackingStore(BackingStore *bs)
{
    if (bs == backing_store) backing_store = NULL;
}

// ====================================================================

void AtomSpace::atomAdded(Handle h)
{
    DPRINTF("AtomSpace::atomAdded(%p): %s\n", h, TLB::getAtom(h)->toString().c_str());
    Type type = getType(h);
    if (type == AT_TIME_LINK) {
        // Add corresponding TimeServer entry
        if (getArity(h) == 2) {
            Handle timeNode = getOutgoing(h, 0);
            if (getType(timeNode) == TIME_NODE) {
                const string& timeNodeName = getName(timeNode);
                Temporal t = Temporal::getFromTimeNodeName(timeNodeName.c_str());
                Handle timed_h = getOutgoing(h, 1);
                timeServer.add(timed_h, t);
            } else logger().warn("AtomSpace::atomAdded: Invalid atom type at the first element in an AtTimeLink's outgoing: %s\n", classserver().getTypeName(getType(timeNode)).c_str());
        } else logger().warn("AtomSpace::atomAdded: Invalid arity for an AtTimeLink: %d (expected: 2)\n", getArity(h));
    } else if (type == CONTEXT_LINK) {
        // Add corresponding VersionedTV to the contextualized atom
        // Note that when a VersionedTV is added to a
        // CompositeTruthValue it will not automatically add a
        // corresponding ContextLink
        if (getArity(h) == 2) {
            Handle ca = getOutgoing(h, 1); // contextualized atom
            setTV(ca, getTV(h), VersionHandle(CONTEXTUAL, h));
        } else logger().warn("AtomSpace::atomAdded: Invalid arity for a ContextLink: %d (expected: 2)\n", getArity(h));
    }
}

void AtomSpace::atomRemoved(Handle h)
{
    Type type = getType(h);
    if (type == AT_TIME_LINK)
    {
        OC_ASSERT(getArity(h) == 2, "AtomSpace::atomRemoved: Got invalid arity for removed AtTimeLink = %d\n", getArity(h));
        Handle timeNode = getOutgoing(h, 0);
        OC_ASSERT(getType(timeNode) == TIME_NODE, "AtomSpace::atomRemoved: Got no TimeNode node at the first position of the AtTimeLink\n");
        Handle timedAtom = getOutgoing(h, 1);
        timeServer.remove(timedAtom, Temporal::getFromTimeNodeName(((Node*) TLB::getAtom(timeNode))->getName().c_str()));

        // XXX THIS IS WRONG --- instead, the space server
        // should listen for the removeAtomSignal signal, and go with that.
        // if outgoingSet[1] is a SpaceMap concept node, remove related map from SpaceServer
        if( getHandle(CONCEPT_NODE, SpaceServer::SPACE_MAP_NODE_NAME) == timedAtom ){
           spaceServer->removeMap(h);
        } // if
    } else if (type == CONTEXT_LINK) {
        // Remove corresponding VersionedTV to the contextualized atom
        // Note that when a VersionedTV is removed from a
        // CompositeTruthValue it will not automatically remove the
        // corresponding ContextLink
        OC_ASSERT(getArity(h) == 2, "AtomSpace::atomRemoved: Got invalid arity for removed ContextLink = %d\n", getArity(h));
        OC_ASSERT(false);
        Handle ca = getOutgoing(h, 1); // contextualized atom
        const TruthValue& tv = getTV(ca);
        OC_ASSERT(tv.getType() == COMPOSITE_TRUTH_VALUE);
        // obviously using a const_cast is rather hacky and should
        // probably be replaced by something better
        CompositeTruthValue& ctv = const_cast<CompositeTruthValue&>(static_cast<const CompositeTruthValue&>(tv));
        ctv.removeVersionedTV(VersionHandle(CONTEXTUAL, h));
    } else if ( inheritsType(type, OBJECT_NODE) ) {
        spaceServer->removeObject(getName(h));
    } // else if
}

// ====================================================================

const AtomTable& AtomSpace::getAtomTable() const
{
    DPRINTF("AtomSpace::getAtomTable Atom space address: %p\n", this);
    return atomTable;
}

const TimeServer& AtomSpace::getTimeServer() const
{
    DPRINTF("AtomSpace::getTimeServer Atom space address: %p\n", this);

    return timeServer;
}

SpaceServer& AtomSpace::getSpaceServer() const
{
    DPRINTF("AtomSpace::getSpaceServer Atom space address: %p\n", this);
<commit_msg>fixed CONTEXT_LINK case of AtomSpace::atomRemoved<commit_after>/*
 * opencog/atomspace/AtomSpace.cc
 *
 * Copyright (C) 2002-2007 Novamente LLC
 * All Rights Reserved
 *
 * Written by <NAME> <<EMAIL>>
 *            <NAME> <<EMAIL>>
 *            <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "AtomSpace.h"

#include <string>
#include <iostream>
#include <list>

#include <stdlib.h>

#include <opencog/atomspace/ClassServer.h>
#include <opencog/atomspace/CompositeTruthValue.h>
#include <opencog/atomspace/HandleEntry.h>
#include <opencog/atomspace/IndefiniteTruthValue.h>
#include <opencog/atomspace/Link.h>
#include <opencog/atomspace/Node.h>
#include <opencog/atomspace/SimpleTruthValue.h>
#include <opencog/atomspace/StatisticsMonitor.h>
#include <opencog/atomspace/TLB.h>
#include <opencog/atomspace/types.h>
#include <opencog/util/Config.h>
#include <opencog/util/Logger.h>
#include <opencog/util/oc_assert.h>

//#define DPRINTF printf
#define DPRINTF(...)

using std::string;
using std::cerr;
using std::cout;
using std::endl;
using std::min;
using std::max;
using namespace opencog;

// ====================================================================

AtomSpace::AtomSpace(void) : 
    type_itr(0,false)
{
    _handle_iterator = NULL;
    emptyName = "";
    backing_store = NULL;

    // XXX this is wrong, the space server should live in its own
    // directory, and not here. It needs to use the addAtom, removeAtom
    // signals to get its work done.
    spaceServer = new SpaceServer(*this);

    fundsSTI = config().get_int("STARTING_STI_FUNDS");
    fundsLTI = config().get_int("STARTING_LTI_FUNDS");
    attentionalFocusBoundary = 1;

    //connect signals
    addedAtomConnection = addAtomSignal().connect(boost::bind(&AtomSpace::atomAdded, this, _1));
    removedAtomConnection = removeAtomSignal().connect(boost::bind(&AtomSpace::atomRemoved, this, _1));

    logger().fine("Max load factor for handle map is: %f", TLB::handle_map.max_load_factor());

}

AtomSpace::~AtomSpace()
{
    //disconnect signals
    addedAtomConnection.disconnect();
    removedAtomConnection.disconnect();


    // Check if has already been deleted. See in code where it can be delete.
    if (_handle_iterator) {
        delete _handle_iterator;
         _handle_iterator = NULL;
    }
    delete spaceServer;
    spaceServer = NULL;
}

// ====================================================================

void AtomSpace::registerBackingStore(BackingStore *bs)
{
    backing_store = bs;
}

void AtomSpace::unregisterBackingStore(BackingStore *bs)
{
    if (bs == backing_store) backing_store = NULL;
}

// ====================================================================

void AtomSpace::atomAdded(Handle h)
{
    DPRINTF("AtomSpace::atomAdded(%p): %s\n", h, TLB::getAtom(h)->toString().c_str());
    Type type = getType(h);
    if (type == AT_TIME_LINK) {
        // Add corresponding TimeServer entry
        if (getArity(h) == 2) {
            Handle timeNode = getOutgoing(h, 0);
            if (getType(timeNode) == TIME_NODE) {
                const string& timeNodeName = getName(timeNode);
                Temporal t = Temporal::getFromTimeNodeName(timeNodeName.c_str());
                Handle timed_h = getOutgoing(h, 1);
                timeServer.add(timed_h, t);
            } else logger().warn("AtomSpace::atomAdded: Invalid atom type at the first element in an AtTimeLink's outgoing: %s\n", classserver().getTypeName(getType(timeNode)).c_str());
        } else logger().warn("AtomSpace::atomAdded: Invalid arity for an AtTimeLink: %d (expected: 2)\n", getArity(h));
    } else if (type == CONTEXT_LINK) {
        // Add corresponding VersionedTV to the contextualized atom
        // Note that when a VersionedTV is added to a
        // CompositeTruthValue it will not automatically add a
        // corresponding ContextLink
        if (getArity(h) == 2) {
            Handle ca = getOutgoing(h, 1); // contextualized atom
            setTV(ca, getTV(h), VersionHandle(CONTEXTUAL, h));
        } else logger().warn("AtomSpace::atomAdded: Invalid arity for a ContextLink: %d (expected: 2)\n", getArity(h));
    }
}

void AtomSpace::atomRemoved(Handle h)
{
    Type type = getType(h);
    if (type == AT_TIME_LINK)
    {
        OC_ASSERT(getArity(h) == 2, "AtomSpace::atomRemoved: Got invalid arity for removed AtTimeLink = %d\n", getArity(h));
        Handle timeNode = getOutgoing(h, 0);
        OC_ASSERT(getType(timeNode) == TIME_NODE, "AtomSpace::atomRemoved: Got no TimeNode node at the first position of the AtTimeLink\n");
        Handle timedAtom = getOutgoing(h, 1);
        timeServer.remove(timedAtom, Temporal::getFromTimeNodeName(((Node*) TLB::getAtom(timeNode))->getName().c_str()));

        // XXX THIS IS WRONG --- instead, the space server
        // should listen for the removeAtomSignal signal, and go with that.
        // if outgoingSet[1] is a SpaceMap concept node, remove related map from SpaceServer
        if( getHandle(CONCEPT_NODE, SpaceServer::SPACE_MAP_NODE_NAME) == timedAtom ){
           spaceServer->removeMap(h);
        } // if
    } else if (type == CONTEXT_LINK) {
        // Remove corresponding VersionedTV to the contextualized atom
        // Note that when a VersionedTV is removed from a
        // CompositeTruthValue it will not automatically remove the
        // corresponding ContextLink
        OC_ASSERT(getArity(h) == 2, "AtomSpace::atomRemoved: Got invalid arity for removed ContextLink = %d\n", getArity(h));
        Handle ca = getOutgoing(h, 1); // contextualized atom
        const TruthValue& tv = getTV(ca);
        OC_ASSERT(tv.getType() == COMPOSITE_TRUTH_VALUE);
        CompositeTruthValue new_ctv(static_cast<const CompositeTruthValue&>(tv));
        new_ctv.removeVersionedTV(VersionHandle(CONTEXTUAL, h));
        // @todo: one may improve that code by converting back the
        // CompositeTV into a simple or indefinite TV when it has more
        // VersionedTV
        setTV(ca, new_ctv);
    } else if ( inheritsType(type, OBJECT_NODE) ) {
        spaceServer->removeObject(getName(h));
    } // else if
}

// ====================================================================

const AtomTable& AtomSpace::getAtomTable() const
{
    DPRINTF("AtomSpace::getAtomTable Atom space address: %p\n", this);
    return atomTable;
}

const TimeServer& AtomSpace::getTimeServer() const
{
    DPRINTF("AtomSpace::getTimeServer Atom space address: %p\n", this);

    return timeServer;
}

SpaceServer& AtomSpace::getSpaceServer() const
{
    DPRINTF("AtomSpace::getSpaceServer Atom space address: %p\n", this);

{'fraction_non_alphanumeric': 0.15078821110349555, 'fraction_numerical': 0.005071967100753941, 'mean_word_length': 3.6586845466155813, 'pattern_counts': {'":': 0, '<': 58, '<?xml version=': 0, '>': 66, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '496107', 'n_tokens_mistral': 4523, 'n_tokens_neox': 4385, 'n_words': 1215}