void DlSatTester :: restore ( unsigned int newTryLevel ) { fpp_assert ( !Stack.empty () ); fpp_assert ( newTryLevel > 0 ); // skip all intermediate restores setCurLevel(newTryLevel); // update split level if ( getCurLevel() < splitRuleLevel ) splitRuleLevel = 0; // restore local bContext = Stack.top(getCurLevel()); restoreBC(); // restore tree CGraph.restore(getCurLevel()); // restore TODO list TODO.restore(getCurLevel()); incStat(nStateRestores); if ( LLM.isWritable(llSRState) ) LL << " sr(" << getCurLevel() << ")"; #ifdef __DEBUG_SAVE_RESTORE writeRoot(llSRState); #endif }
bool DlSatTester :: findConcept ( const CWDArray& lab, BipolarPointer p ) { #ifdef ENABLE_CHECKING fpp_assert ( isCorrect(p) ); // sanity checking // constants are not allowed here fpp_assert ( p != bpTOP ); fpp_assert ( p != bpBOTTOM ); #endif incStat(nLookups); return lab.contains(p); }
modelCacheState modelCacheIan :: merge ( const modelCacheInterface* p ) { fpp_assert ( p != NULL ); // check for nominal clash if ( hasNominalClash(p) ) { curState = csFailed; return getState(); } switch ( p->getCacheType() ) { case mctConst: // adds TOP/BOTTOM curState = mergeStatus ( getState(), p->getState() ); break; case mctSingleton: // adds Singleton { BipolarPointer Singleton = static_cast<const modelCacheSingleton*>(p)->getValue(); mergeSingleton ( getValue(Singleton), isPositive(Singleton) ); break; } case mctIan: mergeIan(static_cast<const modelCacheIan*>(p)); break; default: fpp_unreachable(); } updateNominalStatus(p); return getState(); }
// note that the statistics is given for disjunctions, // so inversed (neg) values are taken into account bool DLDag :: less ( BipolarPointer p1, BipolarPointer p2 ) const { # ifdef ENABLE_CHECKING fpp_assert ( isValid(p1) && isValid(p2) ); # endif // idea: any positive entry should go first if ( preferNonGen ) { if ( isNegative(p1) && isPositive(p2) ) return true; if ( isPositive(p1) && isNegative(p2) ) return false; } const DLVertex& v1 = (*this)[p1]; const DLVertex& v2 = (*this)[p2]; /* // prefer non-cyclical if ( !v1.isInCycle(false) && v2.isInCycle(false) ) return true; if ( !v2.isInCycle(false) && v1.isInCycle(false) ) return false; */ DLVertex::StatType key1 = v1.getStat(iSort); DLVertex::StatType key2 = v2.getStat(iSort); // return "less" wrt sortAscend if ( sortAscend ) return key1 < key2; else return key2 < key1; }
void ReasoningKernel :: Load ( void ) { fpp_assert ( pSLManager != NULL ); pSLManager->prepare(/*input=*/true); Load(*pSLManager); }
void TBox :: addConceptToHeap ( TConcept* pConcept ) { // choose proper tag by concept DagTag tag = pConcept->isPrimitive() ? (pConcept->isSingleton() ? dtPSingleton : dtPConcept): (pConcept->isSingleton() ? dtNSingleton : dtNConcept); // NSingleton is a nominal if ( tag == dtNSingleton && !pConcept->isSynonym() ) static_cast<TIndividual*>(pConcept)->setNominal(); // new concept's addition DLVertex* ver = new DLVertex(tag); ver->setConcept(pConcept); pConcept->pName = DLHeap.directAdd(ver); BipolarPointer desc = bpTOP; // translate body of a concept if ( pConcept->Description != NULL ) // complex concept desc = tree2dag(pConcept->Description); else // only primivive concepts here fpp_assert ( pConcept->isPrimitive() ); // update concept's entry pConcept->pBody = desc; ver->setChild(desc); if ( !pConcept->isSynonym() && pConcept->index() == 0 ) setConceptIndex(pConcept); }
void TBox :: dumpAllRoles ( dumpInterface* dump ) const { RoleMaster::const_iterator p; for ( p = ORM.begin(); p != ORM.end(); ++p ) if ( isRelevant(*p) ) { fpp_assert ( !(*p)->isSynonym() ); dumpRole ( dump, *p ); } for ( p = DRM.begin(); p != DRM.end(); ++p ) if ( isRelevant(*p) ) { fpp_assert ( !(*p)->isSynonym() ); dumpRole ( dump, *p ); } }
void TBox :: dumpExpression ( dumpInterface* dump, BipolarPointer p ) const { fpp_assert ( isValid(p) ); if ( p == bpTOP ) return dump->dumpTop(); if ( p == bpBOTTOM ) return dump->dumpBottom(); // checks inversion if ( isNegative(p) ) { dump->startOp (diNot); dumpExpression ( dump, inverse(p) ); return dump->finishOp (diNot); } const DLVertex& v = DLHeap[p]; switch ( v.Type() ) { case dtTop: return dump->dumpTop(); case dtName: return dump->dumpConcept(static_cast<const TConcept*>(v.getConcept())); case dtAnd: dump->startOp (diAnd); for ( DLVertex::const_iterator q = v.begin(); q != v.end(); ++q ) { if ( q != v.begin() ) dump->contOp (diAnd); dumpExpression ( dump, *q ); } dump->finishOp (diAnd); return; case dtForall: dump->startOp (diForall); dump->dumpRole (v.getRole()); dump->contOp(diForall); dumpExpression ( dump, v.getC() ); dump->finishOp (diForall); return; case dtLE: dump->startOp ( diLE, v.getNumberLE() ); dump->dumpRole (v.getRole()); dump->contOp(diLE); dumpExpression ( dump, v.getC() ); dump->finishOp (diLE); return; default: std::cerr << "Error dumping vertex of type " << v.getTagName() << "(" << v.Type () << ")"; fpp_unreachable(); return; // invalid value } }
void ReasoningKernel :: Save ( void ) { fpp_assert ( pSLManager != NULL ); pSLManager->prepare(/*input=*/false); Save(*pSLManager); }
void TBox :: setRelevant ( BipolarPointer p ) { fpp_assert ( isValid(p) ); if ( p == bpTOP || p == bpBOTTOM ) return; const DLVertex& v = DLHeap[p]; bool pos = isPositive(p); ++nRelevantBCalls; collectLogicFeature(v,pos); switch ( v.Type() ) { case dtDataType: // types and values are not relevant case dtDataValue: case dtDataExpr: case dtNN: // not appear in any expression => not relevant break; case dtPConcept: // negated primitive entries -- does nothing case dtPSingleton: // if ( !pos ) // break; // fall through case dtNConcept: // named concepts case dtNSingleton: setRelevant(const_cast<TConcept*>(static_cast<const TConcept*>(v.getConcept()))); break; case dtForall: case dtLE: setRelevant(const_cast<TRole*>(v.getRole())); setRelevant (v.getC()); break; case dtProj: // no need to set (inverse) roles as it doesn't really matter case dtChoose: setRelevant(v.getC()); break; case dtIrr: setRelevant(const_cast<TRole*>(v.getRole())); break; case dtAnd: for ( DLVertex::const_iterator q = v.begin(); q != v.end(); ++q ) setRelevant(*q); break; default: std::cerr << "Error setting relevant vertex of type " << v.getTagName() << "(" << v.Type () << ")"; fpp_unreachable(); } }
BipolarPointer TBox :: tree2dag ( const DLTree* t ) { if ( t == NULL ) return bpINVALID; // invalid value const TLexeme& cur = t->Element(); BipolarPointer ret = bpINVALID; switch ( cur.getToken() ) { case BOTTOM: // it is just !top ret = bpBOTTOM; break; case TOP: // the 1st node ret = bpTOP; break; case DATAEXPR: // data-related expression ret = addDataExprToHeap ( static_cast<TDataEntry*>(cur.getNE()) ); break; case CNAME: // concept name ret = concept2dag(toConcept(cur.getNE())); break; case INAME: // individual name { ++nNominalReferences; // definitely a nominal TIndividual* ind = toIndividual(cur.getNE()); ind->setNominal(); ret = concept2dag(ind); break; } case NOT: ret = inverse ( tree2dag ( t->Left() ) ); break; case AND: ret = and2dag(t); break; case FORALL: ret = forall2dag ( resolveRole(t->Left()), tree2dag(t->Right()) ); break; case SELF: ret = reflexive2dag(resolveRole(t->Left())); break; case LE: ret = atmost2dag ( cur.getData(), resolveRole(t->Left()), tree2dag(t->Right()) ); break; case PROJFROM: // note: no PROJINTO as already unified ret = DLHeap.directAdd ( new DLVertex ( resolveRole(t->Left()), tree2dag(t->Right()->Right()), resolveRole(t->Right()->Left()) ) ); break; default: fpp_assert ( isSNF(t) ); // safety check fpp_unreachable(); // extra safety check ;) } return ret; }
void DLDag :: readConfig ( const ifOptionSet* Options ) { fpp_assert ( Options != NULL ); // safety check orSortSat = Options->getText ( "orSortSat" ).c_str(); orSortSub = Options->getText ( "orSortSub" ).c_str(); if ( !isCorrectOption(orSortSat) || !isCorrectOption(orSortSub) ) throw EFaCTPlusPlus ( "DAG: wrong OR sorting options" ); }
addConceptResult DlSatTester :: checkAddedConcept ( const CWDArray& lab, BipolarPointer p, const DepSet& dep ) { #ifdef ENABLE_CHECKING fpp_assert ( isCorrect(p) ); // sanity checking // constants are not allowed here fpp_assert ( p != bpTOP ); fpp_assert ( p != bpBOTTOM ); #endif if ( findConcept ( lab, p ) ) return acrExist; if ( findConceptClash ( lab, inverse(p), dep ) ) return acrClash; // we are able to insert a concept return acrDone; }
/// fills in variable index void fillVarIndex ( const V2CMap& query ) { size_t n = 0; Var2I.clear(); I2Var.clear(); for ( V2CMap::const_iterator p = query.begin(), p_end = query.end(); p != p_end; ++p ) if ( Var2I.count(p->first) == 0 ) // new name { Var2I[p->first] = n++; I2Var.push_back(p->first); } fpp_assert ( I2Var.size() == n ); }
bool DlSatTester :: correctCachedEntry ( DlCompletionTree* n ) { fpp_assert ( n->isCached() ); // safety check // FIXME!! check if it is possible to leave node cached in more efficient way modelCacheState status = tryCacheNode(n); // uncheck cached node status and add all elements in TODO list if ( status == csFailed ) redoNodeLabel ( n, "uc" ); return usageByState(status); }
modelCacheState modelCacheIan :: isMergableSingleton ( unsigned int Singleton, bool pos ) const { fpp_assert ( Singleton != 0 ); // deterministic clash if ( getDConcepts(!pos).contains(Singleton) ) return csInvalid; // non-det clash else if ( getNConcepts(!pos).contains(Singleton) ) return csFailed; return csValid; }
/// @return true iff given data node contains data contradiction bool DlSatTester :: hasDataClash ( const DlCompletionTree* Node ) { fpp_assert ( Node && Node->isDataNode() ); // safety check DTReasoner.clear(); // data node may contain only "simple" concepts in there for ( DlCompletionTree::const_label_iterator p = Node->beginl_sc(), p_end = Node->endl_sc(); p != p_end; ++p ) if ( DTReasoner.addDataEntry ( p->bp(), p->getDep() ) ) // clash found return true; return false; }
bool DlSatTester :: findConceptClash ( const CWDArray& lab, BipolarPointer p, const DepSet& dep ) { #ifdef ENABLE_CHECKING fpp_assert ( isCorrect(p) ); // sanity checking // constants are not allowed here fpp_assert ( p != bpTOP ); fpp_assert ( p != bpBOTTOM ); #endif incStat(nLookups); for ( const_label_iterator i = lab.begin(), i_end = lab.end(); i < i_end; ++i ) if ( i->bp() == p ) { // create clashSet clashSet = i->getDep(); clashSet.add(dep); return true; } // we are able to insert a concept return false; }
/// propagate the FALSE value of the KS subsumption down the hierarchy void TaxonomyCreator :: propagateFalseDown ( TaxonomyVertex* node ) { // if taxonomy class already checked -- do nothing if ( isValued(node) ) { fpp_assert ( getValue(node) == false ); return; } // overwise -- value it... setValue ( node, false ); // ... and value all children for ( TaxonomyVertex::iterator p = node->begin(/*upDirection=*/false), p_end = node->end(/*upDirection=*/false); p != p_end; ++p ) propagateFalseDown(*p); }
/// set defaults of OR orderings void DLDag :: setOrderDefaults ( const char* defSat, const char* defSub ) { // defaults should be correct fpp_assert ( isCorrectOption(defSat) && isCorrectOption(defSub) ); if ( LLM.isWritable(llAlways) ) LL << "orSortSat: initial=" << orSortSat << ", default=" << defSat; if ( orSortSat[0] == '0' ) orSortSat = defSat; if ( LLM.isWritable(llAlways) ) LL << ", used=" << orSortSat << "\n" << "orSortSub: initial=" << orSortSub << ", default=" << defSub; if ( orSortSub[0] == '0' ) orSortSub = defSub; if ( LLM.isWritable(llAlways) ) LL << ", used=" << orSortSub << "\n"; }
/// create inverse of role R DLTree* createInverse ( DLTree* R ) { fpp_assert ( R != NULL ); // sanity check switch ( R->Element().getToken() ) { case INV: // R-- = R { DLTree* p = clone(R->Left()); deleteTree(R); return p; } case RNAME: // object role name if ( unlikely(isTopRole(R)) || unlikely(isBotRole(R)) ) return R; // top/bottom roles are inverses of themselves return new DLTree ( TLexeme(INV), R ); default: // no other elements can have inverses fpp_unreachable(); } }
void TsScanner :: FillNameBuffer ( char c ) { unsigned int i = 0; const char stop = c; while ( i <= MaxIDLength && ( c = NextChar() ) != stop ) LexBuff[i++] = c; LexBuff[i] = 0; if ( i > MaxIDLength ) { fpp_assert ( i == MaxIDLength + 1 ); std::cerr << "Identifier was restricted to " << LexBuff << std::endl; do { c = NextChar(); } while ( c != stop ); } }
bool DlSatTester :: checkSatisfiability ( void ) { unsigned int loop = 0; for (;;) { if ( curNode == NULL ) { if ( TODO.empty() ) // no applicable rules { // do run-once things if ( performAfterReasoning() ) // clash found if ( tunedRestore() ) // no more alternatives return false; // if nothing added -- that's it if ( TODO.empty() ) return true; } const ToDoEntry* curTDE = TODO.getNextEntry (); fpp_assert ( curTDE != NULL ); // setup current context curNode = curTDE->Node; curConcept = curNode->label().getConcept(curTDE->offset); } if ( ++loop == 5000 ) { loop = 0; if ( tBox.isCancelled() ) return false; if ( unlikely(getSatTimeout()) && 1000*(float)testTimer >= getSatTimeout() ) throw EFPPTimeout(); } // here curNode/curConcept are set if ( commonTactic() ) // clash found { if ( tunedRestore() ) // the concept is unsatisfiable return false; } else curNode = NULL; } }
// Word must be in a CAPITAL LETTERS void TsScanner :: FillBuffer ( char c ) { unsigned int i = 0; LexBuff [0] = c; while ( i < MaxIDLength && isLegalIdChar ( c = NextChar() ) ) LexBuff[++i] = c; LexBuff[++i] = 0; if ( i > MaxIDLength ) { fpp_assert ( i == MaxIDLength + 1 ); std::cerr << "Identifier was restricted to " << LexBuff << "\n"; do { c = NextChar(); } while ( isLegalIdChar(c) ); } // OK or read the end of ID PutBack ( c ); }
/// create negation of given formula DLTree* createSNFNot ( DLTree* C ) { fpp_assert ( C != NULL ); // sanity check if ( C->Element() == BOTTOM ) { // \not F = T deleteTree(C); return createTop(); } if ( C->Element() == TOP ) { // \not T = F deleteTree(C); return createBottom(); } if ( C->Element () == NOT ) { // \not\not C = C DLTree* p = clone(C->Left()); deleteTree(C); return p; } // general case return new DLTree ( TLexeme(NOT), C ); }
/// add a new iteralbe to a vec void add ( Iterable<Elem>* It ) { Base.push_back(It); last++; fpp_assert ( last == int(Base.size()-1) ); }