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++; } } } }
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); } } }
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); } } } }
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()); } }
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()); } }
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"); }
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); } } }
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); } }
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); } } } }
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; }
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 }