void ConsistencyAtom::storeID( RegistryPtr& registry) { domainAuxID=registry->getAuxiliaryConstantSymbol('t',ID::termFromInteger(0)); maximizeAuxID=registry->getAuxiliaryConstantSymbol('t',ID::termFromInteger(1)); minimizeAuxID=registry->getAuxiliaryConstantSymbol('t',ID::termFromInteger(2)); exprAuxID=registry->getAuxiliaryConstantSymbol('t',ID::termFromInteger(3)); not_exprAuxID=registry->getAuxiliaryConstantSymbol('t',ID::termFromInteger(4)); sumElementAuxID=registry->getAuxiliaryConstantSymbol('t',ID::termFromInteger(5)); pm.setRegistry(registry); pm.addPredicate(exprAuxID); pm.addPredicate(not_exprAuxID); idSaved=true; }
CSVAnswerSetPrinterCallback::CSVAnswerSetPrinterCallback(ProgramCtx& ctx, const std::string& predicate) : firstas(true) { RegistryPtr reg = ctx.registry(); filterpm.reset(new PredicateMask); // setup mask with registry filterpm->setRegistry(reg); // setup mask with predicates ID pred = reg->storeConstantTerm(predicate); filterpm->addPredicate(pred); }
void ArgumentsAtom::retrieve(const Query& query, Answer& answer) throw (PluginError) { RegistryPtr reg = query.interpretation->getRegistry(); // Extract answer index, answerset index and predicate to retrieve int answerindex = query.input[0].address; int answersetindex = query.input[1].address; ID predicate = query.input[2]; // check index validity if (answerindex < 0 || answerindex >= resultsetCache.size()){ throw PluginError("An invalid answer handle was passed to atom &arguments"); }else if(answersetindex < 0 || answersetindex >= resultsetCache[answerindex].size()){ throw PluginError("An invalid answer-set handle was passed to atom &arguments"); }else{ int runningindex = 0; // Go through all atoms of the given answer_set for(Interpretation::Storage::enumerator it = (resultsetCache[answerindex])[answersetindex]->getStorage().first(); it != (resultsetCache[answerindex])[answersetindex]->getStorage().end(); ++it){ ID ogid(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it); const OrdinaryAtom& ogatom = reg->ogatoms.getByID(ogid); // If the atom is built upon the given predicate, return it's parameters if (ogatom.tuple[0] == predicate){ // special case of index "s": positive or strongly negated Tuple ts; ts.push_back(ID::termFromInteger(runningindex)); Term t(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "s"); ts.push_back(reg->storeTerm(t)); ts.push_back(ID::termFromInteger(/*it->isStronglyNegated() ? 1 :*/ 0)); // TODO: check if the atom is strongly negated answer.get().push_back(ts); // Go through all parameters for (int i = 1; i < ogatom.tuple.size(); ++i){ Tuple t; t.push_back(ID::termFromInteger(runningindex)); t.push_back(ID::termFromInteger(i - 1)); t.push_back(ogatom.tuple[i]); answer.get().push_back(t); } runningindex++; } } } }
string ConsistencyAtom::getExpressionFromID(RegistryPtr& reg, const OrdinaryAtom& atom,bool replaceReversibleOperator ) { ostringstream os; for(int i=1;i<atom.tuple.size();i++) { if(atom.tuple[i].isConstantTerm()) { string str=reg->getTermStringByID(atom.tuple[i]); os<<removeQuotes(str); } else { os<<printToString<RawPrinter>(atom.tuple[i],reg); } } string toReturn; if(replaceReversibleOperator) { toReturn= replaceInvertibleOperator(os.str()); } else { toReturn=os.str(); } return toReturn; }
void operator()( ChoiceParserModuleSemantics& mgr, const boost::fusion::vector2< dlvhex::Tuple, boost::optional<std::vector<dlvhex::ID> > >& source, ID& target) { RegistryPtr reg = mgr.ctx.registry(); // add original rule body to all rewritten rules Tuple rules = boost::fusion::at_c<0>(source); if (!!boost::fusion::at_c<1>(source)) { int i = 0; BOOST_FOREACH (ID ruleID, rules) { Rule rule = reg->rules.getByID(ruleID); rule.body.insert(rule.body.end(), boost::fusion::at_c<1>(source).get().begin(), boost::fusion::at_c<1>(source).get().end()); rules[i] = reg->storeRule(rule); i++; }
DLVHEX_NAMESPACE_BEGIN AnswerSetPrinterCallback::AnswerSetPrinterCallback(ProgramCtx& ctx) : ctx(ctx) { RegistryPtr reg = ctx.registry(); if( !ctx.config.getFilters().empty() ) { filterpm.reset(new PredicateMask); // setup mask with registry filterpm->setRegistry(reg); // setup mask with predicates std::vector<std::string>::const_iterator it; for(it = ctx.config.getFilters().begin(); it != ctx.config.getFilters().end(); ++it) { // retrieve/register ID for this constant ID pred = reg->storeConstantTerm(*it); filterpm->addPredicate(pred); } } }
void operator()( ExistsParserModuleSemantics& mgr, const boost::fusion::vector2< std::vector<dlvhex::ID>, dlvhex::ID >& source, ID& target) { RegistryPtr reg = mgr.ctx.registry(); const ID idexists = reg->getAuxiliaryConstantSymbol('x', ID(0,0)); // predicate OrdinaryAtom oatom(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYN | ID::PROPERTY_AUX); oatom.tuple.push_back(idexists); // ID of the original atom oatom.tuple.push_back(boost::fusion::at_c<1>(source)); // existentially quantified variables BOOST_FOREACH (ID var, boost::fusion::at_c<0>(source)){ oatom.tuple.push_back(var); }
/** * @brief utility function that prints a Tuple on the specified ostream */ void ActionPluginFinalCallback::printTuple(std::ostream& output, const Tuple& tuple, const RegistryPtr registryPtr) { bool first = true; for (Tuple::const_iterator it = tuple.begin(); it != tuple.end(); it++) { if (first) first = !first; else output << ", "; if (it->isConstantTerm() || it->isVariableTerm()) output << registryPtr->getTermStringByID(*it); else output << it->address; } }
void DiagRewritingFinalCallback:: operator()() { typedef MinimalNotionCollector::MinimalNotion MinimalNotion; typedef std::list<MinimalNotion>::const_iterator MinimalNotionIterator; std::ostream& o = std::cout; RegistryPtr reg = pcd.reg; if( pcd.isminDiag() ) { // print minimal diagnosis notions for(MinimalNotionIterator it = pcd.mindcollector->getMinimals().begin(); it != pcd.mindcollector->getMinimals().end(); ++it) { if( pcd.isprintOPEQ() ) { for(std::list<InterpretationPtr>::const_iterator itl = it->full.begin(); itl != it->full.end(); ++itl) { o << "Dm:EQ:"; nprinter.print(o, *itl); o << ":"; eqprinter.print(o,*itl); o << std::endl; } } else { o << "Dm:"; nprinter.print(o, it->full.front()); o << std::endl; } } } if( !pcd.isminExp() && !pcd.isExp() ) return; // else do conversion minimal diagnoses -> explanations // (if we need to convert to explanations, we already collected // minimal diagnoses during model enumeration!) std::string prog; { std::stringstream ss; ss << "e1(R) v ne1(R) :- rule(R)." << std::endl; ss << "e2(R) v ne2(R) :- rule(R)." << std::endl; // for every bridge rule we create a predicate rule(br). for(BridgeRuleIterator it = pcd.mcs().rules.begin(); it != pcd.mcs().rules.end(); ++it) { ss << "rule(" << it->Id() << ").\n"; } // for each minimal diagnosis for(MinimalNotionIterator itn = pcd.mindcollector->getMinimals().begin(); itn != pcd.mindcollector->getMinimals().end(); ++itn) { { bool first = true; Interpretation::TrueBitIterator it, it_end; for(boost::tie(it, it_end) = itn->projected1->trueBits(); it != it_end; ++it) { const OrdinaryAtom& a = itn->projected1->getAtomToBit(it); assert(a.tuple.size() == 2); const std::string& ruleid = reg->getTermStringByID(a.tuple[1]); if( first ) first = false; else ss << " v "; ss << "e1(" << ruleid << ")"; } for(boost::tie(it, it_end) = itn->projected2->trueBits(); it != it_end; ++it) { const OrdinaryAtom& a = itn->projected2->getAtomToBit(it); assert(a.tuple.size() == 2); const std::string& ruleid = reg->getTermStringByID(a.tuple[1]); if( first ) first = false; else ss << " v "; ss << "e2(" << ruleid << ")"; } if( first ) { // empty diagnosis -> system is consistent -> make this program inconsistent ss << "true. :- true.\n"; } else { ss << ".\n"; } } } prog = ss.str(); } DBGLOG(DBG,"conversion from diagnoses to explanations uses program:\n" << prog); InputProviderPtr inp(new InputProvider()); inp->addStringInput(prog,"mcsie_conv_diag_expl"); ASPSolverManager mgr; ASPSolverManager::ResultsPtr results = mgr.solve(*software, *inp, reg); // prepare notion printer for explanations NotionPrinter eprinter(pcd, pcd.ide1, pcd.ide2, pcd.bremask); // retrieve all answer sets // and feed them into minimal diagnosis notion collector (unused so far in --iemode=expl) AnswerSetPtr as = results->getNextAnswerSet(); while( !!as ) { DBGLOG(DBG,"Dm->Em converter got answer set " << *as->interpretation); if( pcd.isExp() ) { o << "E:"; eprinter.print(o, as->interpretation); o << std::endl; } if( pcd.isminExp() ) { pcd.minecollector->record(as->interpretation); } as = results->getNextAnswerSet(); } if( pcd.isminExp() ) { // get minimal notions and print them for(std::list<MinimalNotion>::const_iterator it = pcd.minecollector->getMinimals().begin(); it != pcd.minecollector->getMinimals().end(); ++it) { assert(it->full.size() == 1 && "should only have one answer set for converted notions"); o << "Em:"; eprinter.print(o, it->full.front()); o << std::endl; } } }
void ExplRewritingFinalCallback:: operator()() { typedef MinimalNotionCollector::MinimalNotion MinimalNotion; typedef std::list<MinimalNotion>::const_iterator MinimalNotionIterator; std::ostream& o = std::cout; RegistryPtr reg = pcd.reg; if( pcd.isminExp() ) { // print minimal explanation notions for(MinimalNotionIterator it = pcd.minecollector->getMinimals().begin(); it != pcd.minecollector->getMinimals().end(); ++it) { o << "Em:"; nprinter.print(o, it->full.front()); o << std::endl; } } assert(!pcd.isDiag() && "convertion from explanation to diagnosis not possible!"); if( !pcd.isminDiag() ) return; // else do conversion minimal explanations -> minimal diagnoses // (if we need to convert to diagnoses, we already collected // minimal explanations during model enumeration!) std::string prog; { std::stringstream ss; ss << "d1(R) v nd1(R) :- rule(R)." << std::endl; ss << "d2(R) v nd2(R) :- rule(R)." << std::endl; ss << ":- d1(R), d2(R)." << std::endl; // this is not necessary, but not wrong either // (we only use the subset-minimal result of this, which never contains d1 and d2 for a rule) // for every bridge rule we create a predicate rule(br). for(BridgeRuleIterator it = pcd.mcs().rules.begin(); it != pcd.mcs().rules.end(); ++it) { ss << "rule(" << it->Id() << ").\n"; } // for each minimal explanation for(MinimalNotionIterator itn = pcd.minecollector->getMinimals().begin(); itn != pcd.minecollector->getMinimals().end(); ++itn) { { bool first = true; Interpretation::TrueBitIterator it, it_end; for(boost::tie(it, it_end) = itn->projected1->trueBits(); it != it_end; ++it) { const OrdinaryAtom& a = itn->projected1->getAtomToBit(it); assert(a.tuple.size() == 2); const std::string& ruleid = reg->getTermStringByID(a.tuple[1]); if( first ) first = false; else ss << " v "; ss << "d1(" << ruleid << ")"; } for(boost::tie(it, it_end) = itn->projected2->trueBits(); it != it_end; ++it) { const OrdinaryAtom& a = itn->projected2->getAtomToBit(it); assert(a.tuple.size() == 2); const std::string& ruleid = reg->getTermStringByID(a.tuple[1]); if( first ) first = false; else ss << " v "; ss << "d2(" << ruleid << ")"; } if( !first ) { // nonempty explanation -> finish disjunction ss << ".\n"; } } } prog = ss.str(); } DBGLOG(DBG,"conversion from explanations to diagnoses uses program:\n" << prog); InputProviderPtr inp(new InputProvider()); inp->addStringInput(prog,"mcsie_conv_expl_diag"); ASPSolverManager mgr; ASPSolverManager::ResultsPtr results = mgr.solve(*software, *inp, reg); // retrieve all answer sets // and feed them into minimal diagnosis notion collector (unused so far in --iemode=expl) AnswerSetPtr as = results->getNextAnswerSet(); while( !!as ) { DBGLOG(DBG,"Em->Dm converter got answer set " << *as->interpretation); pcd.mindcollector->record(as->interpretation); as = results->getNextAnswerSet(); } // get minimal notions and print them NotionPrinter dmprinter(pcd, pcd.idd1, pcd.idd2, pcd.brdmask); for(std::list<MinimalNotion>::const_iterator it = pcd.mindcollector->getMinimals().begin(); it != pcd.mindcollector->getMinimals().end(); ++it) { assert(!pcd.isprintOPEQ() && "cannot print output projected equilibria when converting explanations to diagnoses"); assert(it->full.size() == 1 && "should only have one answer set for converted notions"); o << "Dm:"; dmprinter.print(o, it->full.front()); o << std::endl; } }
void SimulatorAtom::retrieve(const Query& query, Answer& answer) throw (PluginError){ RegistryPtr reg = query.interpretation->getRegistry(); const Tuple& params = query.input; // get ASP filename std::string programpath = reg->terms.getByID(params[0]).getUnquotedString(); // if we access this file for the first time, parse the content if (programs.find(programpath) == programs.end()){ DBGLOG(DBG, "Parsing simulation program"); InputProviderPtr ip(new InputProvider()); ip->addFileInput(programpath); Logger::Levels l = Logger::Instance().getPrintLevels(); // workaround: verbose causes the parse call below to fail (registry pointer is 0) Logger::Instance().setPrintLevels(0); programs[programpath].changeRegistry(reg); ModuleHexParser hp; hp.parse(ip, programs[programpath]); Logger::Instance().setPrintLevels(l); } ProgramCtx& pc = programs[programpath]; // construct edb DBGLOG(DBG, "Constructing EDB"); InterpretationPtr edb = InterpretationPtr(new Interpretation(*pc.edb)); // go through all input atoms DBGLOG(DBG, "Rewriting input"); for(Interpretation::Storage::enumerator it = query.interpretation->getStorage().first(); it != query.interpretation->getStorage().end(); ++it){ ID ogid(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it); const OrdinaryAtom& ogatom = reg->ogatoms.getByID(ogid); // check if the predicate matches any of the input parameters to simulator atom bool found = false; for (int inp = 1; inp < params.size(); ++inp){ if (ogatom.tuple[0] == params[inp]){ // replace the predicate by "in[inp]" std::stringstream inPredStr; inPredStr << "in" << inp; Term inPredTerm(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, inPredStr.str()); ID inPredID = reg->storeTerm(inPredTerm); OrdinaryAtom oareplace = ogatom; oareplace.tuple[0] = inPredID; // get ID of replaced atom ID oareplaceID = reg->storeOrdinaryGAtom(oareplace); // set this atom in the input interpretation edb->getStorage().set_bit(oareplaceID.address); found = true; break; } } assert(found); } DBGLOG(DBG, "Grounding simulation program"); OrdinaryASPProgram program(pc.registry(), pc.idb, edb); InternalGrounderPtr ig = InternalGrounderPtr(new InternalGrounder(pc, program)); OrdinaryASPProgram gprogram = ig->getGroundProgram(); DBGLOG(DBG, "Evaluating simulation program"); GenuineSolverPtr igas = GenuineSolver::getInstance(pc, gprogram); InterpretationPtr as = igas->getNextModel(); if (as != InterpretationPtr()){ // extract parameters from all atoms over predicate "out" DBGLOG(DBG, "Rewrting output"); Term outPredTerm(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "out"); ID outPredID = reg->storeTerm(outPredTerm); for(Interpretation::Storage::enumerator it = as->getStorage().first(); it != as->getStorage().end(); ++it){ ID ogid(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it); const OrdinaryAtom& ogatom = reg->ogatoms.getByID(ogid); if (ogatom.tuple[0] == outPredID){ Tuple t; for (int ot = 1; ot < ogatom.tuple.size(); ++ot){ t.push_back(ogatom.tuple[ot]); } answer.get().push_back(t); } } } }
bool AnswerSetPrinterCallback::operator()( AnswerSetPtr as) { DLVHEX_BENCHMARK_REGISTER_AND_SCOPE(sid,"AnswerSetPrinterCallback"); // uses the Registry to print the interpretation, including // possible influence from AuxiliaryPrinter objects (if any are registered) Interpretation::Storage::enumerator it, it_end; RegistryPtr reg = as->interpretation->getRegistry(); // must be in this scope! Interpretation::Storage filteredbits; if( !filterpm ) { const Interpretation::Storage& bits = as->interpretation->getStorage(); it = bits.first(); it_end = bits.end(); } else { filterpm->updateMask(); filteredbits = as->interpretation->getStorage() & filterpm->mask()->getStorage(); it = filteredbits.first(); it_end = filteredbits.end(); } std::ostream& o = std::cout; WARNING("TODO think about more efficient printing") o << '{'; if( it != it_end ) { bool gotOutput = reg->printAtomForUser(o, *it); //DBGLOG(DBG,"printed with prefix '' and output " << gotOutput << " " << // printToString<RawPrinter>(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it), reg)); it++; for(; it != it_end; ++it) { if( gotOutput ) { gotOutput |= reg->printAtomForUser(o, *it, ","); //DBGLOG(DBG,"printed with prefix ',' and output " << gotOutput << " " << // printToString<RawPrinter>(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it), reg)); } else { gotOutput |= reg->printAtomForUser(o, *it); //DBGLOG(DBG,"printed with prefix '' and output " << gotOutput << " " << // printToString<RawPrinter>(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it), reg)); } } } o << '}'; as->printWeightVector(o); o << std::endl; if (ctx.config.getOption("WaitOnModel")) { std::cerr << "<waiting>" << std::endl; std::string line; std::getline(std::cin, line); } // never abort return true; }
void ArgSemExtAtom::retrieve(const Query& query, Answer& answer) throw (PluginError) { assert(query.input.size() == 6); RegistryPtr reg = getRegistry(); // check if pspoil is true { // id of constant of saturate/spoil predicate ID saturate_pred = query.input[4]; // get id of 0-ary atom OrdinaryAtom saturate_oatom(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG); saturate_oatom.tuple.push_back(saturate_pred); ID saturate_atom = reg->storeOrdinaryGAtom(saturate_oatom); DBGLOG(DBG,"got saturate_pred=" << saturate_pred << " and saturate_atom=" << saturate_atom); // check if atom <saturate_pred> is true in interpretation bool saturate = query.interpretation->getFact(saturate_atom.address); LOG(DBG,"ArgSemExtAtom called with pos saturate=" << saturate); if( saturate ) { // always return true answer.get().push_back(Tuple()); return; } } // check if nspoil is true { // id of constant of saturate/spoil predicate ID saturate_pred = query.input[5]; // get id of 0-ary atom OrdinaryAtom saturate_oatom(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG); saturate_oatom.tuple.push_back(saturate_pred); ID saturate_atom = reg->storeOrdinaryGAtom(saturate_oatom); DBGLOG(DBG,"got saturate_pred=" << saturate_pred << " and saturate_atom=" << saturate_atom); // check if atom <saturate_pred> is true in interpretation bool saturate = query.interpretation->getFact(saturate_atom.address); LOG(DBG,"ArgSemExtAtom called with neg saturate=" << saturate); if( saturate ) { // always return false answer.use(); return; } } // get arguments const std::string& semantics = reg->getTermStringByID(query.input[0]); ID argRelId = query.input[1]; ID attRelId = query.input[2]; ID extRelId = query.input[3]; // assemble facts from input std::stringstream s; { // add argumentation framework (att, arg) as predicates att/2 and arg/1 // (ignore predicate name of given atoms) // TODO: we could do this more efficiently using extctx.edb->setFact(...); and not by parsing // arguments { PredicateMask& argMask = getPredicateMask(argRelId, reg); argMask.updateMask(); InterpretationPtr argInt(new Interpretation(*query.interpretation)); argInt->bit_and(*argMask.mask()); for(auto begend = argInt->trueBits(); begend.first != begend.second; ++begend.first++) { auto bit_it = begend.first; const OrdinaryAtom& atom = argInt->getAtomToBit(bit_it); assert(atom.tuple.size() == 2); s << "arg(" << printToString<RawPrinter>(atom.tuple[1], reg) << ").\n"; } } // attacks { PredicateMask& attMask = getPredicateMask(attRelId, reg); attMask.updateMask(); InterpretationPtr attInt(new Interpretation(*query.interpretation)); attInt->bit_and(*attMask.mask()); for(auto begend = attInt->trueBits(); begend.first != begend.second; ++begend.first++) { auto bit_it = begend.first; const OrdinaryAtom& atom = attInt->getAtomToBit(bit_it); assert(atom.tuple.size() == 3); s << "att(" << printToString<RawPrinter>(atom.tuple[1], reg) << "," << printToString<RawPrinter>(atom.tuple[2], reg) << ").\n"; } } // extension to check { PredicateMask& extMask = getPredicateMask(extRelId, reg); extMask.updateMask(); InterpretationPtr extInt(new Interpretation(*query.interpretation)); extInt->bit_and(*extMask.mask()); for(auto begend = extInt->trueBits(); begend.first != begend.second; ++begend.first++) { auto bit_it = begend.first; const OrdinaryAtom& atom = extInt->getAtomToBit(bit_it); assert(atom.tuple.size() == 2); s << "ext(" << printToString<RawPrinter>(atom.tuple[1], reg) << ").\n"; } } // add check s << "%% check if ext/1 is an extension\n" ":- arg(X), ext(X), out(X).\n" ":- arg(X), not ext(X), in(X).\n"; } // build program InputProviderPtr input(new InputProvider); input->addStringInput(s.str(),"facts_from_predicate_input"); input->addFileInput(semantics + ".encoding"); #if 0 // we use an extra registry for an external program ProgramCtx extctx; extctx.setupRegistry(RegistryPtr(new Registry)); // parse ModuleHexParser parser; parser.parse(input, extctx); DBGLOG(DBG,"after parsing input: idb and edb are" << std::endl << std::endl << printManyToString<RawPrinter>(extctx.idb,"\n",extctx.registry()) << std::endl << *extctx.edb << std::endl); // check if there is one answer set, if yes return true, false otherwise { typedef ASPSolverManager::SoftwareConfiguration<ASPSolver::DLVSoftware> DLVConfiguration; DLVConfiguration dlv; OrdinaryASPProgram program(extctx.registry(), extctx.idb, extctx.edb, extctx.maxint); ASPSolverManager mgr; ASPSolverManager::ResultsPtr res = mgr.solve(dlv, program); AnswerSet::Ptr firstAnswerSet = res->getNextAnswerSet(); if( firstAnswerSet != 0 ) { LOG(DBG,"got answer set " << *firstAnswerSet->interpretation); // true answer.get().push_back(Tuple()); } else { LOG(DBG,"got no answer set!"); // false (-> mark as used) answer.use(); } } #else ProgramCtx subctx = ctx; subctx.changeRegistry(RegistryPtr(new Registry)); subctx.edb.reset(new Interpretation(subctx.registry())); subctx.inputProvider = input; input.reset(); // parse into subctx, but do not call converters if( !subctx.parser ) { subctx.parser.reset(new ModuleHexParser); } subctx.parser->parse(subctx.inputProvider, subctx); std::vector<InterpretationPtr> subas = ctx.evaluateSubprogram(subctx, false); if( !subas.empty() ) { LOG(DBG,"got answer set " << *subas.front()); // true answer.get().push_back(Tuple()); } else { LOG(DBG,"got no answer set!"); // false (-> mark as used) answer.use(); } #endif }
void ExtSourceProperties::interpretProperties(RegistryPtr reg, const ExternalAtom& atom, const std::vector<std::vector<std::string> >& props) { DBGLOG(DBG, "Interpreting external source properties"); typedef std::vector<std::string> Prop; BOOST_FOREACH (Prop p, props) { // parameter interpretation ID param1 = ID_FAIL; ID param2 = ID_FAIL; if (p.size() > 1) { try { param1 = ID::termFromInteger(boost::lexical_cast<int>(p[1])); } catch(boost::bad_lexical_cast&) { param1 = reg->storeConstantTerm(p[1]); } } if (p.size() > 2) { try { param2 = ID::termFromInteger(boost::lexical_cast<int>(p[2])); } catch(boost::bad_lexical_cast&) { param2 = reg->storeConstantTerm(p[2]); } } // property interpretation std::string name = p[0]; if (name == "functional") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"functional\" expects no parameters"); DBGLOG(DBG, "External Atom is functional"); functional = true; } else if (name == "monotonic") { if (param2 != ID_FAIL) throw GeneralError("Property \"monotonic\" expects less than two parameters"); if (param1 == ID_FAIL) { DBGLOG(DBG, "External Atom is monotonic in all input parameters"); for (uint32_t i = 0; i < atom.inputs.size(); ++i) { monotonicInputPredicates.insert(i); } } else { bool found = false; for (uint32_t i = 0; i < atom.inputs.size(); ++i) { if (atom.inputs[i] == param1) { DBGLOG(DBG, "External Atom is monotonic in parameter " << i); monotonicInputPredicates.insert(i); found = true; break; } } if (!found) throw SyntaxError("Property refers to invalid input parameter"); } } else if (name == "antimonotonic") { if (param2 != ID_FAIL) throw GeneralError("Property \"antimonotonic\" expects less than two parameters"); if (param1 == ID_FAIL) { DBGLOG(DBG, "External Atom is antimonotonic in all input parameters"); for (uint32_t i = 0; i < atom.inputs.size(); ++i) { antimonotonicInputPredicates.insert(i); } } else { bool found = false; for (uint32_t i = 0; i < atom.inputs.size(); ++i) { if (atom.inputs[i] == param1) { DBGLOG(DBG, "External Atom is antimonotonic in parameter " << i); antimonotonicInputPredicates.insert(i); found = true; break; } } if (!found) throw SyntaxError("Property refers to invalid input parameter"); } } else if (name == "atomlevellinear" || name == "fullylinear") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"atomlevellinear\" expects no parameters"); DBGLOG(DBG, "External Atom is linear on atom level"); atomlevellinear = true; } else if (name == "tuplelevellinear") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"tuplelevellinear\" expects no parameters"); DBGLOG(DBG, "External Atom is linear on tuple level"); tuplelevellinear = true; } else if (name == "usesenvironment") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"usesenvironment\" expects no parameters"); DBGLOG(DBG, "External Atom uses environment"); usesEnvironment = true; } else if (name == "finitedomain") { if (param2 != ID_FAIL) throw GeneralError("Property \"finitedomain\" expects less than two parameters"); if (param1 == ID_FAIL) { DBGLOG(DBG, "External Atom has a finite domain in all output positions"); for (uint32_t i = 0; i < atom.tuple.size(); ++i) { finiteOutputDomain.insert(i); } } else { bool found = false; if (!param1.isIntegerTerm()) throw GeneralError("The parameter of property \"finitedomain\" must be an integer"); finiteOutputDomain.insert(param1.address); } } else if (name == "relativefinitedomain") { if (param1 == ID_FAIL || param2 == ID_FAIL) throw GeneralError("Property \"relativefinitedomain\" expects two parameters"); int wrt; bool found = false; for (uint32_t i = 0; i < atom.inputs.size(); ++i) { if (atom.inputs[i] == param2) { wrt = i; found = true; break; } } if (!found) throw SyntaxError("Property refers to invalid input parameter"); if (!param1.isIntegerTerm()) throw GeneralError("The first parameter of property \"relativefinitedomain\" must be an integer"); relativeFiniteOutputDomain.insert(std::pair<int, int>(param1.address, wrt)); } else if (name == "finitefiber") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"finitefiber\" expects no parameters"); DBGLOG(DBG, "External Atom has a finite fiber"); finiteFiber = true; } else if (name == "wellorderingstrlen") { if (param1 == ID_FAIL || param2 == ID_FAIL) throw GeneralError("Property \"wellordering\" expects two parameters"); DBGLOG(DBG, "External Atom has a wellordering using strlen"); wellorderingStrlen.insert(std::pair<int, int>(param1.address, param2.address)); } else if (name == "wellordering") { if (param1 == ID_FAIL || param2 == ID_FAIL) throw GeneralError("Property \"wellordering\" expects two parameters"); DBGLOG(DBG, "External Atom has a wellordering using natural"); wellorderingNatural.insert(std::pair<int, int>(param1.address, param2.address)); } else if (name == "supportsets") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"supportsets\" expects no parameters"); DBGLOG(DBG, "External Atom provides support sets"); supportSets = true; } else if (name == "completepositivesupportsets") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"completepositivesupportsets\" expects no parameters"); DBGLOG(DBG, "External Atom provides complete positive support sets"); supportSets = true; completePositiveSupportSets = true; } else if (name == "completenegativesupportsets") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"completepositivesupportsets\" expects no parameters"); DBGLOG(DBG, "External Atom provides complete negative support sets"); supportSets = true; completeNegativeSupportSets = true; } else if (name == "variableoutputarity") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"variableoutputarity\" expects no parameters"); DBGLOG(DBG, "External Atom has a variable output arity"); variableOutputArity = true; } else if (name == "caresaboutassigned") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"caresaboutassigned\" expects no parameters"); DBGLOG(DBG, "External Atom cares about assigned atoms"); caresAboutAssigned = true; } else if (name == "caresaboutchanged") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"caresaboutchanged\" expects no parameters"); DBGLOG(DBG, "External Atom has a variable output arity"); caresAboutChanged = true; } else { throw SyntaxError("Property \"" + name + "\" unrecognized"); } }