Ejemplo n.º 1
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++;
			}
		}
	}
}
Ejemplo n.º 2
0
	virtual void retrieve(const Query& q, Answer& a) throw (dlvhex::PluginError)
  {
    // get input
    assert(q.input.size() == 1);
    ID pred = q.input[0];

    // get outputs
    assert(q.pattern.size() == outputSize);

    // build unifier
    OrdinaryAtom unifier(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYN);
    unifier.tuple.push_back(pred);
    unifier.tuple.insert(unifier.tuple.begin(), q.pattern.begin(), q.pattern.end());

    // check if <pred>(pattern) part of interpretation (=forward <pred> via external atom)
    assert(q.interpretation != 0);
    const Interpretation::Storage& bits = q.interpretation->getStorage();
    for(Interpretation::Storage::enumerator it = bits.first();
        it != bits.end(); ++it)
    {
      const OrdinaryAtom& ogatom = registry->ogatoms.getByID(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it));
      if( ogatom.unifiesWith(unifier) )
      {
        Tuple partial;
        partial.insert(partial.begin(), ogatom.tuple.begin()+1, ogatom.tuple.end());
        a.get().push_back(partial);
      }
    }
  }
Ejemplo n.º 3
0
void
PredicatesAtom::retrieve(const Query& query, Answer& answer) throw (PluginError)
{
	RegistryPtr reg = query.interpretation->getRegistry();

	// Retrieve answer index and answer-set index
	int answerindex = query.input[0].address;
	int answersetindex = query.input[1].address;

	// check index validity
	if (answerindex < 0 || answerindex >= resultsetCache.size()){
		throw PluginError("An invalid answer handle was passed to atom &predicates");
	}else if(answersetindex < 0 || answersetindex >= resultsetCache[answerindex].size()){
		throw PluginError("An invalid answer-set handle was passed to atom &predicates");
	}else{
		// 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){

			if (!reg->ogatoms.getIDByAddress(*it).isAuxiliary()){
				ID ogid(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it);
				const OrdinaryAtom& ogatom = reg->ogatoms.getByID(ogid);

				Tuple t;
				t.push_back(ogatom.tuple[0]);
				t.push_back(ID::termFromInteger(ogatom.tuple.size() - 1));
				answer.get().push_back(t);
			}
		}
	}
}
Ejemplo n.º 4
0
void
CallHexFileAtom::retrieve(const Query& query, Answer& answer) throw (PluginError)
{
	RegistryPtr reg = query.interpretation->getRegistry();

	std::string programpath;
	std::string cmdargs;
	InterpretationConstPtr inputfacts = query.interpretation;
	try{
		const Tuple& params = query.input;

		// load program
		programpath = reg->terms.getByID(params[0]).getUnquotedString();

		// Retrieve command line arguments
		if (params.size() > 1 + arity){
			cmdargs = reg->terms.getByID(params[1 + arity]).getUnquotedString();
		}

		// Build hex call identifier
		HexCall hc(HexCall::HexFile, programpath, cmdargs, inputfacts);

		// request entry from cache (this will automatically add it if it's not contained yet)
		Tuple out;
		out.push_back(ID::termFromInteger(resultsetCache[hc]));
		answer.get().push_back(out);
	}catch(PluginError){
		throw;
	}catch(...){
		std::stringstream msg;
		msg << "Nested Hex program \"" << programpath << "\" failed. Command line arguments were: " << cmdargs;
		throw PluginError(msg.str());
	}
}
Ejemplo n.º 5
0
	virtual void retrieve(const Query& q, Answer& a) throw (dlvhex::PluginError)
  {
    // get input
    assert(checkInputArity(q.input.size()));
    assert(checkOutputArity(getExtSourceProperties(), q.pattern.size()));

    ID idoutput = registry->ogatoms.getIDByTuple(q.input);
    // no ogatom -> cannot be in interpretation
    if( idoutput == ID_FAIL )
      return;

    assert(q.interpretation != 0);
    if( q.interpretation->getFact(idoutput.address) )
    {
      // success = found = true!
      a.get().push_back(Tuple());
    }
  }
