Skip to content

Commit

Permalink
Merge 'LGDict' of github.com:williampma/opencog
Browse files Browse the repository at this point in the history
Conflicts:
	opencog/nlp/CMakeLists.txt
  • Loading branch information
linas committed Dec 22, 2014
2 parents f670c52 + 68ae225 commit 065497f
Show file tree
Hide file tree
Showing 14 changed files with 467 additions and 178 deletions.
1 change: 1 addition & 0 deletions lib/opencog.conf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ MODULES = opencog/server/libbuiltinreqs.so,
opencog/shell/libscheme-shell.so,
opencog/shell/libpy-shell.so,
opencog/nlp/types/libnlp-types.so,
opencog/nlp/sureal/libLGDictModule.so,
opencog/learning/pln/libPLNTypes.so,
opencog/dynamics/attention/libattention-types.so,
opencog/dynamics/attention/libattention.so,
Expand Down
4 changes: 4 additions & 0 deletions opencog/nlp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ IF (HAVE_VITERBI)
# Currently does not build, due to changes in SchemeEval API.
# ADD_SUBDIRECTORY (viterbi)
ENDIF (HAVE_VITERBI)

IF (HAVE_LINK_GRAMMAR)
ADD_SUBDIRECTORY (sureal)
ENDIF (HAVE_LINK_GRAMMAR)
29 changes: 29 additions & 0 deletions opencog/nlp/sureal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

INCLUDE_DIRECTORIES (
${LINK_GRAMMAR_INCLUDE_DIRS} # for LinkGrammar dictionary
${CMAKE_BINARY_DIR} # for the NLP atom types
)

ADD_LIBRARY (sureal SHARED
LGDictReader
)

ADD_DEPENDENCIES (sureal
nlp_atom_types
)

IF (HAVE_GUILE)
TARGET_LINK_LIBRARIES (sureal smob ${LINK_GRAMMAR_LIBRARY})
ENDIF (HAVE_GUILE)


ADD_LIBRARY (LGDictModule SHARED
LGDictModule
)
TARGET_LINK_LIBRARIES (LGDictModule sureal server)

IF (WIN32)
INSTALL (TARGETS sureal DESTINATION "lib${LIB_DIR_SUFFIX}/opencog")
ELSEIF (CYGWIN)
INSTALL (TARGETS sureal DESTINATION "lib${LIB_DIR_SUFFIX}/opencog")
ENDIF ()
92 changes: 92 additions & 0 deletions opencog/nlp/sureal/LGDictModule.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* LGDictModule.cc
*
* Copyright (C) 2014 OpenCog Foundation
*
* Author: William Ma <https://github.com/williampma>
*
* 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 <opencog/atomspace/AtomSpace.h>
#include <opencog/guile/SchemePrimitive.h>

#include <opencog/nlp/types/atom_types.h>

#include "LGDictModule.h"
#include "LGDictReader.h"

using namespace opencog;

DECLARE_MODULE(LGDictModule);

/**
* The constructor for LGDictModule.
*
* @param cs the OpenCog server
*/
LGDictModule::LGDictModule(CogServer& cs) : Module(cs)
{

}

/**
* The destructor for LGDictModule.
*/
LGDictModule::~LGDictModule()
{
dictionary_delete(m_pDictionary);
}

/**
* The required implementation for the pure virtual init method.
*/
void LGDictModule::init(void)
{
m_pDictionary = dictionary_create_default_lang();

#ifdef HAVE_GUILE
define_scheme_primitive("lg-get-dict-entry", &LGDictModule::do_lg_get_dict_entry, this);
#endif
}

/**
* Implementation of the "lg-get-dict-entry" scheme primitive.
*
* The corresponding implementation for the "lg-get-dict-entry" primitive,
* which accepts a WordNode as input and output the LG dictionary atom.
*
* @param h the input WordNode containing the word string
* @return the LG dictionary atom
*/
Handle LGDictModule::do_lg_get_dict_entry(Handle h)
{
#ifdef HAVE_GUILE
AtomSpace* pAS = SchemeSmob::ss_get_env_as("lg-get-dict-entry");

if (pAS->isNode(h) && pAS->getType(h) == WORD_NODE)
{
LGDictReader reader(m_pDictionary, pAS);

return reader.getAtom(pAS->getName(h));
}

return Handle::UNDEFINED;

#else
return Handle::UNDEFINED;
#endif
}
56 changes: 56 additions & 0 deletions opencog/nlp/sureal/LGDictModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* LGDictMoudle.h
*
* Copyright (C) 2014 OpenCog Foundation
*
* Author: William Ma <https://github.com/williampma>
*
* 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 _OPENCOG_LG_DICT_MODULE_H
#define _OPENCOG_LG_DICT_MODULE_H

