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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
|
/* 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
*/
#ifndef TAXONOMYCREATOR_H
#define TAXONOMYCREATOR_H
// taxonomy creator for DL
#include "Taxonomy.h"
#include "SearchableStack.h"
#include "tSignature.h"
class TaxonomyCreator
{
protected: // internal typedefs
/// set of the subsumers
typedef ClassifiableEntry::linkSet SubsumerSet;
/// SS RW iterator
typedef SubsumerSet::iterator ss_iterator;
/// abstract class to represent the known subsumers of a concept
class KnownSubsumers
{
public: // interface
/// empty c'tor
KnownSubsumers ( void ) {}
/// empty d'tor
virtual ~KnownSubsumers ( void ) {}
// iterators
/// begin of the Sure subsumers interval
virtual ss_iterator s_begin ( void ) = 0;
/// end of the Sure subsumers interval
virtual ss_iterator s_end ( void ) = 0;
/// begin of the Possible subsumers interval
virtual ss_iterator p_begin ( void ) = 0;
/// end of the Possible subsumers interval
virtual ss_iterator p_end ( void ) = 0;
// flags
/// whether there are no sure subsumers
bool s_empty ( void ) { return s_begin() == s_end(); }
/// whether there are no possible subsumers
bool p_empty ( void ) { return p_begin() == p_end(); }
/// @return true iff CE is the possible subsumer
virtual bool isPossibleSub ( const ClassifiableEntry* ce ATTR_UNUSED ) const { return true; }
}; // KnownSubsumers
/// class to represent the TS's
class ToldSubsumers: public KnownSubsumers
{
protected: // members
/// two iterators for the TS of a concept
ss_iterator beg, end;
public: // interface
/// c'tor
ToldSubsumers ( ss_iterator b, ss_iterator e ) : beg(b), end(e) {}
/// d'tor
virtual ~ToldSubsumers ( void ) {}
// iterators
/// begin of the Sure subsumers interval
virtual ss_iterator s_begin ( void ) { return beg; }
/// end of the Sure subsumers interval
virtual ss_iterator s_end ( void ) { return end; }
/// begin of the Possible subsumers interval
virtual ss_iterator p_begin ( void ) { return end; }
/// end of the Possible subsumers interval
virtual ss_iterator p_end ( void ) { return end; }
}; // ToldSubsumers
protected: // members
/// Taxonomy to be build
Taxonomy* pTax;
/// aux array to keep synonyms found during TS classification
std::vector<ClassifiableEntry*> Syns;
/// labeller for marking nodes with a label wrt classification
TLabeller valueLabel;
/// pointer to currently classified entry
const ClassifiableEntry* curEntry;
/// number of tested entries
unsigned int nEntries;
/// number of completely-defined entries
unsigned long nCDEntries;
/// session flag: shows the direction of the search
bool upDirection;
/// optimisation flag: if entry is completely defined by it's told subsumers, no other classification required
bool useCompletelyDefined;
/// stack for Taxonomy creation
SearchableStack <ClassifiableEntry*> waitStack;
/// told subsumers corresponding to a given entry
SearchableStack <KnownSubsumers*> ksStack;
/// signature of a \bot-module corresponding to a given entry
SearchableStack <const TSignature*> sigStack;
private: // no copy
/// no copy c'tor
TaxonomyCreator ( const TaxonomyCreator& );
/// no assignment
TaxonomyCreator& operator = ( const TaxonomyCreator& );
protected: // methods
/// initialise aux entry with given concept p
void setCurrentEntry ( const ClassifiableEntry* p )
{
pTax->getCurrent()->clear();
pTax->getCurrent()->setSample(p);
curEntry = p;
}
//-----------------------------------------------------------------
//-- General classification support
//-----------------------------------------------------------------
/// return 1 if current entry is classified as a synonym of already classified one
virtual bool classifySynonym ( void ) { return pTax->processSynonym(); }
/// set up Told Subsumers for the current entry
void setToldSubsumers ( void );
/// add non-redundant candidates for the current entry
void setNonRedundantCandidates ( void );
//-----------------------------------------------------------------
//-- Tunable methods (depending on taxonomy type)
//-----------------------------------------------------------------
/// check if no classification needed (synonym, orphan, unsatisfiable)
virtual bool immediatelyClassified ( void ) { return classifySynonym(); }
/// setup TD phase (ie, identify/set parent candidates)
void setupTopDown ( void )
{
setToldSubsumers();
if ( !needTopDown() )
{
++nCDEntries;
setNonRedundantCandidates();
}
}
/// check if it is possible to skip TD phase
virtual bool needTopDown ( void ) const { return false; }
/// explicitly run TD phase
virtual void runTopDown ( void ) {}
/// check if it is possible to skip BU phase
virtual bool needBottomUp ( void ) const { return false; }
/// explicitly run BU phase
virtual void runBottomUp ( void ) {}
/// actions that to be done BEFORE entry will be classified
virtual void preClassificationActions ( void ) {}
//-----------------------------------------------------------------
//-- General classification methods
//-----------------------------------------------------------------
/// Common pre- and post-action to setup 2-phase algo
void performClassification ( void );
/// fills parents and children of Current using tunable general approach
void generalTwoPhaseClassification ( void );
/// @return true if V is a direct parent of current wrt labels
bool isDirectParent ( TaxonomyVertex* v ) const;
/// add PARENT as a parent if it exists and is direct parent
void addPossibleParent ( TaxonomyVertex* parent )
{
if ( parent && isDirectParent(parent) )
pTax->getCurrent()->addNeighbour ( /*upDirection=*/true, parent );
}
//-----------------------------------------------------------------
//-- DFS-based classification
//-----------------------------------------------------------------
/// @return true if a NODE has been valued during current classification pass
bool isValued ( TaxonomyVertex* node ) const { return node->isValued(valueLabel); }
/// get the subsumption value of a NODE wrt currently classified one
bool getValue ( TaxonomyVertex* node ) const { return node->getValue(); }
/// set the classification value of a NODE to VALUE
bool setValue ( TaxonomyVertex* node, bool value ) const { return node->setValued ( value, valueLabel ); }
/// prepare known subsumers for given entry if necessary
virtual KnownSubsumers* buildKnownSubsumers ( ClassifiableEntry* p )
{ return new ToldSubsumers(p->told_begin(), p->told_end()); }
/// prepare signature for given entry
virtual const TSignature* buildSignature ( ClassifiableEntry* ) { return NULL; }
/// add top entry together with its known subsumers
void addTop ( ClassifiableEntry* p )
{
waitStack.push(p);
ksStack.push(buildKnownSubsumers(p));
sigStack.push(buildSignature(p));
}
/// remove top entry
void removeTop ( void )
{
waitStack.pop();
delete ksStack.top();
ksStack.pop();
sigStack.pop();
}
/// ensure that all TS of the top entry are classified. @return the reason of cycle or NULL.
ClassifiableEntry* prepareTS ( ClassifiableEntry* cur );
/// classify top entry of the stack
void classifyTop ( void )
{
fpp_assert ( !waitStack.empty() ); // sanity check
setCurrentEntry(waitStack.top());
performClassification();
removeTop();
}
/// propagate the TRUE value of the KS subsumption up the hierarchy
void propagateTrueUp ( TaxonomyVertex* node );
/// propagate the FALSE value of the KS subsumption down the hierarchy
void propagateFalseDown ( TaxonomyVertex* node );
/// propagate constant VALUE into an appropriate direction
bool setAndPropagate ( TaxonomyVertex* node, bool value )
{
if ( value )
propagateTrueUp(node);
else
propagateFalseDown(node);
return value;
}
ss_iterator told_begin ( void ) { return ksStack.top()->s_begin(); }
ss_iterator told_end ( void ) { return ksStack.top()->s_end(); }
/// check if it is necessary to log taxonomy action
virtual bool needLogging ( void ) const { return false; }
public: // interface
/// init c'tor
TaxonomyCreator ( Taxonomy* tax )
: pTax(tax)
, curEntry(NULL)
, nEntries(0)
, nCDEntries(0)
, useCompletelyDefined(false)
{}
/// d'tor
virtual ~TaxonomyCreator ( void ) {}
//------------------------------------------------------------------------------
//-- classification interface
//------------------------------------------------------------------------------
/// classify given entry: general method is by DFS
void classifyEntry ( ClassifiableEntry* p )
{
fpp_assert ( waitStack.empty() ); // sanity check
// don't classify artificial concepts
if ( p->isNonClassifiable() )
return;
prepareTS(p);
}
/// clear all labels from Taxonomy vertices
void clearLabels ( void ) { pTax->clearVisited(); valueLabel.newLabel(); }
// flags interface
/// set Completely Defined flag
void setCompletelyDefined ( bool use ) { useCompletelyDefined = use; }
// taxonomy info access
/// print taxonomy info to a stream
virtual void print ( std::ostream& o ) const;
}; // TaxonomyCreator
#endif // TAXONOMYCREATOR_H
|