modelCacheState DlSatTester :: reportNodeCached ( DlCompletionTree* node ) { doCacheNode(node); enum modelCacheState status = newNodeCache.getState(); switch ( status ) { case csValid: incStat(nCachedSat); if ( LLM.isWritable(llGTA) ) LL << " cached(" << node->getId() << ")"; break; case csInvalid: incStat(nCachedUnsat); break; case csFailed: case csUnknown: incStat(nCacheFailed); if ( LLM.isWritable(llGTA) ) LL << " cf(c)"; status = csFailed; break; default: fpp_unreachable(); } return status; }
static void SaveSingleCache ( SaveLoadManager& m, BipolarPointer bp, const modelCacheInterface* cache ) { if ( cache == NULL ) return; m.saveSInt(bp); m.saveUInt(cache->getCacheType()); switch ( cache->getCacheType() ) { case modelCacheInterface::mctConst: m.saveUInt(cache->getState() == csValid); break; case modelCacheInterface::mctSingleton: m.saveSInt(dynamic_cast<const modelCacheSingleton*>(cache)->getValue()); break; case modelCacheInterface::mctIan: dynamic_cast<const modelCacheIan*>(cache)->Save(m); break; default: fpp_unreachable(); } m.o() << "\n"; }
bool DlSatTester :: addToDoEntry ( DlCompletionTree* node, const ConceptWDep& C, const char* reason ) { if ( C == bpTOP ) // simplest things first return false; if ( C == bpBOTTOM ) { setClashSet(C.getDep()); if ( LLM.isWritable(llGTA) ) logClash ( node, C ); return true; } const DLVertex& v = DLHeap[C]; DagTag tag = v.Type(); // try to add a concept to a node label switch ( tryAddConcept ( node->label().getLabel(tag), C.bp(), C.getDep() ) ) { case acrClash: // clash -- return if ( LLM.isWritable(llGTA) ) logClash ( node, C ); return true; case acrExist: // already exists -- nothing new return false; case acrDone: // try was done return insertToDoEntry ( node, C, tag, reason ); default: // safety check fpp_unreachable(); } }
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 } }
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(); }
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; }
/// init c'tor Iterable ( const ElemVec& Init ) : Elems(Init) , pBeg(Elems.begin()) , pEnd(Elems.end()) , pCur(pBeg) { if ( Elems.empty() ) // no empty vecs allowed here fpp_unreachable(); std::cout << " " << Init.size(); }
// dump given concept expression void dumpCExpression ( dumpInterface* dump, const DLTree* C ) { if ( C == nullptr ) return; Token t = C->Element().getToken(); diOp tag; switch (t) { case TOP: return dump->dumpTop(); case BOTTOM: return dump->dumpBottom(); case CNAME: case INAME: return dump->dumpConcept(static_cast<TConcept*>(C->Element().getNE())); case NOT: dump->startOp(diNot); dumpCExpression ( dump, C->Left() ); return dump->finishOp(diNot); case AND: case OR: tag = t == AND ? diAnd : diOr; dump->startOp(tag); dumpCExpression ( dump, C->Left() ); dump->contOp(tag); dumpCExpression ( dump, C->Right() ); return dump->finishOp(tag); case EXISTS: case FORALL: case LE: case GE: tag = t == EXISTS ? diExists : t == FORALL ? diForall : t == GE ? diGE : diLE; if ( t == GE || t == LE ) dump->startOp ( tag, C->Element().getData() ); else dump->startOp(tag); dumpRExpression ( dump, C->Left() ); dump->contOp(tag); dumpCExpression ( dump, C->Right() ); return dump->finishOp(tag); default: fpp_unreachable(); } }
/// 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(); } }
// dump given role expression void dumpRExpression ( dumpInterface* dump, const DLTree* R ) { if ( R == nullptr ) return; switch ( R->Element().getToken() ) { case RNAME: case DNAME: return dump->dumpRole(static_cast<TRole*>(R->Element().getNE())); case NOT: case INV: dump->startOp(diInv); dumpRExpression ( dump, R->Left() ); return dump->finishOp(diInv); default: fpp_unreachable(); } }
static const modelCacheInterface* LoadSingleCache ( SaveLoadManager& m ) { modelCacheState state = (modelCacheState)m.loadUInt(); switch ( state ) { case modelCacheInterface::mctConst: return new modelCacheConst ( m.loadUInt() != 0 ); case modelCacheInterface::mctSingleton: return new modelCacheSingleton(m.loadSInt()); case modelCacheInterface::mctIan: { bool hasNominals = bool(m.loadUInt()); unsigned int nC = m.loadUInt(); unsigned int nR = m.loadUInt(); modelCacheIan* cache = new modelCacheIan ( hasNominals, nC, nR ); cache->Load(m); return cache; } default: fpp_unreachable(); } }
void modelCacheIan :: processConcept ( const DLVertex& cur, bool pos, bool det ) { switch ( cur.Type() ) { case dtTop: // sanity checks case dtDataType: // data entries can not be cached case dtDataValue: case dtDataExpr: fpp_unreachable(); break; case dtNConcept: // add concepts to Concepts case dtPConcept: case dtNSingleton: case dtPSingleton: (det ? getDConcepts(pos) : getNConcepts(pos)).insert(static_cast<const ClassifiableEntry*>(cur.getConcept())->index()); break; case dtIrr: // for \neg \ER.Self: add R to AR-set case dtForall: // add AR.C roles to forallRoles case dtLE: // for <= n R: add R to forallRoles if ( unlikely ( cur.getRole()->isTop() ) ) // force clash to every other edge (pos ? forallRoles : existsRoles).completeSet(); else if ( pos ) // no need to deal with existentials here: they would be created through edges { if ( cur.getRole()->isSimple() ) forallRoles.insert(cur.getRole()->index()); else processAutomaton(cur); } break; default: // all other -- nothing to do break; } }
void DLVertex :: Print ( std::ostream& o ) const { o << "[d(" << getDepth(true) << "/" << getDepth(false) << "),s(" << getSize(true) << "/" << getSize(false) << "),b(" << getBranch(true) << "/" << getBranch(false) << "),g(" << getGener(true) << "/" << getGener(false) << "),f(" << getFreq(true) << "/" << getFreq(false) << ")] "; o << getTagName(); switch ( Type() ) { case dtAnd: // nothing to do (except for printing operands) case dtSplitConcept: break; case dtTop: // nothing to do case dtNN: return; case dtDataExpr: o << ' ' << *static_cast<const TDataEntry*>(getConcept())->getFacet(); return; case dtDataValue: // named entry -- just like concept names case dtDataType: case dtPConcept: case dtNConcept: case dtPSingleton: case dtNSingleton: o << '(' << getConcept()->getName() << ") " << (isNNameTag(Type()) ? "=" : "[=") << ' ' << getC(); return; case dtLE: o << ' ' << getNumberLE() << ' ' << getRole()->getName() << ' ' << getC(); return; case dtForall: o << ' ' << getRole()->getName() << '{' << getState() << '}' << ' ' << getC(); return; case dtIrr: o << ' ' << getRole()->getName(); return; case dtProj: o << ' ' << getRole()->getName() << ", " << getC() << " => " << getProjRole()->getName(); return; case dtChoose: o << ' ' << getC(); return; default: std::cerr << "Error printing vertex of type " << getTagName() << "(" << Type() << ")"; fpp_unreachable(); } // print operands of the concept constructor for ( const_iterator q = begin(); q != end(); ++q ) o << ' ' << *q; }
void DLVertex :: Load ( SaveLoadManager& m ) { // now OP is already loaded switch ( Type() ) { case dtBad: case dtTop: // can't be S/L default: fpp_unreachable(); break; case dtAnd: { unsigned int size = m.loadUInt(); for ( unsigned int j = 0; j < size; ++j ) Child.push_back(m.loadSInt()); break; } case dtLE: Role = static_cast<const TRole*>(m.loadEntry()); setChild(m.loadSInt()); n = m.loadUInt(); break; case dtForall: Role = static_cast<const TRole*>(m.loadEntry()); setChild(m.loadSInt()); n = m.loadUInt(); break; case dtIrr: Role = static_cast<const TRole*>(m.loadEntry()); break; case dtPConcept: case dtNConcept: case dtPSingleton: case dtNSingleton: setConcept(m.loadEntry()); setChild(m.loadSInt()); break; case dtProj: setChild(m.loadSInt()); Role = static_cast<const TRole*>(m.loadEntry()); ProjRole = static_cast<const TRole*>(m.loadEntry()); break; case dtNN: // nothing to do break; case dtDataType: case dtDataValue: case dtDataExpr: setConcept(m.loadEntry()); setChild(m.loadSInt()); break; } }
void DLVertex :: Save ( SaveLoadManager& m ) const { m.saveUInt(static_cast<unsigned int>(Type())); switch ( Type() ) { case dtBad: case dtTop: // can't be S/L default: fpp_unreachable(); break; case dtAnd: m.saveUInt(Child.size()); for ( const_iterator p = begin(); p != end(); ++p ) m.saveSInt(*p); break; case dtLE: m.savePointer(Role); m.saveSInt(getC()); m.saveUInt(getNumberLE()); break; case dtForall: // n here is for the automaton state m.savePointer(Role); m.saveSInt(getC()); m.saveUInt(getNumberLE()); break; case dtIrr: m.savePointer(Role); break; case dtPConcept: case dtNConcept: case dtPSingleton: case dtNSingleton: m.savePointer(Concept); m.saveSInt(getC()); break; case dtProj: m.saveSInt(getC()); m.savePointer(Role); m.savePointer(ProjRole); break; case dtNN: // nothing to do break; case dtDataType: case dtDataValue: case dtDataExpr: m.savePointer(Concept); m.saveSInt(getC()); break; } m.o() << "\n"; }