#include <link-grammar/dict-api.h>

#include <opencog/server/Module.h>
#include <opencog/atomspace/Handle.h>

namespace opencog {

/**
* An OpenCog module for reading LG dictionary.
*
* This module creates the necessary scheme bindings for accessing the
* Link Grammar dictionary.
*/
class LGDictModule : public Module
{
private:
Handle do_lg_get_dict_entry(Handle);

Dictionary m_pDictionary;

public:
LGDictModule(CogServer&);
virtual ~LGDictModule();
const char * id(void);
virtual void init(void);
};

}

#endif // _OPENCOG_LG_DICT_MODULE_H
165 changes: 165 additions & 0 deletions opencog/nlp/sureal/LGDictReader.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* LGDictReader.cc
*
* Copyright (C) 2014 OpenCog Foundation
*
* Author: William Ma <https://github.com/williampma>
*
* 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 "LGDictReader.h"

using namespace opencog;

/**
* Constructor of the LGDictReader class.
*
* @param pDict the Dictionary to read from
* @param pAS the AtomSpace where atoms will be created
*/
LGDictReader::LGDictReader(Dictionary pDict, AtomSpace* pAS)
: m_pDictionary(pDict), m_pScmEval(new SchemeEval(pAS))
{

}

/**
* Destructor of the LGDictReader class.
*/
LGDictReader::~LGDictReader()
{
delete m_pScmEval;
}

/**
* Method to construct LG dictionary atom.
*
* Given a word string, construct the corresponding atom representing
* the Link Grammar's dictionary entry.
*
* The returned expression is in the form of an opencog-style
* prefix-notation boolean expression. Note that it is not in any
* particular kind of normal form. In particular, some AND nodes
* may have only one child: these can be removed.
*
* Note that the order of the connectors is important: while linking,
* these must be satisfied in left-to-right (nested!?) order.
*
* Optional clauses are indicated by OR-ing with null, where "null"
* is a CONNECTOR Node with string-value "0". Optional clauses are
* not necessarily in any sort of normal form; the null connector can
* appear anywhere.
*
* @param word the input word string
* @return the handle to the newly created atom
*/
Handle LGDictReader::getAtom(const std::string& word)
{
// See if we know about this word, or not.
Dict_node* dn_head = dictionary_lookup_list(m_pDictionary, word.c_str());

if (!dn_head)
return Handle::UNDEFINED;

std::string set = "(SetLink\n";

for (Dict_node* dn = dn_head; dn; dn = dn->right)
{
Exp* exp = dn->exp;

print_expression(exp);

// First atom at the front of the outgoing set is the word itself.
// Second atom is the first disjuct that must be fulfilled.
std::string word_cset = " (LgWordCset (WordNode \"";
word_cset += word;
word_cset += "\")\n";
word_cset += lg_exp_to_scm_string(exp);
word_cset += ")\n";

set += word_cset;
}

set += ")\n";

free_lookup_list(m_pDictionary, dn_head);

return m_pScmEval->eval_h(set);
}

/**
* Helper method for converting LG expression trees to scheme code.
*
* @param exp the input expression trees
* @return the scheme output
*/
std::string LGDictReader::lg_exp_to_scm_string(Exp* exp)
{
if (CONNECTOR_type == exp->type)
{
std::stringstream ss;
ss << "(LgConnector (LgConnectorNode ";
ss << "\"" << exp->u.string << "\")";
ss << "(LgConnDirNode \"" << exp->dir << "\")";

if (exp->multi)
ss << "(LgConnMultiNode \"@\")";

ss << ")\n";

return ss.str();
}

// Whenever a null appears in an OR-list, it means the
// entire OR-list is optional. A null can never appear
// in an AND-list.
E_list* el = exp->u.l;

if (NULL == el)
return "(LgConnector (LgConnectorNode \"0\"))\n";

// The C data structure that link-grammar uses for connector
// expressions is totally insane, as witnessed by the loop below.
// Anyway: operators are infixed, i.e. are always binary,
// with exp->u.l->e being the left hand side, and
// exp->u.l->next->e being the right hand side.
// This means that exp->u.l->next->next is always null.
std::string alist;

if (AND_type == exp->type)
alist = "(LgAnd ";

if (OR_type == exp->type)
alist = "(LgOr ";

alist += lg_exp_to_scm_string(el->e);
el = el->next;

while (el && exp->type == el->e->type)
{
el = el->e->u.l;
alist += lg_exp_to_scm_string(el->e);
el = el->next;
}

if (el)
alist += lg_exp_to_scm_string(el->e);

alist.append (")\n");

return alist;
}
Loading

0 comments on commit 065497f

Please sign in to comment.