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
}
Exemplo n.º 2
0
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);
        }
    }
}
Exemplo n.º 5
0
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());
}
Exemplo n.º 6
0
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()) {
}
Exemplo n.º 8
0
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
}
Exemplo n.º 9
0
// 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;
    }
  }
}