DLVHEX_NAMESPACE_BEGIN PlainModelGeneratorFactory::PlainModelGeneratorFactory( ProgramCtx& ctx, const ComponentInfo& ci, ASPSolverManager::SoftwareConfigurationPtr externalEvalConfig): BaseModelGeneratorFactory(), externalEvalConfig(externalEvalConfig), ctx(ctx), eatoms(ci.outerEatoms), idb(), xidb() { RegistryPtr reg = ctx.registry(); // this model generator can handle: // components with outer eatoms // components with inner rules // components with inner constraints // this model generator CANNOT handle: // components with inner eatoms assert(ci.innerEatoms.empty()); // copy rules and constraints to idb // TODO we do not need this except for debugging idb.reserve(ci.innerRules.size() + ci.innerConstraints.size()); idb.insert(idb.end(), ci.innerRules.begin(), ci.innerRules.end()); idb.insert(idb.end(), ci.innerConstraints.begin(), ci.innerConstraints.end()); // transform original innerRules and innerConstraints // to xidb with only auxiliaries xidb.reserve(ci.innerRules.size() + ci.innerConstraints.size()); std::back_insert_iterator<std::vector<ID> > inserter(xidb); std::transform(ci.innerRules.begin(), ci.innerRules.end(), inserter, boost::bind( &PlainModelGeneratorFactory::convertRule, this, ctx, _1)); std::transform(ci.innerConstraints.begin(), ci.innerConstraints.end(), inserter, boost::bind( &PlainModelGeneratorFactory::convertRule, this, ctx, _1)); #ifndef NDEBUG { { std::ostringstream s; RawPrinter printer(s,ctx.registry()); printer.printmany(idb," "); DBGLOG(DBG,"PlainModelGeneratorFactory got idb " << s.str()); } { std::ostringstream s; RawPrinter printer(s,ctx.registry()); printer.printmany(xidb," "); DBGLOG(DBG,"PlainModelGeneratorFactory got xidb " << s.str()); } } #endif }
DLVHEX_NAMESPACE_USE BOOST_AUTO_TEST_CASE(testDisj) { ProgramCtx ctx; ctx.setupRegistry(RegistryPtr(new Registry)); std::stringstream ss; ss << // a <-(+)-> a (head/head = disjunctive) "a v b." << std::endl << "a v c." << std::endl; InputProviderPtr ip(new InputProvider); ip->addStreamInput(ss, "testinput"); ModuleHexParser parser; BOOST_REQUIRE_NO_THROW(parser.parse(ip, ctx)); LOG_REGISTRY_PROGRAM(ctx); ID ida = ctx.registry()->ogatoms.getIDByString("a"); ID idb = ctx.registry()->ogatoms.getIDByString("b"); ID idc = ctx.registry()->ogatoms.getIDByString("c"); BOOST_REQUIRE((ida | idb | idc) != ID_FAIL); // smaller more efficient dependency graph { DependencyGraph depgraph(ctx, ctx.registry()); std::vector<ID> auxRules; depgraph.createDependencies(ctx.idb, auxRules); BOOST_CHECK_EQUAL(depgraph.countNodes(), 2); BOOST_CHECK_EQUAL(depgraph.countDependencies(), 2); // TODO test dependencies (will do manually with graphviz at the moment) const char* fnamev = "testDependencyGraphDisjVerbose.dot"; LOG(INFO,"dumping verbose graph to " << fnamev); std::ofstream filev(fnamev); depgraph.writeGraphViz(filev, true); makeGraphVizPdf(fnamev); const char* fnamet = "testDependencyGraphDisjTerse.dot"; LOG(INFO,"dumping terse graph to " << fnamet); std::ofstream filet(fnamet); depgraph.writeGraphViz(filet, false); makeGraphVizPdf(fnamet); } }
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); }
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 ModuleHexParser::parse(InputProviderPtr in, ProgramCtx& ctx) { assert(!!in); assert(!!ctx.registry()); if( ctx.edb == 0 ) { // create empty interpretation using this context's registry ctx.edb.reset(new Interpretation(ctx.registry())); DBGLOG(DBG, " reset edb "); } else { DBGLOG(DBG, " not reset edb "); } // put whole input from stream into a string // (an alternative would be the boost::spirit::multi_pass iterator // but this can be done later when the parser is updated to Spirit V2) WARNING("TODO incrementally read and parse this stream") std::ostringstream buf; buf << in->getAsStream().rdbuf(); std::string input = buf.str(); // create grammar HexGrammarSemantics semanticsMgr(ctx); HexGrammar<HexParserIterator, HexParserSkipper> grammar(semanticsMgr); // configure grammar with modules BOOST_FOREACH(HexParserModulePtr module, modules) { switch(module->getType()) { case HexParserModule::TOPLEVEL: grammar.registerToplevelModule(module->createGrammarModule()); break; case HexParserModule::BODYATOM: grammar.registerBodyAtomModule(module->createGrammarModule()); break; case HexParserModule::HEADATOM: grammar.registerHeadAtomModule(module->createGrammarModule()); break; case HexParserModule::TERM: grammar.registerTermModule(module->createGrammarModule()); break; default: LOG(ERROR,"unknown parser module type " << module->getType() << "!"); assert(false); break; } } // prepare iterators HexParserIterator it_begin = input.begin(); HexParserIterator it_end = input.end(); // parse HexParserSkipper skipper; DBGLOG(DBG,"starting to parse"); bool success = false; try { success = boost::spirit::qi::phrase_parse( it_begin, it_end, grammar, skipper); DBGLOG(DBG,"parsing returned with success=" << success); } catch(const boost::spirit::qi::expectation_failure<HexParserIterator>& e) { LOG(ERROR,"parsing returned with failure: expected '" << e.what_ << "'"); it_begin = e.first; } if( !success || it_begin != it_end ) { if( it_begin != it_end ) LOG(ERROR,"iterators not the same!"); HexParserIterator it_displaybegin = it_begin; HexParserIterator it_displayend = it_begin; unsigned usedLeft = 0; while( usedLeft++ < 50 && it_displaybegin != input.begin() && *it_displaybegin != '\n' ) it_displaybegin--; if( *it_displaybegin == '\n' ) { it_displaybegin++; usedLeft--; } unsigned limitRight = 50; while( limitRight-- > 0 && it_displayend != it_end && *it_displayend != '\n' ) it_displayend++; LOG(ERROR,"unparsed '" << std::string(it_displaybegin, it_displayend) << "'"); LOG(ERROR,"---------" << std::string(usedLeft, '-') << "^"); throw SyntaxError("Could not parse complete input!"); } // workaround: making IDs in idb unique WARNING("we should probably also do this for MLP, at the same time we should probably generalize MLP better") WARNING("we should use std::set<ID> for IDB") std::set<ID> uniqueidb(ctx.idb.begin(), ctx.idb.end()); ctx.idb.clear(); ctx.idb.insert(ctx.idb.end(), uniqueidb.begin(), uniqueidb.end()); }
int main(int argn, char** argv) { try { DLVHEX_BENCHMARK_REGISTER_AND_START(sidoverall, "overall timing"); if( argn != 5 ) { std::cerr << "usage: " << argv[0] << " <heurimode> <mbmode> <backend> <inputfile>" << std::endl; return -1; } // // setup benchmarking // benchmark::BenchmarkController& ctr = benchmark::BenchmarkController::Instance(); ctr.setOutput(&std::cerr); // for continuous statistics output, display every 1000'th output ctr.setPrintInterval(999); // deconstruct benchmarking (= output results) at scope exit int dummy; // this is needed, as SCOPE_EXIT is not defined for no arguments BOOST_SCOPE_EXIT( (dummy) ) { (void)dummy; benchmark::BenchmarkController::finish(); } BOOST_SCOPE_EXIT_END // // preprocess arguments // const std::string heurimode(argv[1]); const std::string mbmode(argv[2]); const std::string backend(argv[3]); const std::string fname(argv[4]); // get input InputProviderPtr ip(new InputProvider); ip->addFileInput(fname); // don't rewrite // prepare program context ProgramCtx ctx; { RegistryPtr registry(new Registry); ctx.setupRegistry(registry); PluginContainerPtr pluginContainer(new PluginContainer); ctx.setupPluginContainer(pluginContainer); } // create all testing plugin atoms ctx.addPluginAtom(PluginAtomPtr(new AbovePluginAtom)); ctx.addPluginAtom(PluginAtomPtr(new SenseNotArmed1PluginAtom)); ctx.addPluginAtom(PluginAtomPtr(new SenseNotArmed2PluginAtom)); ctx.addPluginAtom(PluginAtomPtr(new GenPluginAtom2("gen2",2))); // parse HEX program LOG(INFO,"parsing HEX program"); DLVHEX_BENCHMARK_REGISTER_AND_START(sidhexparse, "HexParser::parse"); ModuleHexParser parser; parser.parse(ip, ctx); DLVHEX_BENCHMARK_STOP(sidhexparse); ctx.associateExtAtomsWithPluginAtoms(ctx.idb,true); //LOG_REGISTRY_PROGRAM(ctx); // create dependency graph LOG(INFO,"creating dependency graph"); DLVHEX_BENCHMARK_REGISTER_AND_START(siddepgraph, "create dependencygraph"); std::vector<dlvhex::ID> auxRules; dlvhex::DependencyGraph depgraph(ctx, ctx.registry()); depgraph.createDependencies(ctx.idb, auxRules); DLVHEX_BENCHMARK_STOP(siddepgraph); #ifndef NDEBUG writeGraphViz(depgraph, fname+"PlainHEXDepGraph"); #endif // create component graph LOG(INFO,"creating component graph"); DLVHEX_BENCHMARK_REGISTER_AND_START(sidcompgraph, "create componentgraph"); dlvhex::ComponentGraph compgraph(depgraph, ctx.registry()); DLVHEX_BENCHMARK_STOP(sidcompgraph); #ifndef NDEBUG writeGraphViz(compgraph, fname+"PlainHEXCompGraph"); #endif // manage external evaluation configuration / backend ASPSolverManager::SoftwareConfigurationPtr externalEvalConfig; if( backend == "dlv" ) { externalEvalConfig.reset(new ASPSolver::DLVSoftware::Configuration); } else if( backend == "libdlv" ) { #ifdef HAVE_LIBDLV externalEvalConfig.reset(new ASPSolver::DLVLibSoftware::Configuration); #else std::cerr << "sorry, libdlv not compiled in" << std::endl; return -1; #endif // HAVE_LIBDLV } else if( backend == "libclingo" ) { #ifdef HAVE_LIBCLINGO externalEvalConfig.reset(new ASPSolver::ClingoSoftware::Configuration); #else std::cerr << "sorry, libclingo not compiled in" << std::endl; return -1; #endif // HAVE_LIBCLINGO } else { std::cerr << "usage: <backend> must be one of 'dlv','libdlv','libclingo'" << std::endl; return -1; } // create eval graph LOG(INFO,"creating eval graph"); DLVHEX_BENCHMARK_REGISTER_AND_START(sidevalgraph, "create evalgraph"); FinalEvalGraph evalgraph; EvalGraphBuilder egbuilder(ctx, compgraph, evalgraph, externalEvalConfig); // use one of several heuristics if( heurimode == "old" ) { // old DLVHEX heuristic LOG(INFO,"building eval graph with old heuristics"); EvalHeuristicOldDlvhex heuristicOldDlvhex; heuristicOldDlvhex.build(egbuilder); } else if( heurimode == "trivial" ) { // trivial heuristic: just take component graph // (maximum number of eval units, probably large overhead) LOG(INFO,"building eval graph with trivial heuristics"); EvalHeuristicTrivial heuristic; heuristic.build(egbuilder); } else if( heurimode == "easy" ) { // easy heuristic: just make some easy adjustments to improve on the trivial heuristics LOG(INFO,"building eval graph with easy heuristics"); EvalHeuristicEasy heuristic; heuristic.build(egbuilder); } else { std::cerr << "usage: <heurimode> must be one of 'old','trivial','easy'" << std::endl; return -1; } DLVHEX_BENCHMARK_STOP(sidevalgraph); #ifndef NDEBUG writeGraphViz(compgraph, fname+"PlainHEXEvalGraph"); #endif // setup final unit LOG(INFO,"setting up final unit"); DLVHEX_BENCHMARK_REGISTER_AND_START(sidfinalunit, "creating final unit"); EvalUnit ufinal; { ufinal = evalgraph.addUnit(FinalEvalGraph::EvalUnitPropertyBundle()); LOG(INFO,"ufinal = " << ufinal); FinalEvalGraph::EvalUnitIterator it, itend; boost::tie(it, itend) = evalgraph.getEvalUnits(); for(; it != itend && *it != ufinal; ++it) { DBGLOG(DBG,"adding dependency from ufinal to unit " << *it << " join order " << *it); // we can do this because we know that eval units (= vertices of a vecS adjacency list) are unsigned integers evalgraph.addDependency(ufinal, *it, FinalEvalGraph::EvalUnitDepPropertyBundle(*it)); } } DLVHEX_BENCHMARK_STOP(sidfinalunit); // prepare for output //GenericOutputBuilder ob; #warning reactivate and redesign outputbuilder //std::cerr << __FILE__ << ":" << __LINE__ << std::endl << *ctx.registry() << std::endl; // evaluate LOG(INFO,"evaluating"); DLVHEX_BENCHMARK_REGISTER(sidoutputmodel, "output model"); dlvhex::ModelBuilderConfig<FinalEvalGraph> mbcfg(evalgraph); if( mbmode == "online" ) { typedef FinalOnlineModelBuilder::Model Model; typedef FinalOnlineModelBuilder::OptionalModel OptionalModel; typedef FinalOfflineModelBuilder::MyModelGraph MyModelGraph; LOG(INFO,"creating model builder"); DLVHEX_BENCHMARK_REGISTER_AND_START(sidonlinemb, "create online mb"); FinalOnlineModelBuilder mb(mbcfg); DLVHEX_BENCHMARK_STOP(sidonlinemb); // get and print all models OptionalModel m; DLVHEX_BENCHMARK_REGISTER(sidgetnextonlinemodel, "get next online model"); unsigned mcount = 0; do { DBGLOG(DBG,"requesting model"); DLVHEX_BENCHMARK_START(sidgetnextonlinemodel); m = mb.getNextIModel(ufinal); DLVHEX_BENCHMARK_STOP(sidgetnextonlinemodel); if( !!m ) { InterpretationConstPtr interpretation = mb.getModelGraph().propsOf(m.get()).interpretation; #ifndef NDEBUG DBGLOG(DBG,"got model#" << mcount << ":" << *interpretation); std::set<Model> onlyFor; onlyFor.insert(m.get()); GraphVizFunc func = boost::bind(&writeEgMgGraphViz<MyModelGraph>, _1, true, boost::cref(mb.getEvalGraph()), boost::cref(mb.getModelGraph()), onlyFor); std::stringstream smodel; smodel << fname << "PlainHEXOnlineModel" << mcount; writeGraphVizFunctors(func, func, smodel.str()); #endif mcount++; // output model { std::cout << *interpretation << std::endl; } //std::cerr << __FILE__ << ":" << __LINE__ << std::endl << *ctx.registry() << std::endl; #ifndef NDEBUG mb.printEvalGraphModelGraph(std::cerr); #endif } } while( !!m ); #ifndef NDEBUG mb.printEvalGraphModelGraph(std::cerr); #endif #ifndef NDEBUG GraphVizFunc func = boost::bind(&writeEgMgGraphViz<MyModelGraph>, _1, true, boost::cref(mb.getEvalGraph()), boost::cref(mb.getModelGraph()), boost::none); writeGraphVizFunctors(func, func, fname+"PlainHEXOnlineEgMg"); #endif //std::cerr << __FILE__ << ":" << __LINE__ << std::endl << *ctx.registry() << std::endl; DLVHEX_BENCHMARK_STOP(sidoverall); std::cerr << "TIMING " << fname << " " << heurimode << " " << mbmode << " " << backend << " " << evalgraph.countEvalUnits() << " evalunits " << evalgraph.countEvalUnitDeps() << " evalunitdeps " << mcount << " models "; benchmark::BenchmarkController::Instance().printDuration(std::cerr, sidoverall) << std::endl; } else if( mbmode == "offline" ) { typedef FinalOfflineModelBuilder::Model Model; typedef FinalOfflineModelBuilder::OptionalModel OptionalModel; typedef FinalOfflineModelBuilder::MyModelGraph MyModelGraph; LOG(INFO,"creating model builder"); DLVHEX_BENCHMARK_REGISTER_AND_START(sidofflinemb, "create offline mb"); FinalOfflineModelBuilder mb(mbcfg); DLVHEX_BENCHMARK_STOP(sidofflinemb); LOG(INFO,"creating all final imodels"); DLVHEX_BENCHMARK_REGISTER_AND_START(sidofflinemodels, "create offline models"); mb.buildIModelsRecursively(ufinal); DLVHEX_BENCHMARK_STOP(sidofflinemodels); #ifndef NDEBUG mb.printEvalGraphModelGraph(std::cerr); #endif LOG(INFO,"printing models"); DLVHEX_BENCHMARK_REGISTER_AND_START(sidprintoffmodels, "print offline models"); MyModelGraph& mg = mb.getModelGraph(); const MyModelGraph::ModelList& models = mg.modelsAt(ufinal, MT_IN); unsigned mcount = 0; BOOST_FOREACH(Model m, models) { InterpretationConstPtr interpretation = mg.propsOf(m).interpretation; #ifndef NDEBUG DBGLOG(DBG,"got model#" << mcount << ":" << *interpretation); std::set<Model> onlyFor; onlyFor.insert(m); GraphVizFunc func = boost::bind(&writeEgMgGraphViz<MyModelGraph>, _1, true, boost::cref(mb.getEvalGraph()), boost::cref(mb.getModelGraph()), onlyFor); std::stringstream smodel; smodel << fname << "PlainHEXOfflineModel" << mcount; writeGraphVizFunctors(func, func, smodel.str()); #endif mcount++; // output model { std::cout << *interpretation << std::endl; } } DLVHEX_BENCHMARK_STOP(sidprintoffmodels); #ifndef NDEBUG GraphVizFunc func = boost::bind(&writeEgMgGraphViz<MyModelGraph>, _1, true, boost::cref(mb.getEvalGraph()), boost::cref(mb.getModelGraph()), boost::none); writeGraphVizFunctors(func, func, fname+"PlainHEXOfflineEgMg"); #endif DLVHEX_BENCHMARK_STOP(sidoverall); std::cerr << "TIMING " << fname << " " << heurimode << " " << mbmode << " " << backend << " " << evalgraph.countEvalUnits() << " evalunits " << evalgraph.countEvalUnitDeps() << " evalunitdeps " << mcount << " models "; benchmark::BenchmarkController::Instance().printDuration(std::cerr, sidoverall) << "s" << std::endl; } else { std::cerr << "usage: <mbmode> must be one of 'online','offline'" << std::endl; return -1; } return 0; }
DLVHEX_NAMESPACE_BEGIN ActionPluginFinalCallback::ActionPluginFinalCallback(ProgramCtx& ctx) : programCtx(ctx), ctxData(ctx.getPluginData<ActionPlugin>()), registryPtr( ctx.registry()) { }
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 }
// change model callback void MCSIEPlugin::setupProgramCtx(ProgramCtx& ctx) { ProgramCtxData& pcd = ctx.getPluginData<MCSIE>(); if( pcd.isEnabled() ) { // setup predicate masks RegistryPtr reg(ctx.registry()); // store registry in ProgramCtxData pcd.reg = reg; // configure predicate mask for d1/d2 pcd.idd1 = reg->storeConstantTerm("d1"); pcd.idd2 = reg->storeConstantTerm("d2"); pcd.brdmask.setRegistry(reg); pcd.brdmask.addPredicate(pcd.idd1); pcd.brdmask.addPredicate(pcd.idd2); pcd.brd1mask.setRegistry(reg); pcd.brd1mask.addPredicate(pcd.idd1); pcd.brd2mask.setRegistry(reg); pcd.brd2mask.addPredicate(pcd.idd2); // configure collector (if we do not use them this will not hurt performance) pcd.mindcollector.reset( new MinimalNotionCollector(pcd.brd1mask, pcd.brd2mask)); // configure predicate mask for e1/e2 pcd.ide1 = reg->storeConstantTerm("e1"); pcd.ide2 = reg->storeConstantTerm("e2"); pcd.bremask.setRegistry(reg); pcd.bremask.addPredicate(pcd.ide1); pcd.bremask.addPredicate(pcd.ide2); pcd.bre1mask.setRegistry(reg); pcd.bre1mask.addPredicate(pcd.ide1); pcd.bre2mask.setRegistry(reg); pcd.bre2mask.addPredicate(pcd.ide2); // configure collector (if we do not use them this will not hurt performance) pcd.minecollector.reset( new MinimalNotionCollector(pcd.bre1mask, pcd.bre2mask)); // configure predicate mask for each context's output beliefs assert(!pcd.mcs().contexts.empty() && "here we expect to have parsed the input and " "we expect to know the number of contexts"); for(ContextIterator it = pcd.mcs().contexts.begin(); it != pcd.mcs().contexts.end(); ++it) { pcd.obmasks.push_back(PredicateMask()); PredicateMask& mask = pcd.obmasks.back(); std::ostringstream s; s << "a" << it->ContextNum(); mask.setRegistry(reg); ID idob(reg->storeConstantTerm(s.str())); mask.addPredicate(idob); } // register model callbacks (accumulate minimal notions, print nonminimal notions) // register final callback (print minmimal notions, convert to dual notions) switch(pcd.getMode()) { case ProgramCtxData::DIAGREWRITING: { PrintAndAccumulateModelCallback* ppcd = new PrintAndAccumulateModelCallback(pcd, pcd.idd1, pcd.idd2, pcd.brdmask, pcd.mindcollector); ModelCallbackPtr mcb(ppcd); WARNING("here we could try to only remove the default answer set printer") ctx.modelCallbacks.clear(); ctx.modelCallbacks.push_back(mcb); FinalCallbackPtr fcb(new DiagRewritingFinalCallback(pcd, *ppcd, ctx.aspsoftware)); ctx.finalCallbacks.push_back(fcb); } break; case ProgramCtxData::EXPLREWRITING: { PrintAndAccumulateModelCallback* ppcd = new PrintAndAccumulateModelCallback(pcd, pcd.ide1, pcd.ide2, pcd.bremask, pcd.minecollector); ModelCallbackPtr mcb(ppcd); WARNING("here we could try to only remove the default answer set printer") ctx.modelCallbacks.clear(); ctx.modelCallbacks.push_back(mcb); FinalCallbackPtr fcb(new ExplRewritingFinalCallback(pcd, *ppcd, ctx.aspsoftware)); ctx.finalCallbacks.push_back(fcb); } break; case ProgramCtxData::EQREWRITING: { ModelCallbackPtr mcb(new PrintEQModelCallback(pcd)); WARNING("here we could try to only remove the default answer set printer") ctx.modelCallbacks.clear(); ctx.modelCallbacks.push_back(mcb); // no final callback } break; } } }