Esempio n. 1
0
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);
}
Esempio n. 3
0
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++;
			}
		}
	}
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
    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);
        }
    }
}
Esempio n. 7
0
  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;
  }
}
Esempio n. 11
0
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;
}
Esempio n. 13
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
}
Esempio n. 14
0
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");
        }
    }