/*
* fetch-cats.cc
*
* Fetch the entire contents of the dict; needed for generation.
*
* Copyright (c) 2022 Linas Vepstas <linasvepstas@gmail.com>
*/
#ifdef HAVE_ATOMESE
extern "C" {
#include "../link-includes.h" // For Dictionary
#include "../dict-common/dict-common.h" // for Dictionary_s
#include "lookup-atomese.h"
};
#include "local-as.h"
#include <opencog/lg/types/atom_types.h>
using namespace opencog;
// This works only with sections; it won't handle pairs or MST things.
void as_add_categories(Dictionary dict)
{
Local* local = (Local*) (dict->as_server);
// Get all sections.
if (local->stnp)
{
local->stnp->fetch_all_atoms_of_type(SECTION);
local->stnp->barrier();
}
// Assume one category per word and word-class.
// (i.e. that all words will have sections)
size_t nclasses = local->asp->get_num_atoms_of_type(WORD_CLASS_NODE);
size_t nwords = local->asp->get_num_atoms_of_type(WORD_NODE);
size_t ncat = nclasses + nwords;
dict->num_categories = ncat;
dict->num_categories_alloced = ncat + 2;
dict->category = (Category*) malloc(
dict->num_categories_alloced * sizeof(*dict->category));
// First, loop over all word-classes
HandleSeq allcl;
local->asp->get_handles_by_type(allcl, WORD_CLASS_NODE);
size_t j = 1;
for (size_t i=0; i<allcl.size(); i++)
{
const Handle& wcl = allcl[i];
// Some word-classes might not be in any sections.
dict->category[j].exp = make_sect_exprs(dict, wcl);
if (nullptr == dict->category[j].exp)
continue;
// Crufty dicts can contain empty cats.
size_t nwo = wcl->getIncomingSetSizeByType(MEMBER_LINK);
if (0 == nwo)
continue;
dict->category[j].name =
string_set_add(wcl->get_name().c_str(), dict->string_set);
// Copy the words into the cateory.
dict->category[j].word = (const char**)
malloc(nwo * sizeof(*dict->category[0].word));
nwo = 0;
for (const Handle& memb : wcl->getIncomingSetByType(MEMBER_LINK))
{
const Handle& wrd = memb->getOutgoingAtom(0);
if (WORD_NODE != wrd->get_type()) continue;
dict->category[j].word[nwo] =
string_set_add(wrd->get_name().c_str(), dict->string_set);
nwo++;
}
dict->category[j].num_words = nwo;
j++;
}
// Add individual words.
HandleSeq allwo;
local->asp->get_handles_by_type(allwo, WORD_NODE);
for (size_t i=0; i<allwo.size(); i++)
{
dict->category[j].exp = make_sect_exprs(dict, allwo[i]);
if (nullptr == dict->category[j].exp)
continue;
dict->category[j].name =
string_set_add(allwo[i]->get_name().c_str(), dict->string_set);
dict->category[j].num_words = 1;
dict->category[j].word =
(const char**) malloc(sizeof(*dict->category[0].word));
dict->category[j].word[0] = dict->category[j].name;
j++;
}
j--; // First j was empty (on purpose)
/* Free excess memory, if any */
dict->num_categories_alloced = j + 2;
dict->category = (Category*) realloc(dict->category,
dict->num_categories_alloced * sizeof(*dict->category));
/* Set the termination entry. */
dict->num_categories = j;
dict->category[j + 1].num_words = 0;
}
#endif // HAVE_ATOMESE