Ejemplo n.º 6
0
	virtual void retrieve(const Query& q, Answer& a) throw (dlvhex::PluginError)
  {
    #if 0
    // get inputs
    assert(q.input.size() == 2);
    ID pred = q.input[0];
    ID cmp = q.input[1];
    LOG(INFO,"calculating above extatom for predicate " << pred << " and symbol " << cmp);
    const Term& cmpt = registry->terms.getByID(cmp);

    // get query
    assert(q.pattern.size() == 1);
    ID out = q.pattern.front();

    // build set of found targets
    assert(q.interpretation != 0);
    dlvhex::OrdinaryAtomTable::PredicateIterator it, it_end;
    assert(registry != 0);
    for(boost::tie(it, it_end) = registry->ogatoms.getRangeByPredicateID(pred);
        it != it_end; ++it)
    {
      const dlvhex::OrdinaryAtom& oatom = *it;

      // skip ogatoms not present in interpretation
      if( !q.interpretation->getFact(registry->ogatoms.getIDByStorage(oatom).address) )
        continue;

      // the edge predicate must be unary
      assert(oatom.tuple.size() == 2);
      const Term& t = registry->terms.getByID(oatom.tuple[1]);
      if( t.symbol >= cmpt.symbol )
      {
        if( (out.isTerm() && out.isVariableTerm()) ||
            (out == oatom.tuple[1]) )
        {
          Tuple t;
          t.push_back(oatom.tuple[1]);
          a.get().push_back(t);
        }
      }
    }
    #endif
    throw std::runtime_error("todo implement SenseNotArmed1PluginAtom::retrieve");
  }
Ejemplo n.º 7
0
void
AnswerSetsAtom::retrieve(const Query& query, Answer& answer) throw (PluginError)
{
	// Retrieve answer index
	int answerindex = query.input[0].address;

	// check index validity
	if (answerindex < 0 || answerindex >= resultsetCache.size()){
		throw PluginError("An invalid answer handle was passed to atom &answersets");
	}else{
		// Return handles to all answer-sets of the given answer (all integers from 0 to the number of answer-sets minus 1)
		int i = 0;
		for (HexAnswer::iterator it = resultsetCache[answerindex].begin(); it != resultsetCache[answerindex].end(); it++){
			Tuple out;
			out.push_back(ID::termFromInteger(i++));
			answer.get().push_back(out);
		}
	}
}
Ejemplo n.º 8
0
	virtual void retrieve(const Query& q, Answer& a) throw (dlvhex::PluginError)
  {
    // get inputs
    assert(q.input.size() == 3);
    ID preddisarm = q.input[0];
    ID predlook = q.input[1];
    ID time = q.input[2];
    LOG(INFO,"calculating senseNotArmed2 extatom for " << preddisarm << "/" << predlook << "/" << time);

    // get outputs
    assert(q.pattern.size() == 0);

    // check if <preddisarm>(time) and <predlook>(time) part of interpretation
    Tuple tdisarm;
    tdisarm.push_back(preddisarm);
    tdisarm.push_back(time);
    ID iddisarm = registry->ogatoms.getIDByTuple(tdisarm);

    Tuple tlook;
    tlook.push_back(predlook);
    tlook.push_back(time);
    ID idlook = registry->ogatoms.getIDByTuple(tlook);

    if( iddisarm == ID_FAIL || idlook == ID_FAIL )
    {
      // cannot be part of interpretation -> return no tuple as condition not true
      return;
    }

    // check interpretation
    assert(q.interpretation != 0);
    if( q.interpretation->getFact(iddisarm.address) &&
        q.interpretation->getFact(idlook.address) )
    {
      // found both facts
      Tuple t;
      a.get().push_back(t);
    }
  }
