1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
/* This file is part of the FaCT++ DL reasoner
Copyright (C) 2003-2015 Dmitry Tsarkov and The University of Manchester
Copyright (C) 2015-2016 Dmitry Tsarkov
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*******************************************************\
|* Implementation of taxonomy building for the FaCT++ *|
\*******************************************************/
#include "Taxonomy.h"
#include "logging.h"
/********************************************************\
|* Implementation of class Taxonomy *|
\********************************************************/
Taxonomy :: ~Taxonomy ( void )
{
delete Current;
for ( TaxVertexVec::iterator p = Graph.begin(), p_end = Graph.end(); p < p_end; ++p )
delete *p;
}
void Taxonomy :: print ( std::ostream& o ) const
{
o << "All entries are in format:\n\"entry\" {n: parent_1 ... parent_n} {m: child_1 child_m}\n\n";
TVSet sorted(Graph.begin()+2, Graph.end());
getTopVertex()->print(o);
for ( TVSet::const_iterator p = sorted.begin(), p_end = sorted.end(); p != p_end; ++p )
if ( likely((*p)->isInUse()) )
(*p)->print(o);
getBottomVertex()->print(o);
}
//---------------------------------------------------
// classification part
//---------------------------------------------------
void
Taxonomy :: addCurrentToSynonym ( TaxonomyVertex* syn )
{
const ClassifiableEntry* curEntry = Current->getPrimer();
if ( queryMode() ) // no need to insert; just mark SYN as a host to curEntry
syn->setVertexAsHost(curEntry);
else
{
syn->addSynonym(curEntry);
if ( LLM.isWritable(llTaxInsert) )
LL << "\nTAX:set " << curEntry->getName() << " equal " << syn->getPrimer()->getName();
}
}
/// insert current node either directly or as a synonym
void
Taxonomy :: finishCurrentNode ( void )
{
TaxonomyVertex* syn = Current->getSynonymNode();
if ( syn )
addCurrentToSynonym(syn);
else if ( !queryMode() ) // insert node into taxonomy
{
Current->incorporate();
Graph.push_back(Current);
// we used the Current so need to create a new one
Current = new TaxonomyVertex();
}
}
bool Taxonomy :: processSynonym ( void )
{
const ClassifiableEntry* curEntry = Current->getPrimer();
const ClassifiableEntry* syn = resolveSynonym(curEntry);
if ( syn == curEntry )
return false; // not a synonym
// update synonym vertex:
fpp_assert ( syn->getTaxVertex() != NULL );
addCurrentToSynonym(syn->getTaxVertex());
return true;
}
/// call this method after taxonomy is built
void
Taxonomy :: finalise ( void )
{ // create links from leaf concepts to bottom
const bool upDirection = false;
for ( TaxVertexVec::iterator p = Graph.begin()+1, p_end = Graph.end(); p < p_end; ++p )
if ( likely((*p)->isInUse()) && (*p)->noNeighbours(upDirection) )
{
(*p)->addNeighbour ( upDirection, getBottomVertex() );
getBottomVertex()->addNeighbour ( !upDirection, *p );
}
willInsertIntoTaxonomy = false; // after finalisation one shouldn't add new entries to taxonomy
}
/// unlink the bottom from the taxonomy
void
Taxonomy :: deFinalise ( void )
{
const bool upDirection = true;
TaxonomyVertex* bot = getBottomVertex();
for ( TaxonomyVertex::iterator p = bot->begin(upDirection), p_end = bot->end(upDirection); p != p_end; ++p )
(*p)->removeLink ( !upDirection, bot );
bot->clearLinks(upDirection);
willInsertIntoTaxonomy = true; // it's possible again to add entries
}
|