bool OntologyParser::parse( const QString& filename, const QString& serializationMimeType ) { Soprano::RdfSerialization serialization = Soprano::SerializationUnknown; if( !serializationMimeType.isEmpty() ) { serialization = Soprano::mimeTypeToSerialization( serializationMimeType ); } else if ( filename.endsWith( "trig" ) ) { serialization = Soprano::SerializationTrig; } else { serialization = Soprano::SerializationRdfXml; } if ( !( d->rdfParser = Soprano::PluginManager::instance()->discoverParserForSerialization( serialization, serializationMimeType ) ) ) { return false; } if ( !quiet ) qDebug() << "(OntologyParser) Parsing " << filename << endl; Soprano::StatementIterator it = d->rdfParser->parseFile( filename, QUrl("http://org.kde.nepomuk/dummybaseuri"), serialization, serializationMimeType ); bool success = true; while( it.next() ) { const Soprano::Statement& s = *it; if( s.predicate().uri() == Soprano::Vocabulary::RDFS::subClassOf() ) { ResourceClass* rc = d->getClass( s.subject().uri().toString() ); rc->setParentResource( d->getClass( s.object().uri().toString() ) ); rc->addParentResource( d->getClass( s.object().uri().toString() ) ); rc->setGenerateClass( true ); } else if( s.predicate().uri() == Soprano::Vocabulary::RDF::type() ) { if( s.object().uri().toString().endsWith( "#Class" ) ) d->getClass( s.subject().uri().toString() )->setGenerateClass( true ); } else if( s.predicate().uri() == Soprano::Vocabulary::RDFS::domain() ) { ResourceClass* rc = d->getClass( s.object().uri().toString() ); Property* p = d->getProperty( s.subject().uri().toString() ); p->setDomain( rc ); if ( !rc->allProperties().contains( p ) ) rc->addProperty( p ); rc->setGenerateClass( true ); } else if( s.predicate().uri() == Soprano::Vocabulary::RDFS::range() ) { Property* prop = d->getProperty(s.subject().uri().toString()); QUrl type = s.object().uri(); if( type.toString().contains( "XMLSchema" ) ) { prop->setLiteralRange( d->xmlSchemaTypes[type] ); } else if( type == Soprano::Vocabulary::RDFS::Literal() ) { prop->setLiteralRange( "QString" ); } else { prop->setRange( d->getClass(s.object().uri()) ); } } else if( s.predicate().uri() == Soprano::Vocabulary::NRL::maxCardinality() || s.predicate().uri() == Soprano::Vocabulary::NRL::cardinality() ) { Property * p = d->getProperty(s.subject().uri()); int cValue = s.object().literal().toInt(); p->setIsList( cValue > 1 ); if( s.predicate().uri() == Soprano::Vocabulary::NRL::maxCardinality() ) p->setMaxCardinality( cValue ); else p->setCardinality( cValue ); } else if( s.predicate().uri() == Soprano::Vocabulary::RDFS::comment() ) { d->comments[s.subject().uri()] = s.object().literal().toString(); } else if ( s.predicate().uri() == Soprano::Vocabulary::NRL::inverseProperty() ) { d->getProperty(s.subject().uri())->setInverseProperty( d->getProperty(s.object().uri()) ); d->getProperty(s.object().uri())->setInverseProperty( d->getProperty(s.subject().uri()) ); } } // determine the reverse properties for( QMap<QUrl, Property>::iterator propIt = d->properties.begin(); propIt != d->properties.end(); ++propIt ) { Property& p = propIt.value(); if( p.range() ) { if ( !quiet ) qDebug() << "Setting reverse property " << p.uri() << " on type " << p.range()->uri() << endl; if ( !p.range()->allReverseProperties().contains( &p ) ) p.range()->addReverseProperty( &p ); } if ( !p.domain() ) { p.setDomain( d->getClass(Soprano::Vocabulary::RDFS::Resource()) ); } Q_ASSERT( d->properties.count( propIt.key() ) == 1 ); } // now assign the comments to resources and properties QMapIterator<QUrl, QString> commentsIt( d->comments ); while( commentsIt.hasNext() ) { commentsIt.next(); if( d->resources.contains( commentsIt.key() ) ) d->resources[commentsIt.key()].setComment( commentsIt.value() ); else if( d->properties.contains( commentsIt.key() ) ) d->properties[commentsIt.key()].setComment( commentsIt.value() ); } // testing stuff for( QMap<QUrl, ResourceClass>::iterator it = d->resources.begin(); it != d->resources.end(); ++it ) { if( !it->parentClass(false) ) { it->setParentResource( d->getClass(Soprano::Vocabulary::RDFS::Resource()) ); } if ( !quiet ) qDebug() << "Resource: " << (*it).name() << "[" << (*it).uri() << "]" << " (->" << (*it).parentClass(false)->name() << ")" << ( (*it).generateClass() ? " (will be generated)" : " (will not be generated)" ) << endl; Q_ASSERT( d->resources.count( it.key() ) == 1 ); QListIterator<const Property*> propIt( (*it).allProperties() ); while( propIt.hasNext() ) { const Property* p = propIt.next(); if ( !quiet ) qDebug() << " " << p->uri() << " (->" << p->typeString() << ")" << ( p->isList() ? QString("+") : QString("1") ) << endl; } } return success; }
std::vector<LinearLiteralPropagator::LinearConstraintClause> LinearLiteralPropagator::propagate_true(const ReifiedLinearConstraint& rl) { const LinearConstraint& l = rl.l; assert(l.getRelation()==LinearConstraint::Relation::LE); std::vector<LinearConstraintClause> ret; LinearConstraintClause::itervec clause; auto minmax = computeMinMax(l, clause); if (minmax.second <= l.getRhs()) return ret; //std::cout << "trying to propagate " << l << std::endl; auto views = l.getViews(); for (std::size_t index=0; index < views.size(); ++index) { auto& i = views[index]; auto wholeRange = vs_.getVariableStorage().getRestrictor(i); assert(wholeRange.size()>0); auto r = vs_.getVariableStorage().getCurrentRestrictor(i); std::pair<int64,int64> mm; mm.first = minmax.first - r.lower(); mm.second = minmax.second - r.upper(); //Literal prop = s_.falseLit(); bool prop = false; Restrictor::ViewIterator propIt(wholeRange.begin()); bool conflict = false; int64 up = l.getRhs() - mm.first; //// check if this returns the correct literals, /// see translatorClauseChecker::add, there is a positive and a negative add if (up < wholeRange.lower()) // derive false { //std::cout << "Constrain View " << i.v << "*" << i.a << "+" << i.c << " with new upper bound " << up << std::endl; propIt=wholeRange.begin();//can be removed conflict = true; } else if (up < r.upper()) { //std::cout << "Constrain Variable " << i.v << "*" << i.a << "+" << i.c << " with new upper bound " << up << std::endl; auto newUpper = std::upper_bound(wholeRange.begin(), wholeRange.end(), up, [](int64 val, int64 it){ return it > val; }); //assert(newUpper != r.end()); /// should never be able to happen, as up < r.upper().first, so there is something which is smaller, this means we do not need r ? if (newUpper==wholeRange.begin()) { propIt = newUpper; conflict=true; } else { propIt = newUpper; --newUpper; prop = true; //prop = vs_.getVariableCreator().getLiteral(newUpper); conflict = !constrainUpperBound((newUpper+1)); // +1 is needed, as it is an iterator pointing after the element minmax.first = mm.first + r.lower(); minmax.second = mm.second + *newUpper; //minmax = mm + std::minmax(i.second*(int64)r.lower(),i.second*(int64)((*newUpper))); } } if (prop || conflict) { LinearConstraintClause c(rl); LinearConstraintClause::itervec aux(clause); aux[index] = propIt; c.setClause(std::move(aux),index); c.setConflict(conflict); ret.emplace_back(c); } if (conflict) break; } //When i changed a bound, the reason for the next ones can change, right ? No! only the upper/lower bound is changes, the other bound is used for reason return ret; }
void LinearLiteralPropagator::propagate_true(const ReifiedLinearConstraint& rl) { const LinearConstraint& l = rl.l; assert(l.getRelation()==LinearConstraint::Relation::LE); propClause_.clear(); auto minmax = computeMinMax(l, propClause_); if (minmax.second <= l.getRhs()) return; if (conf_.propStrength<=2) { if (minmax.first > l.getRhs()) { propClauses_.emplace_back(std::make_pair(~rl.v,std::move(propClause_))); } return; } //std::cout << "trying to propagate " << l << std::endl; auto& views = l.getViews(); for (std::size_t index=0; index < views.size(); ++index) { auto& i = views[index]; auto wholeRange = vs_.getVariableStorage().getRestrictor(i); assert(wholeRange.size()>0); auto r = vs_.getVariableStorage().getCurrentRestrictor(i); assert(r.begin() < r.end()); std::pair<int64,int64> mm; mm.first = minmax.first - r.lower(); mm.second = minmax.second - r.upper(); //Literal prop = s_.falseLit(); bool prop = false; Restrictor::ViewIterator propIt(wholeRange.begin()); bool conflict = false; int64 up = l.getRhs() - mm.first; if (up < wholeRange.lower()) // derive false { //std::cout << "Constrain View " << i.v << "*" << i.a << "+" << i.c << " with new upper bound " << up << std::endl; //propIt=wholeRange.begin();//can be removed conflict = true; } else if (up < r.upper()) { //std::cout << "Constrain Variable " << i.v << "*" << i.a << "+" << i.c << " with new upper bound " << up << std::endl; //std::cout << "This Variable before had domain " << r.lower() << " .. " << r.upper() << std::endl; auto newUpper = order::wrap_upper_bound(wholeRange.begin(), r.end(), up); //assert(newUpper != r.end()); /// should never be able to happen, as up < r.upper().first, so there is something which is smaller, this means we do not need r ? propIt = newUpper; if (newUpper==wholeRange.begin()) { conflict=true; } else { --newUpper; prop = true; //prop = vs_.getVariableCreator().getLiteral(newUpper); //std::cout << "the upper bound not included for this view will be " << *(newUpper+1) << std::endl; conflict = !constrainUpperBound((newUpper+1)); // +1 is needed, as it is an iterator pointing after the element //minmax.first = mm.first + r.lower(); minmax.second = mm.second + *newUpper; //minmax = mm + std::minmax(i.second*(int64)r.lower(),i.second*(int64)((*newUpper))); } } if (prop || conflict) { itervec aux; if (conflict) aux = std::move(propClause_); else aux = propClause_; aux[index] = propIt; propClauses_.emplace_back(std::make_pair(~rl.v,std::move(aux))); } if (conflict) break; } //When i changed a bound, the reason for the next ones can change, right ? No! only the upper/lower bound is changes, the other bound is used for reason }