Ejemplo n.º 9
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);
			}
		}
	}
}
Ejemplo n.º 10
0
void ConsistencyAtom::retrieve(const Query& query, Answer& answer, NogoodContainerPtr nogoods) throw (PluginError)
{
	Interpretation toCheck;
	RegistryPtr registry = getRegistry();
	std::vector<std::string> expressions;
	std::vector<OrdinaryAtom> sumData;
	int domainMaxValue;
	int domainMinValue;
	bool definedDomain=false;
	std::string globalConstraintName = "";
	std::string globalConstraintValue = "";

	std::pair<Interpretation::TrueBitIterator, Interpretation::TrueBitIterator>
		trueAtoms ;
	InterpretationConstPtr toUse;
	if(query.assigned!=NULL)
	{
		trueAtoms= query.assigned->trueBits();
		toUse=query.assigned;
	}
	else
	{
		toUse=query.interpretation;
		trueAtoms= query.interpretation->trueBits();
	}


	vector<ID> atomIds;
	if(!idSaved)
		storeID(registry);

	// Iterate over all input interpretation
	for (Interpretation::TrueBitIterator it = trueAtoms.first; it != trueAtoms.second; it++) {
		const OrdinaryAtom &atom = toUse->getAtomToBit(it);
		Term name = registry->terms.getByID(atom.tuple[0]);
		if(!query.interpretation->getFact(*it)){
			continue;
		}
		string expr="";

		if (atom.tuple[0]==exprAuxID) {
			expressions.push_back(getExpressionFromID(registry,atom,false));
			ID atomID=registry->ogatoms.getIDByTuple(atom.tuple);
			atomIds.push_back(atomID);
			if(cspGraphLearning && possibleConflictCpVariable.find(atomID)!=possibleConflictCpVariable.end())
			{
				set< Interpretation* > s=possibleConflictCpVariable.at(atomID);
				for( set<Interpretation*>::iterator it=s.begin();it!=s.end();++it)
				{
					toCheck.add(**it);
				}
			}
		}
		else if (atom.tuple[0]==not_exprAuxID) {
			expressions.push_back(getExpressionFromID(registry,atom,true));
			ID atomID=registry->ogatoms.getIDByTuple(atom.tuple);
			atomIds.push_back(atomID);
			// if the atom doesn't contain ASP variables insert all atom that are possible conflict
			if(cspGraphLearning && possibleConflictCpVariable.find(atomID)!=possibleConflictCpVariable.end())
			{
				set< Interpretation* > s=possibleConflictCpVariable.at(atomID);
				for( set<Interpretation*>::iterator it=s.begin();it!=s.end();++it)
				{
					toCheck.add(**it);
				}
			}
		}
		else if (atom.tuple[0]==domainAuxID) {
			definedDomain=true;
			domainMinValue=atom.tuple[1].address;
			domainMaxValue=atom.tuple[2].address;;
		}
		else if (atom.tuple[0]==maximizeAuxID ||atom.tuple[0]==minimizeAuxID) {
			globalConstraintName = name.symbol;
			globalConstraintValue = removeQuotes(registry->terms.getByID(atom.tuple[1]).symbol);
		}
		else { // this predicate received as input to sum aggregate function
			sumData.push_back(atom);
		}
	}

	if(!definedDomain)
		throw dlvhex::PluginError("No domain specified");

//	 Call gecode solver
	GecodeSolver* solver = new GecodeSolver(registry,sumData,domainMinValue, domainMaxValue, globalConstraintName, globalConstraintValue, simpleParser);
	solver->propagate(expressions);

	Gecode::Search::Options opt;
	Gecode::BAB<GecodeSolver> solutions(solver,opt);

	// If there's at least one solution, then data is consistent
	if (solutions.next()) {
		Tuple out;
		answer.get().push_back(out);
		if(cspAnticipateLearning && query.assigned!=NULL)
			anticipateLearning(registry,query.assigned,nogoods,expressions,atomIds,sumData,domainMinValue,domainMaxValue,globalConstraintName,globalConstraintValue,toCheck);
	}
	else if (nogoods != 0){ // otherwise we need to learn IIS from it
		GecodeSolver* otherSolver = new GecodeSolver(registry,sumData, domainMinValue,domainMaxValue, globalConstraintName, globalConstraintValue, simpleParser);
		learningProcessor->learnNogoods(nogoods, expressions, atomIds, otherSolver);
		delete otherSolver;
	}
	delete solver;
}
Ejemplo n.º 11
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
}