<commit_before>/*
 * Copyright (C) 2002-2007 Novamente LLC
 * Copyright (C) 2008 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * Authors:
 * <NAME>
 * <NAME>
 *
 * 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.
 */

#ifndef ATW_H
#define ATW_H

#include <time.h>
#include <queue>
#include <vector>

#include <boost/config.hpp>
#include <boost/smart_ptr.hpp>
// Attempted to use boost::bimap in boost 1.35+ but had too much trouble
//#include <boost/bimap/unordered_set_of.hpp>
//#include <boost/bimap/multiset_of.hpp>
//#include <map>
//#include <boost/bimap/bimap.hpp>

#include <opencog/atomspace/TimeServer.h>
#include <opencog/atomspace/type_codes.h>

#include "PLN.h"

#include "iAtomSpaceWrapper.h"
#include "rules/Rule.h"
#include "utils/fim.h"
#include "utils/Singleton.h"

//! The value at which PLN considers a TV a binary True.
#define PLN_TRUE_MEAN 0.989

//using namespace boost::bimaps;

//! TODO: use static accessor method within AtomSpaceWrapper class instead of global
#define GET_ATW ((AtomSpaceWrapper*) ::haxx::defaultAtomSpaceWrapper)

namespace reasoning
{
//! Construct a vtree around Handle h
vtree make_vtree(Handle h);

typedef std::pair<Handle,VersionHandle> vhpair;

/** The bridge between the OpenCog AtomSpace and PLN.
 *
 * <h2>Fixing Fresh = true</h2>
 * 
 * The original version of Probabilistic Logic Networks made improper use of a
 * parameter in Novemente called \b fresh when adding new atoms to the
 * AtomSpace. This allowed atoms to be added to the AtomSpace without checking
 * for duplicates. The end result is that atoms were no longer unique: nodes
 * with the same name and type, or links that had the same outgoing set and
 * type, could duplicated. OpenCog does not allow this behaviour.
 * 
 * To fix this, all accesses to the AtomSpace now occur through the
 * AtomSpaceWrapper, which presents fake Handles to PLN and interprets them to a
 * combination of a real \c Handle and a \c VersionHandle. A system of dummy
 * contexts is used to emulate the behaviour of allowing duplicate atoms in the
 * AtomSpace by storing multiple \c TruthValues within a CompositeTruthValue.
 *
 * The AtomSpaceWrapper did exist in the original PLN, but it was more for
 * carrying out normalisation and allowing different AtomSpace backends to be
 * used for efficiency reasons. 
 * 
 * Dummy contexts are represented as directed links. A root dummy context,
 * represented as a Concept Node with name "___PLN___" is used for the outgoing
 * set of dummy contexts in duplicate nodes. For links that are duplicates the
 * outgoing set of their dummy context consists of the dummy context of any
 * duplicate atoms they refer to, or the root dummy context if they refer to the
 * original version of an atom.
 * 
 * <h3> Node example </h3>
 *
 * If a node already exists, then a dummy context is created that links to the
 * root PLN dummy context.
 * 
 * E.g. say we have
 *
 * \code
 *  ConceptNode "x" <0.8, 0.9>
 * \endcode
 *
 * and we want to add a new node with the same name and type, but with TV
 * <0.5,0.5>. To achieve this we create a new dummy context link:
 *
 * \code
 *  dc <- OrderedLink (ConceptNode "___PLN___")
 * \endcode
 * 
 * \c dc is then used as the context for the new TV:
 * 
 * \code
 *  ConceptNode "x" <0.8, 0.9> [ Context dc <0.5, 0.5> ]
 * \endcode
 * 
 * <h3> Link example </h3>
 * 
 * If a link already exists, then the appropriate contexts for each outgoing
 * atom are linked by a new dummy context link (with the appropriate context
 * links of each atom in the outgoing set of the link in the same order as the
 * outgoing set of the existing link).
 * 
 * E.g. say we have an InheritanceLink composed of two ConceptNodes that both
 * have CompositeTruthValues:
 * 
 * \code
 *  dc_x <- OrderedLink (ConceptNode "__PLN__")
 *  dc_y <- OrderedLink (ConceptNode "__PLN__")
 *  InheritanceLink <0.8, 0.9>
 *      ConceptNode "x" <0.8, 0.9> [ Context dc_x <0.5, 0.5> ]
 *      ConceptNode "y" <0.8, 0.9> [ Context dc_y <0.1, 0.5> ]
 * \endcode
 * 
 * If we want to create another link with a different \c TruthValue, but between
 * the versions of x and y that are under the dummy context (instead of the
 * original TruthValues) then we get:
 * 
 * \code
 *  dc_x_y <- OrderedLink (dc_x dc_y)
 *  InheritanceLink <0.8, 0.9> [ Context dc_x_y <0.3, 0.5> ]
 *      ConceptNode "x" <0.8, 0.9> [ Context dc_x <0.5, 0.5> ]
 *      ConceptNode "y" <0.8, 0.9> [ Context dc_y <0.1, 0.5> ]
 * \endcode
 */
class AtomSpaceWrapper : public iAtomSpaceWrapper
{
    //! How to represent the universe size
    // CONST_SIZE = constant value
    // REAL_SIZE  = actual size of knowledge/experience
    enum USizeMode_t { CONST_SIZE, REAL_SIZE };
<commit_msg>Update documentation on dummy contexts<commit_after>/*
 * Copyright (C) 2002-2007 Novamente LLC
 * Copyright (C) 2008 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * Authors:
 * <NAME>
 * <NAME>
 *
 * 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.
 */

#ifndef ATW_H
#define ATW_H

#include <time.h>
#include <queue>
#include <vector>

#include <boost/config.hpp>
#include <boost/smart_ptr.hpp>
// Attempted to use boost::bimap in boost 1.35+ but had too much trouble
//#include <boost/bimap/unordered_set_of.hpp>
//#include <boost/bimap/multiset_of.hpp>
//#include <map>
//#include <boost/bimap/bimap.hpp>

#include <opencog/atomspace/TimeServer.h>
#include <opencog/atomspace/type_codes.h>

#include "PLN.h"

#include "iAtomSpaceWrapper.h"
#include "rules/Rule.h"
#include "utils/fim.h"
#include "utils/Singleton.h"

//! The value at which PLN considers a TV a binary True.
#define PLN_TRUE_MEAN 0.989

//using namespace boost::bimaps;

//! TODO: use static accessor method within AtomSpaceWrapper class instead of global
#define GET_ATW ((AtomSpaceWrapper*) ::haxx::defaultAtomSpaceWrapper)

namespace reasoning
{
//! Construct a vtree around Handle h
vtree make_vtree(Handle h);

typedef std::pair<Handle,VersionHandle> vhpair;

/** The bridge between the OpenCog AtomSpace and PLN.
 *
 * <h2>Fixing Fresh = true</h2>
 * 
 * The original version of Probabilistic Logic Networks made improper use of a
 * parameter in Novemente called \b fresh when adding new atoms to the
 * AtomSpace. This allowed atoms to be added to the AtomSpace without checking
 * for duplicates. The end result is that atoms were no longer unique: nodes
 * with the same name and type, or links that had the same outgoing set and
 * type, could duplicated. OpenCog does not allow this behaviour.
 * 
 * To fix this, all accesses to the AtomSpace now occur through the
 * AtomSpaceWrapper, which presents fake Handles to PLN and interprets them to a
 * combination of a real \c Handle and a \c VersionHandle. A system of dummy
 * contexts is used to emulate the behaviour of allowing duplicate atoms in the
 * AtomSpace by storing multiple \c TruthValues within a CompositeTruthValue.
 *
 * The AtomSpaceWrapper did exist in the original PLN, but it was more for
 * carrying out normalisation and allowing different AtomSpace backends to be
 * used for efficiency reasons. 
 * 
 * Dummy contexts are represented as directed links. A root dummy context,
 * represented as a Concept Node with name "___PLN___" is used for the outgoing
 * set of dummy contexts in duplicate nodes. For links that are duplicates the
 * outgoing set of their dummy context consists of the dummy context of any
 * duplicate atoms they refer to, or the root dummy context if they refer to the
 * original version of an atom.
 * 
 * <h3> Node example </h3>
 *
 * If a node already exists, then a dummy context is created that links to the
 * root PLN dummy context.
 * 
 * E.g. say we have
 *
 * \code
 *  ConceptNode "x" <0.8, 0.9>
 * \endcode
 *
 * and we want to add a new node with the same name and type, but with TV
 * <0.5,0.5>. To achieve this we create a new dummy context link:
 *
 * \code
 *  dc <- OrderedLink (ConceptNode "___PLN___")
 * \endcode
 * 
 * \c dc is then used as the context for the new TV:
 * 
 * \code
 *  ConceptNode "x" <0.8, 0.9> [ Context dc <0.5, 0.5> ]
 * \endcode
 * 
 * <h3> Link example </h3>
 * 
 * If a link already exists, then the appropriate contexts for each outgoing
 * atom are linked by a new dummy context link (with the appropriate context
 * links of each atom in the outgoing set of the link in the same order as the
 * outgoing set of the existing link). This link's outgoing set/list is prefixed
 * by the root dummy context node if such a context to context link doesn't
 * exist, if it does exist then the context links are searched for the "bottom"
 * link and this is used as the prefix.
 * 
 * E.g. say we have an InheritanceLink composed of two ConceptNodes that both
 * have CompositeTruthValues:
 * 
 * \code
 *  dc_x <- OrderedLink (ConceptNode "__PLN__")
 *  dc_y <- OrderedLink (ConceptNode "__PLN__")
 *  InheritanceLink <0.8, 0.9>
 *      ConceptNode "x" <0.8, 0.9> [ Context dc_x <0.5, 0.5> ]
 *      ConceptNode "y" <0.8, 0.9> [ Context dc_y <0.1, 0.5> ]
 * \endcode
 * 
 * If we want to create another link with a different \c TruthValue, but between
 * the versions of x and y that are under the dummy context (instead of the
 * original TruthValues) then we get:
 * 
 * \code
 *  dc_x_y <- OrderedLink (dc_x dc_y)
 *  InheritanceLink <0.8, 0.9> [ Context dc_x_y <0.3, 0.5> ]
 *      ConceptNode "x" <0.8, 0.9> [ Context dc_x <0.5, 0.5> ]
 *      ConceptNode "y" <0.8, 0.9> [ Context dc_y <0.1, 0.5> ]
 * \endcode
 *
 * Then if we want to create yet another with a different truthvalue, we get:
 *
 * \code
 * dc_x_y_2 <- OrderedLink (dc_x_y dc_x dc_y)
 * InheritanceLink <0.8, 0.9> (Context dc_x_y_2 <0.777, 0.5>)
 *   ConceptNode "x" <0.8, 0.9> (Context dc_x <0.5, 0.5>)
 *   ConceptNode "y" <0.8, 0.9> (Context dc_y <0.1, 0.5>)
 * \endcode
 *
 */
class AtomSpaceWrapper : public iAtomSpaceWrapper
{
    //! How to represent the universe size
    // CONST_SIZE = constant value
    // REAL_SIZE  = actual size of knowledge/experience
    enum USizeMode_t { CONST_SIZE, REAL_SIZE };

{'fraction_non_alphanumeric': 0.09077393965894184, 'fraction_numerical': 0.019414079580236117, 'mean_word_length': 3.5543608124253288, 'pattern_counts': {'":': 0, '<': 88, '<?xml version=': 0, '>': 79, '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': '2480178', 'n_tokens_mistral': 3755, 'n_tokens_neox': 3554, 'n_words': 1556}