dlvhex
2.5.0
|
00001 /* dlvhex -- Answer-Set Programming with external interfaces. 00002 * Copyright (C) 2005-2007 Roman Schindlauer 00003 * Copyright (C) 2006-2015 Thomas Krennwallner 00004 * Copyright (C) 2009-2016 Peter Schüller 00005 * Copyright (C) 2011-2016 Christoph Redl 00006 * Copyright (C) 2015-2016 Tobias Kaminski 00007 * Copyright (C) 2015-2016 Antonius Weinzierl 00008 * 00009 * This file is part of dlvhex. 00010 * 00011 * dlvhex is free software; you can redistribute it and/or modify it 00012 * under the terms of the GNU Lesser General Public License as 00013 * published by the Free Software Foundation; either version 2.1 of 00014 * the License, or (at your option) any later version. 00015 * 00016 * dlvhex is distributed in the hope that it will be useful, but 00017 * WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with dlvhex; if not, write to the Free Software 00023 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00024 * 02110-1301 USA. 00025 */ 00026 00035 #ifdef HAVE_CONFIG_H 00036 #include "config.h" 00037 #endif // HAVE_CONFIG_H 00038 00039 #ifdef HAVE_MLP 00040 00041 #include "dlvhex2/MLPSolver.h" 00042 00043 DLVHEX_NAMESPACE_BEGIN 00044 00045 MLPSolver::MLPSolver(ProgramCtx& ctx1) 00046 { 00047 printLevel = 0; 00048 nASReturned = 0; 00049 forget = 0; 00050 instSplitting = 0; 00051 totalSizeInstOgatoms=0; 00052 ctx = ctx1; 00053 RegistryPtr R2(new Registry(*ctx.registry()) ); 00054 registrySolver = R2; 00055 DBGLOG(DBG, "[MLPSolver::MLPSolver] constructor finished"); 00056 } 00057 00058 00059 void MLPSolver::dataReset() 00060 { 00061 RegistryPtr R2(new Registry(*ctx.registry() )); 00062 registrySolver = R2; 00063 sTable.clear(); 00064 moduleInstTable.clear(); 00065 A.clear(); 00066 M.reset( new Interpretation( registrySolver )); 00067 path.clear(); 00068 totalSizeInstOgatoms = 0; 00069 instOgatoms.clear(); 00070 } 00071 00072 00073 void MLPSolver::setNASReturned(int n) 00074 { 00075 if ( n>=0 ) { 00076 nASReturned = n; 00077 } 00078 } 00079 00080 00081 void MLPSolver::setForget(int n) 00082 { 00083 if ( n==0 || n==1 ) forget = n; 00084 } 00085 00086 00087 void MLPSolver::setInstSplitting(int n) 00088 { 00089 if ( n==0 || n==1 ) instSplitting = n; 00090 } 00091 00092 00093 void MLPSolver::setPrintLevel(int level) 00094 { 00095 printLevel = level; 00096 } 00097 00098 00099 bool MLPSolver::foundCinPath(const ValueCallsType& C, const std::vector<ValueCallsType>& path, ValueCallsType& CPrev, int& PiSResult) 00100 { // method to found if there exist a PiS in C that also occur in some Cprev in path 00101 bool result = false; 00102 VCAddressIndex::const_iterator itC = C.get<impl::AddressTag>().begin(); 00103 VCAddressIndex::const_iterator itCend = C.get<impl::AddressTag>().end(); 00104 // loop over all value calls in C 00105 while ( itC != itCend ) { 00106 // look over all Cprev in path 00107 std::vector<ValueCallsType>::const_iterator itP = path.begin(); 00108 std::vector<ValueCallsType>::const_iterator itPend = path.end(); 00109 while ( !(itP == itPend) && result == false ) { 00110 ValueCallsType Cprev = *itP; 00111 // *itC contain an index of PiS in moduleInstTable 00112 // now look in the Cprev if there is such PiS 00113 VCElementIndex::const_iterator itCprev = Cprev.get<impl::ElementTag>().find(*itC); 00114 if ( itCprev != Cprev.get<impl::ElementTag>().end() ) { 00115 CPrev = Cprev; 00116 PiSResult = *itC; 00117 result = true; 00118 } 00119 itP++; 00120 } 00121 itC++; 00122 } 00123 return result; 00124 } 00125 00126 00127 int MLPSolver::extractS(int PiS) 00128 { 00129 // PiS is an index to moduleInstTable 00130 const ModuleInst& m = moduleInstTable.get<impl::AddressTag>().at(PiS); 00131 return m.idxS; 00132 } 00133 00134 00135 int MLPSolver::extractPi(int PiS) 00136 { 00137 // PiS is an index to moduleInstTable 00138 const ModuleInst& m = moduleInstTable.get<impl::AddressTag>().at(PiS); 00139 return m.idxModule; 00140 } 00141 00142 00143 bool MLPSolver::isEmptyInterpretation(int S) 00144 { 00145 // S is an index to sTable 00146 const Interpretation& IS = sTable.get<impl::AddressTag>().at(S); 00147 if ( IS.isClear() ) { 00148 DBGLOG(DBG, "[MLPSolver::isEmptyInterpretation] empty interpretation: " << IS); 00149 return true; 00150 } 00151 else { 00152 DBGLOG(DBG, "[MLPSolver::isEmptyInterpretation] not empty interpretation: " << IS); 00153 return false; 00154 } 00155 } 00156 00157 00158 bool MLPSolver::foundNotEmptyInst(const ValueCallsType& C) 00159 { // loop over all PiS inside C, check is the S is not empty 00160 VCAddressIndex::const_iterator itC = C.get<impl::AddressTag>().begin(); 00161 VCAddressIndex::const_iterator itCend = C.get<impl::AddressTag>().end(); 00162 while ( itC != itCend ) { 00163 if ( !isEmptyInterpretation(extractS(*itC)) ) return true; 00164 itC++; 00165 } 00166 return false; 00167 } 00168 00169 00170 void MLPSolver::unionCtoFront(ValueCallsType& C, const ValueCallsType& C2) 00171 { // union C2 to C 00172 // loop over C2 00173 VCAddressIndex::const_iterator itC2 = C2.get<impl::AddressTag>().begin(); 00174 VCAddressIndex::const_iterator itC2end = C2.get<impl::AddressTag>().end(); 00175 while ( itC2 != itC2end ) { 00176 // insert 00177 C.get<impl::ElementTag>().insert(*itC2); 00178 itC2++; 00179 } 00180 } 00181 00182 00183 std::string MLPSolver::getAtomTextFromTuple(const Tuple& tuple) 00184 { 00185 std::stringstream ss; 00186 RawPrinter printer(ss, registrySolver); 00187 Tuple::const_iterator it = tuple.begin(); 00188 printer.print(*it); 00189 std::string predInsideName = ss.str(); 00190 it++; 00191 if( it != tuple.end() ) { 00192 ss << "("; 00193 printer.print(*it); 00194 it++; 00195 while(it != tuple.end()) { 00196 ss << ","; 00197 printer.print(*it); 00198 it++; 00199 } 00200 ss << ")"; 00201 } 00202 return ss.str(); 00203 } 00204 00205 00206 // rewrite ordinary atom, for example p(a) -> m25___p(a) 00207 ID MLPSolver::rewriteOrdinaryAtom(ID oldAtomID, int idxMI) 00208 { 00209 // find the correct table: og/on 00210 OrdinaryAtomTable* tbl; 00211 // if ground atom 00212 if ( oldAtomID.isOrdinaryGroundAtom() ) { 00213 tbl = ®istrySolver->ogatoms; 00214 } 00215 else { // if non-ground atoms 00216 tbl = ®istrySolver->onatoms; 00217 } 00218 // create the new atom (so that we do not rewrite the original one 00219 OrdinaryAtom atomRnew = tbl->getByID(oldAtomID); 00220 // access the predicate name 00221 ID& predR = atomRnew.tuple.front(); 00222 Predicate p = registrySolver->preds.getByID(predR); 00223 // rename the predicate name by <prefix> + <old name> 00224 std::stringstream ss; 00225 ss << "m" << idxMI << MODULEINSTSEPARATOR; 00226 p.symbol = ss.str() + p.symbol; 00227 DBGLOG(DBG, "[MLPSolver::rewriteOrdinaryAtom] " << p.symbol); 00228 // try to locate the new pred name 00229 ID predNew = registrySolver->preds.getIDByString(p.symbol); 00230 DBGLOG(DBG, "[MLPSolver::rewriteOrdinaryAtom] ID predNew = " << predNew); 00231 if ( predNew == ID_FAIL ) { 00232 predNew = registrySolver->preds.storeAndGetID(p); 00233 DBGLOG(DBG, "[MLPSolver::rewriteOrdinaryAtom] ID predNew after FAIL = " << predNew); 00234 } 00235 // rewrite the predicate inside atomRnew 00236 predR = predNew; 00237 DBGLOG(DBG, "[MLPSolver::rewriteOrdinaryAtom] new predR = " << predR); 00238 // replace the atom text 00239 atomRnew.text = getAtomTextFromTuple(atomRnew.tuple); 00240 // try to locate the new atom (the rewritten one) 00241 ID atomFind = tbl->getIDByString(atomRnew.text); 00242 DBGLOG(DBG, "[MLPSolver::rewriteOrdinaryAtom] ID atomFind = " << atomFind); 00243 if (atomFind == ID_FAIL) { 00244 atomFind = tbl->storeAndGetID(atomRnew); 00245 DBGLOG(DBG, "[MLPSolver::rewriteOrdinaryAtom] ID atomFind after FAIL = " << atomFind); 00246 } 00247 return atomFind; 00248 } 00249 00250 00251 // prefix only the input predicates (with PiS) 00252 ID MLPSolver::rewriteModuleAtom(const ModuleAtom& oldAtom, int idxMI) 00253 { 00254 // create the new atom (so that we do not rewrite the original one) 00255 DBGLOG(DBG, "[MLPSolver::rewriteModuleAtom] To be rewritten = " << oldAtom); 00256 ModuleAtom atomRnew = oldAtom; 00257 rewriteTuple(atomRnew.inputs, idxMI); 00258 DBGLOG(DBG, "[MLPSolver::rewriteModuleAtom] After rewriting = " << atomRnew); 00259 ID atomRnewID = registrySolver->matoms.getIDByElement(atomRnew.predicate, atomRnew.inputs, atomRnew.outputAtom); 00260 if ( atomRnewID == ID_FAIL ) { 00261 return registrySolver->matoms.storeAndGetID(atomRnew); 00262 } 00263 return atomRnewID; 00264 } 00265 00266 00267 ID MLPSolver::rewritePredicate(const Predicate& oldPred, int idxMI) 00268 { 00269 // create the new Predicate (so that we do not rewrite the original one) 00270 Predicate predRnew = oldPred; 00271 std::stringstream ss; 00272 ss << "m" << idxMI << MODULEINSTSEPARATOR; 00273 predRnew.symbol = ss.str() + predRnew.symbol; 00274 ID predFind = registrySolver->preds.getIDByString(predRnew.symbol); 00275 DBGLOG(DBG, "[MLPSolver::rewritePredicate] ID predFind = " << predFind); 00276 if (predFind == ID_FAIL) { 00277 predFind = registrySolver->preds.storeAndGetID(predRnew); 00278 DBGLOG(DBG, "[MLPSolver::rewritePredicate] ID predFind after FAIL = " << predFind); 00279 } 00280 return predFind; 00281 } 00282 00283 00284 void MLPSolver::rewriteTuple(Tuple& tuple, int idxMI) 00285 { 00286 Tuple::iterator it = tuple.begin(); 00287 while ( it != tuple.end() ) { 00288 DBGLOG(DBG, "[MLPSolver::rewriteTuple] ID = " << *it); 00289 if ( it->isAtom() || it->isLiteral() ) { 00290 if ( it->isOrdinaryGroundAtom() ) { 00291 DBGLOG(DBG, "[MLPSolver::rewriteTuple] Rewrite ordinary ground atom = " << *it); 00292 if ( it->isLiteral() ) 00293 *it = ID::literalFromAtom(rewriteOrdinaryAtom(*it, idxMI), it->isNaf() ); 00294 else 00295 *it = rewriteOrdinaryAtom(*it, idxMI); 00296 00297 } 00298 else if ( it->isOrdinaryNongroundAtom() ) { 00299 DBGLOG(DBG, "[MLPSolver::rewriteTuple] Rewrite ordinary non ground atom = " << *it ); 00300 if ( it->isLiteral() ) 00301 *it = ID::literalFromAtom( rewriteOrdinaryAtom(*it, idxMI), it->isNaf() ); 00302 else 00303 *it = rewriteOrdinaryAtom(*it, idxMI); 00304 } 00305 else if ( it->isModuleAtom() ) { 00306 DBGLOG(DBG, "[MLPSolver::rewriteTuple] Rewrite module atom = " << *it); 00307 if ( it->isLiteral() ) 00308 *it = ID::literalFromAtom( rewriteModuleAtom(registrySolver->matoms.getByID(*it), idxMI), it->isNaf() ); 00309 else 00310 *it = rewriteModuleAtom(registrySolver->matoms.getByID(*it), idxMI); 00311 } 00312 } 00313 else if ( it->isTerm() ) { 00314 if ( it->isPredicateTerm() ) { 00315 DBGLOG(DBG, "[MLPSolver::rewriteTuple] Rewrite predicate term = " << *it); 00316 *it = rewritePredicate(registrySolver->preds.getByID(*it), idxMI); 00317 } 00318 } 00319 00320 it++; 00321 } 00322 } 00323 00324 00325 // instIdx: refer to the index of Mi/S in the moduleInstTable 00326 // intr: \bM 00327 // intrResult: Mi/S as the result 00328 void MLPSolver::createMiS(int instIdx, const InterpretationPtr& intr, InterpretationPtr& intrResult) 00329 { 00330 intrResult->clear(); 00331 const Tuple& tuple = getOgatomsInInst(instIdx); 00332 Tuple::const_iterator it = tuple.begin(); 00333 while ( it != tuple.end() ) { 00334 if ( intr->getFact((*it).address) ) { 00335 intrResult->setFact((*it).address); 00336 } 00337 it++; 00338 } 00339 } 00340 00341 00342 // part of the rewrite method 00343 // look for a module atom in the body of the rules 00344 // if the module atom is exist in the A replace with the outputAtom (prefixed) 00345 // add o with prefix PjT as fact 00346 void MLPSolver::replacedModuleAtoms(int instIdx, InterpretationPtr& edb, Tuple& idb) 00347 { 00348 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] idb input = " << printvector(idb)); 00349 00350 // iterate over rules, check if there is a module atoms there 00351 Tuple::iterator itR = idb.begin(); 00352 while ( itR != idb.end() ) { 00353 assert( itR->isRule() == true ); 00354 // check if the rule contain at least a module atom 00355 if ( itR->doesRuleContainModatoms() == true ) { 00356 const Rule& r = registrySolver->rules.getByID(*itR); 00357 Rule rNew = r; 00358 // iterate over the body of rules 00359 Tuple::iterator itB = rNew.body.begin(); 00360 while ( itB != rNew.body.end() ) { 00361 if ( (*itB).isModuleAtom() && A.size() > instIdx ) { 00362 // find the module atom in the AiS 00363 IDSElementIndex::iterator itE = A.at(instIdx).get<impl::ElementTag>().find(*itB); 00364 if ( itE != A.at(instIdx).get<impl::ElementTag>().end() ) { 00365 // if found 00366 // create the PjT 00367 // first, get the module atom 00368 const ModuleAtom& ma = registrySolver->matoms.getByID(*itB); 00369 // create the interpretation Mi/S 00370 InterpretationPtr newM(new Interpretation( registrySolver )); 00371 createMiS(instIdx, M, newM); 00372 // get the module Pj using the predicate from the module input, get the formal input 00373 const Module& m = registrySolver->moduleTable.getModuleByName(ma.actualModuleName); 00374 const Tuple& formalInputs = registrySolver->inputList.at(m.inputList); 00375 Tuple restrictT; 00376 Tuple newT; 00377 // Mi/S restrict by p rename to q 00378 restrictionAndRenaming( *(newM), ma.inputs, formalInputs, restrictT, newT); 00379 Interpretation intrNewT; 00380 createInterpretationFromTuple(newT, intrNewT); 00381 int idxPjT = addOrGetModuleIstantiation(m.moduleName, intrNewT); 00382 00383 // get the outputAtom 00384 ID outputAtom = ma.outputAtom; 00385 OrdinaryAtomTable* tbl; 00386 if ( outputAtom.isOrdinaryGroundAtom() ) { 00387 tbl = ®istrySolver->ogatoms; 00388 } 00389 else 00390 tbl = ®istrySolver->onatoms; 00391 const OrdinaryAtom& atomR = tbl->getByID(outputAtom); 00392 // create the new one 00393 OrdinaryAtom newOutputAtom = atomR; 00394 ID& predR = newOutputAtom.tuple.front(); 00395 Predicate p = registrySolver->preds.getByID(predR); 00396 // remove the p1__ 00397 p.symbol = p.symbol.substr( p.symbol.find(MODULEPREFIXSEPARATOR) + 2); 00398 // prefix it with m PjT___ + p2__ 00399 std::stringstream ss; 00400 ss << "m" << idxPjT << MODULEINSTSEPARATOR << m.moduleName << MODULEPREFIXSEPARATOR << p.symbol; 00401 p.symbol = ss.str(); 00402 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] p.symbol new = " << p.symbol); 00403 // try to locate the new pred name 00404 ID predNew = registrySolver->preds.getIDByString(p.symbol); 00405 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] ID predNew = " << predNew); 00406 if ( predNew == ID_FAIL ) { 00407 predNew = registrySolver->preds.storeAndGetID(p); 00408 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] ID predNew after FAIL = " << predNew); 00409 } 00410 // rewrite the predicate inside atomRnew 00411 predR = predNew; 00412 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] new predR = " << predR); 00413 // replace the atom text 00414 newOutputAtom.text = getAtomTextFromTuple(newOutputAtom.tuple); 00415 // try to locate the new atom (the rewritten one) 00416 ID atomFind = tbl->getIDByString(newOutputAtom.text); 00417 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] ID atomFind = " << atomFind); 00418 if (atomFind == ID_FAIL) { 00419 atomFind = tbl->storeAndGetID(newOutputAtom); 00420 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] ID atomFind after FAIL = " << atomFind); 00421 } 00422 00423 // replace the module atom with this newOutputAtom 00424 // *itB = atomFind; 00425 *itB = ID::literalFromAtom( atomFind, itB->isNaf() ); 00426 00427 // put Mj/T as a facts if not nil 00428 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] idxPjT = " << idxPjT); 00429 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] M = " << *M); 00430 InterpretationPtr MjT(new Interpretation()); 00431 createMiS(idxPjT, M, MjT); 00432 Interpretation::Storage MjTAtoms = MjT->getStorage(); 00433 Interpretation::Storage::enumerator itMjTAtoms = MjTAtoms.first(); 00434 while ( itMjTAtoms != MjTAtoms.end() ) { 00435 // if the atoms is set 00436 const OrdinaryAtom& atomGround = registrySolver->ogatoms.getByAddress(*itMjTAtoms); 00437 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] atomGround inspected = " << atomGround); 00438 if (atomGround.tuple.front() == newOutputAtom.tuple.front() ) { 00439 // if the predicate = newOutputAtom, if yes: edb->setFact(*itMjTAtoms); 00440 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] before set fact = " << *edb); 00441 edb->setFact(*itMjTAtoms); 00442 DBGLOG(DBG, "[MLPSolver::replacedModuleAtoms] after set fact = " << *edb); 00443 } 00444 itMjTAtoms++; 00445 } 00446 } 00447 } 00448 itB++; 00449 } 00450 // TODO: optimize the bool (and the loop) here 00451 // check if there is still a module atom left 00452 bool stillAModuleAtom = false; 00453 itB = rNew.body.begin(); 00454 while ( itB != rNew.body.end() && stillAModuleAtom == false) { 00455 if ( (*itB).isAtom() || (*itB).isLiteral() ) { 00456 if ( (*itB).isModuleAtom() ) stillAModuleAtom = true; 00457 } 00458 itB++; 00459 } 00460 // if no module atom left, take out the property rule mod atoms 00461 if (stillAModuleAtom == false) { 00462 rNew.kind &= ID::PROPERTY_RULE_UNMODATOMS; 00463 } 00464 ID rNewID = registrySolver->rules.getIDByElement(rNew); 00465 if ( rNewID == ID_FAIL ) { 00466 rNewID = registrySolver->storeRule(rNew); 00467 } 00468 // collect it in the idbResult 00469 *itR = rNewID; 00470 } 00471 itR++; 00472 } 00473 } 00474 00475 00476 void MLPSolver::rewrite(const ValueCallsType& C, InterpretationPtr& edbResult, Tuple& idbResult) 00477 { 00478 DBGLOG(DBG, "[MLPSolver::rewrite] enter "); 00479 // prepare edbResult 00480 edbResult.reset(new Interpretation( registrySolver ) ); 00481 // prepare idbResult 00482 idbResult.clear(); 00483 // loop over C 00484 VCAddressIndex::const_iterator itC = C.get<impl::AddressTag>().begin(); 00485 VCAddressIndex::const_iterator itCend = C.get<impl::AddressTag>().end(); 00486 while ( itC != itCend ) { 00487 // check if idx *itC has been made in Top 00488 bool usingTop = false; 00489 if ( instSplitting == 1 && *itC < Top.size() ) { 00490 // if yes, 00491 IDSet top = Top.at(*itC); 00492 if ( containFin(A, *itC) ) { 00493 // add nothing 00494 usingTop = true; 00495 } else 00496 if (top.size()>0 /*|| containFin(A, *itC) */ ) { 00497 Tuple idbResultTemp; 00498 IDSetToTuple(top, idbResultTemp); 00499 idbResult.insert(idbResult.end(), idbResultTemp.begin(), idbResultTemp.end()); 00500 usingTop = true; 00501 DBGLOG(DBG, "[MLPSolver::rewrite] Get top["<< *itC <<"]: "); 00502 if ( printProgramInformation == true ) 00503 printIdb(registrySolver, idbResult); 00504 } 00505 else { 00506 DBGLOG(DBG, "Interpretation M: " << *M); 00507 DBGLOG(DBG, "Top[" << *itC << "].size = 0--"); 00508 } 00509 } 00510 if ( usingTop == false ) { 00511 // get the module idx and idx S 00512 int idxM = extractPi(*itC); 00513 int idxS = extractS(*itC); 00514 const Module& m = registrySolver->moduleTable.getByAddress(idxM); 00515 // rewrite the edb, get the edb pointed by m.edb 00516 DBGLOG(DBG, "[MLPSolver::rewrite] rewrite edb "); 00517 InterpretationPtr edbTemp( new Interpretation(registrySolver) ); 00518 edbTemp->add(*ctx.edbList.at(m.edb)); 00519 // add S (from the instantiation) to the edb 00520 edbTemp->add( sTable.get<impl::AddressTag>().at(idxS) ); 00521 // iterate over edb 00522 Interpretation::Storage bits = edbTemp->getStorage(); 00523 Interpretation::Storage::enumerator it = bits.first(); 00524 while ( it!=bits.end() ) { 00525 // get the atom that is pointed by *it (element of the edb) 00526 ID atomRID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it); 00527 // rewrite the atomR, resulting in a new atom with prefixed predicate name, change: the registry in ctxSolver 00528 ID atomRewrite = rewriteOrdinaryAtom(atomRID, *itC); 00529 edbResult->setFact(atomRewrite.address); 00530 it++; 00531 } 00532 00533 // rewrite the idb 00534 DBGLOG(DBG, "[MLPSolver::rewrite] rewrite idb"); 00535 Tuple idbTemp; 00536 idbTemp.insert(idbTemp.end(), ctx.idbList.at(m.idb).begin(), ctx.idbList.at(m.idb).end()); 00537 // loop over the rules 00538 Tuple::iterator itT = idbTemp.begin(); 00539 while (itT != idbTemp.end()) { 00540 const Rule& r = registrySolver->rules.getByID(*itT); 00541 Rule rNew = r; 00542 // for each rule: body and head, rewrite it 00543 rewriteTuple(rNew.head, *itC); 00544 rewriteTuple(rNew.body, *itC); 00545 00546 ID rNewID = registrySolver->rules.getIDByElement(rNew); 00547 if ( rNewID == ID_FAIL ) { 00548 rNewID = registrySolver->storeRule(rNew); 00549 } 00550 // collect it in the idbResult 00551 idbResult.push_back(rNewID); 00552 itT++; 00553 } 00554 } 00555 00556 // put Mi/S as a facts if not nil 00557 DBGLOG(DBG, "[MLPSolver::rewrite] Mi/S as a facts if not nil"); 00558 InterpretationPtr MiS(new Interpretation() ); 00559 createMiS(*itC, M, MiS); 00560 Interpretation::Storage MiSAtoms = MiS->getStorage(); 00561 Interpretation::Storage::enumerator itMiSAtoms = MiSAtoms.first(); 00562 while ( itMiSAtoms != MiSAtoms.end() ) { 00563 edbResult->setFact(*itMiSAtoms); 00564 itMiSAtoms++; 00565 } 00566 00567 // inpect module atoms, replace with o, remove module rule property 00568 // add o as facts prefixed by Pj/T 00569 DBGLOG(DBG, "[MLPSolver::rewrite] replaced module atoms"); 00570 replacedModuleAtoms( *itC, edbResult, idbResult); 00571 00572 itC++; 00573 } 00574 00575 00576 } 00577 00578 bool MLPSolver::isOrdinary(const Tuple& idb) 00579 { 00580 Tuple::const_iterator itT = idb.begin(); 00581 while ( itT != idb.end() ) { 00582 assert( itT->isRule() == true ); 00583 // check if the rule contain at least a module atom 00584 if ( itT->doesRuleContainModatoms() == true ) { 00585 return false; 00586 } 00587 itT++; 00588 } 00589 return true; 00590 } 00591 00592 00593 std::vector<int> MLPSolver::foundMainModules() 00594 { 00595 std::vector<int> result; 00596 ModuleTable::AddressIterator itBegin, itEnd; 00597 boost::tie(itBegin, itEnd) = registrySolver->moduleTable.getAllByAddress(); 00598 int ctr = 0; 00599 while ( itBegin != itEnd ) { 00600 Module module = *itBegin; 00601 if ( registrySolver->inputList.at(module.inputList).size() == 0 ) { 00602 result.push_back(ctr); 00603 } 00604 itBegin++; 00605 ctr++; 00606 } 00607 DBGLOG(DBG, "[MLPSolver::foundMainModules] finished"); 00608 return result; 00609 } 00610 00611 00612 // to be used only in the beginning 00613 MLPSolver::ValueCallsType MLPSolver::createValueCallsMainModule(int idxModule) 00614 { 00615 // create a new, empty interpretation s 00616 InterpretationType s(registrySolver); 00617 // find [] in the sTable 00618 MLPSolver::ITElementIndex::iterator itIndex = sTable.get<impl::ElementTag>().find(s); 00619 // if it is not exist, insert [] into the sTable 00620 if ( itIndex == sTable.get<impl::ElementTag>().end() ) { 00621 DBGLOG(DBG, "[MLPSolver::createValueCallsMainModule] inserting empty interpretation..."); 00622 sTable.get<impl::ElementTag>().insert(s); 00623 } 00624 // get the [] 00625 MLPSolver::ITElementIndex::iterator itS = sTable.get<impl::ElementTag>().find(s); 00626 // set m.idxModule and m.idxS 00627 ModuleInst PiS(idxModule, sTable.project<impl::AddressTag>(itS) - sTable.get<impl::AddressTag>().begin() ); 00628 00629 DBGLOG(DBG, "[MLPSolver::createValueCallsMainModule] PiS.idxModule = " << PiS.idxModule); 00630 DBGLOG(DBG, "[MLPSolver::createValueCallsMainModule] PiS.idxS = " << PiS.idxS); 00631 00632 moduleInstTable.get<impl::ElementTag>().insert( PiS ); 00633 MLPSolver::MIElementIndex::iterator itM = moduleInstTable.get<impl::ElementTag>().find( boost::make_tuple(PiS.idxModule, PiS.idxS) ); 00634 int idxMI = moduleInstTable.project<impl::AddressTag>( itM ) - moduleInstTable.get<impl::AddressTag>().begin(); 00635 DBGLOG( DBG, "[MLPSolver::createValueCallsMainModule] store PiS at index = " << idxMI ); 00636 00637 ValueCallsType C; 00638 C.push_back(idxMI); 00639 return C; 00640 } 00641 00642 00643 void MLPSolver::assignFin(IDSet& t) 00644 { 00645 t.clear(); 00646 t.get<impl::ElementTag>().insert(ID_FAIL); 00647 } 00648 00649 00650 void MLPSolver::findAllModulesAtom(const Tuple& newRules, Tuple& result) 00651 { 00652 result.clear(); 00653 DBGLOG(DBG, "[MLPSolver::findAllModulesAtom] enter"); 00654 Tuple::const_iterator it = newRules.begin(); 00655 while ( it != newRules.end() ) { 00656 if ( it->doesRuleContainModatoms() == true ) { 00657 // get the rule only if it contains module atoms 00658 const Rule& r = registrySolver->rules.getByID(*it); 00659 // iterate over body, assume that the module atom only exist in the body 00660 Tuple::const_iterator lit = r.body.begin(); 00661 while ( lit != r.body.end() ) { 00662 if ( lit->isModuleAtom() ) { 00663 result.push_back(*lit); 00664 DBGLOG(DBG, "[MLPSolver::findAllModulesAtom] push_back: " << *lit); 00665 } 00666 lit++; 00667 } 00668 } 00669 it++; 00670 } 00671 } 00672 00673 00674 ID MLPSolver::getPredIDFromAtomID(const ID& atomID) 00675 { 00676 assert( atomID.isAtom() || (atomID).isLiteral() ); 00677 if ( atomID.isOrdinaryGroundAtom() ) { 00678 const OrdinaryAtom& atom = registrySolver->ogatoms.getByID(atomID); 00679 return atom.tuple.front(); 00680 } 00681 else if ( atomID.isOrdinaryNongroundAtom() ) { 00682 const OrdinaryAtom& atom = registrySolver->onatoms.getByID(atomID); 00683 return atom.tuple.front(); 00684 } 00685 return ID_FAIL; 00686 } 00687 00688 00689 // look if in the tuple, contain an atom with the same predicate name 00690 // as in id 00691 bool MLPSolver::containsPredName(const Tuple& tuple, const ID& id) 00692 { 00693 Tuple::const_iterator itRH = tuple.begin(); 00694 while ( itRH != tuple.end() ) { 00695 // *itRH = id of an ordinary atom 00696 if ( (*itRH).isAtom() ) { 00697 if ( id == getPredIDFromAtomID(*itRH) ) return true; 00698 } 00699 itRH++; 00700 } 00701 return false; 00702 } 00703 00704 00705 // predicate: predicate to be searched for 00706 // rules: the base rule to inspect 00707 // predsSearched: list of predicate searched so far 00708 // rules result: ID of rule that has been the result so far 00709 void MLPSolver::collectAllRulesDefined(ID predicate, const Tuple& rules, Tuple& predsSearched, Tuple& rulesResult) 00710 { 00711 DBGLOG(DBG, "[MLPSolver::collectAllRulesDefined] enter, to find pred: " << predicate); 00712 Tuple::iterator location = std::find(predsSearched.begin(), predsSearched.end(), predicate); 00713 // if not found, push_back this predicate; if found do nothing 00714 if ( location == predsSearched.end() ) { 00715 predsSearched.push_back(predicate); 00716 // look for rule in rules that defined this predicate 00717 Tuple::const_iterator it = rules.begin(); 00718 while ( it != rules.end() ) { 00719 const Rule& r = registrySolver->rules.getByID(*it); 00720 if ( containsPredName(r.head, predicate) ) { 00721 // if this rule defined the predicate, 00722 // look into the result, if not found, push it; 00723 location = std::find(rulesResult.begin(), rulesResult.end(), *it); 00724 if ( location == rulesResult.end() ) { 00725 rulesResult.push_back(*it); 00726 } 00727 Tuple::const_iterator itB = r.body.begin(); 00728 while ( itB != r.body.end() ) { 00729 // search for the predicate in the body 00730 OrdinaryAtomTable* tbl; 00731 if ( itB->isOrdinaryAtom() ) { 00732 if (itB->isOrdinaryGroundAtom() ) { 00733 tbl = ®istrySolver->ogatoms; 00734 } 00735 else { 00736 tbl = ®istrySolver->onatoms; 00737 } 00738 const OrdinaryAtom& oa = tbl->getByID(*itB); 00739 collectAllRulesDefined(oa.tuple.front(), rules, predsSearched, rulesResult); 00740 } 00741 else { 00742 DBGLOG(DBG, "[MLPSolver::collectAllRulesDefined] found not an Ordinary atom: " << *itB); 00743 } 00744 *itB++; 00745 } 00746 itB = r.head.begin(); 00747 while ( itB != r.head.end() ) { 00748 // search for the predicate in the body 00749 OrdinaryAtomTable* tbl; 00750 if ( itB->isOrdinaryAtom() ) { 00751 if (itB->isOrdinaryGroundAtom() ) { 00752 tbl = ®istrySolver->ogatoms; 00753 } 00754 else { 00755 tbl = ®istrySolver->onatoms; 00756 } 00757 const OrdinaryAtom& oa = tbl->getByID(*itB); 00758 collectAllRulesDefined(oa.tuple.front(), rules, predsSearched, rulesResult); 00759 } 00760 else { 00761 DBGLOG(DBG, "[MLPSolver::collectAllRulesDefined] found not an Ordinary atom: " << *itB); 00762 } 00763 *itB++; 00764 } 00765 } 00766 it++; 00767 } 00768 } 00769 } 00770 00771 00772 // test if the input preds of this moduleAtom are all prepared 00773 bool MLPSolver::allPrepared(const ID& moduleAtom, const Tuple& rules) 00774 { 00775 DBGLOG(DBG, "[MLPSolver::allPrepared] enter with module atom: " << moduleAtom); 00776 const ModuleAtom& m = registrySolver->matoms.getByID(moduleAtom); 00777 00778 Tuple predsSearched; 00779 Tuple result; 00780 Tuple::const_iterator itPred = m.inputs.begin(); 00781 // iterate over the input preds 00782 while ( itPred != m.inputs.end() ) { 00783 // collect all rules that defined this input 00784 collectAllRulesDefined(*itPred, rules, predsSearched, result); 00785 itPred++; 00786 } 00787 // iterate over the resulting rules 00788 Tuple::iterator itRules = result.begin(); 00789 while ( itRules != result.end() ) { 00790 if ( itRules->doesRuleContainModatoms() == true ) return false; 00791 itRules++; 00792 } 00793 return true; 00794 } 00795 00796 00797 // looking for which module atoms has the smallest ill 00798 ID MLPSolver::smallestILL(const Tuple& newRules) 00799 { 00800 DBGLOG(DBG, "[MLPSolver::smallestILL] enter to find the smallest ILL in: "); 00801 if ( printProgramInformation == true ) printIdb(registrySolver, newRules); 00802 00803 Tuple modAtoms; 00804 findAllModulesAtom(newRules, modAtoms); 00805 Tuple::iterator it = modAtoms.begin(); 00806 while ( it != modAtoms.end() ) { 00807 if ( allPrepared(*it, newRules) ) { 00808 return *it; 00809 } 00810 it++; 00811 } 00812 return ID_FAIL; 00813 } 00814 00815 00816 bool MLPSolver::defined(const Tuple& preds, const Tuple& ruleHead) 00817 { 00818 DBGLOG(DBG, "[MLPSolver::defined] enter"); 00819 Tuple::const_iterator itPred = preds.begin(); 00820 while ( itPred != preds.end() ) { 00821 // *itPred = the predicate names (yes the names only, the ID is belong to term predicate) 00822 if ( containsPredName(ruleHead, *itPred) == true ) return true; 00823 itPred++; 00824 00825 } 00826 return false; 00827 } 00828 00829 00830 void MLPSolver::addHeadOfModuleAtom(const Tuple& rules, IDSet& predsForbid, IDSet& rulesForbid) 00831 { 00832 Tuple::const_iterator it = rules.begin(); 00833 while ( it != rules.end() ) { 00834 if ( it->doesRuleContainModatoms() == true ) { 00835 // add rule id to rulesForbid 00836 rulesForbid.get<impl::ElementTag>().insert(*it); 00837 const Rule& r = registrySolver->rules.getByID(*it); 00838 addTuplePredNameToIDSet(r.head, predsForbid); 00839 } 00840 it++; 00841 } 00842 } 00843 00844 00845 // from tuple, get the atom, get the predicate name, locate the id 00846 // add the ID into idSet 00847 void MLPSolver::addTuplePredNameToIDSet(const Tuple& tuple, IDSet& idSet) 00848 { 00849 Tuple::const_iterator it = tuple.begin(); 00850 while ( it != tuple.end() ) { 00851 if ( (*it).isAtom() || (*it).isLiteral() ) 00852 idSet.get<impl::ElementTag>().insert( getPredIDFromAtomID(*it) ); 00853 it++; 00854 } 00855 } 00856 00857 00858 bool MLPSolver::tupleContainPredNameIDSet(const Tuple& tuple, const IDSet& idset) 00859 { 00860 Tuple::const_iterator it = tuple.begin(); 00861 while ( it != tuple.end() ) { 00862 DBGLOG(DBG, "[MLPSolver::tupleContainPredNameIDSet] id on inspection: " << *it); 00863 if ( (*it).isAtom() || (*it).isLiteral() ) { 00864 if ( containID( getPredIDFromAtomID(*it) , idset) == true ) return true; 00865 DBGLOG(DBG, "[MLPSolver::tupleContainPredNameIDSet] is an atom or literal"); 00866 } 00867 else { 00868 DBGLOG(DBG, "[MLPSolver::tupleContainPredNameIDSet] is not an atom or literal"); 00869 } 00870 it++; 00871 } 00872 return false; 00873 } 00874 00875 00876 bool MLPSolver::containID(ID id, const IDSet& idSet) 00877 { 00878 MLPSolver::IDSElementIndex::const_iterator it = idSet.get<impl::ElementTag>().find(id); 00879 if ( it != idSet.get<impl::ElementTag>().end() ) return true; 00880 else return false; 00881 } 00882 00883 00884 void MLPSolver::addHeadPredsForbid(const Tuple& rules, IDSet& predsForbid, IDSet& rulesForbid) 00885 { 00886 bool stop = false; 00887 while ( stop == false ) { 00888 stop = true; 00889 Tuple::const_iterator it = rules.begin(); 00890 while ( it != rules.end() ) { 00891 // if the rule is not contained in rulesForbid, inspect: 00892 if ( containID(*it, rulesForbid) == false ) { 00893 const Rule& r = registrySolver->rules.getByID(*it); 00894 // if the body contains pred forbid 00895 DBGLOG(DBG, "[MLPSolver::addHeadPredsForbid] rules on inspection: " << r); 00896 if ( tupleContainPredNameIDSet(r.body, predsForbid) == true ) { 00897 addTuplePredNameToIDSet(r.head, predsForbid); 00898 rulesForbid.get<impl::ElementTag>().insert(*it); 00899 stop = false; 00900 } 00901 // if disjunctive head 00902 if ( r.head.size()>1) { 00903 addTuplePredNameToIDSet(r.head, predsForbid); 00904 rulesForbid.get<impl::ElementTag>().insert(*it); 00905 stop = false; 00906 } 00907 } 00908 it++; 00909 } 00910 } 00911 } 00912 00913 00914 void MLPSolver::IDSetToTuple(const IDSet& idSet, Tuple& result) 00915 { 00916 result.clear(); 00917 MLPSolver::IDSAddressIndex::const_iterator it = idSet.get<impl::AddressTag>().begin(); 00918 while ( it != idSet.get<impl::AddressTag>().end() ) { 00919 result.push_back(*it); 00920 it++; 00921 } 00922 } 00923 00924 00925 void MLPSolver::collectLargestBottom(const ModuleAtom& moduleAtom, const Tuple& rulesSource, Tuple& bottom, Tuple& top) 00926 { 00927 DBGLOG(DBG, "[MLPSolver::collectLargestBottom] enter"); 00928 // first, get the bottom of input splitting set 00929 bottom.clear(); 00930 collectBottom(moduleAtom, rulesSource, bottom); 00931 Tuple rules; 00932 // rulesSource - bottom = rules 00933 tupleMinus(rulesSource, bottom, rules); 00934 00935 // collect rules forbid 00936 IDSet predsForbid; 00937 IDSet rulesForbid; 00938 // the head of the rule that contain module atom in the body is forbidden 00939 addHeadOfModuleAtom(rules, predsForbid, rulesForbid); 00940 00941 if ( printProgramInformation == true ) { 00942 DBGLOG(DBG, "[MLPSolver::collectLargestBottom] after addHeadOfModuleAtom, predsForbid: "); 00943 Tuple predsForbidTuple; 00944 IDSetToTuple(predsForbid, predsForbidTuple); 00945 printIdb(registrySolver, predsForbidTuple); 00946 00947 DBGLOG(DBG, "[MLPSolver::collectLargestBottom] after addHeadOfModuleAtom, rulesForbid: "); 00948 Tuple rulesForbidTuple; 00949 IDSetToTuple(rulesForbid, rulesForbidTuple); 00950 printIdb(registrySolver, rulesForbidTuple); 00951 } 00952 // if there is something that is forbidden 00953 if ( predsForbid.size() > 0 ) { 00954 addHeadPredsForbid(rules, predsForbid, rulesForbid); 00955 DBGLOG(DBG, "[MLPSolver::collectLargestBottom] after addHeadPredsForbid, rulesForbid: "); 00956 if ( printProgramInformation == true ) { 00957 Tuple rulesForbidTuple; 00958 IDSetToTuple(rulesForbid, rulesForbidTuple); 00959 printIdb(registrySolver, rulesForbidTuple); 00960 } 00961 } 00962 // substract rules forbid from the original rules 00963 Tuple::const_iterator it = rules.begin(); 00964 while ( it != rules.end() ) { 00965 if ( containID(*it, rulesForbid) == false ) 00966 bottom.push_back(*it); 00967 it++; 00968 } 00969 IDSetToTuple(rulesForbid, top); 00970 } 00971 00972 00973 void MLPSolver::tupleMinus(const Tuple& source, const Tuple& minusTuple, Tuple& result) 00974 { 00975 DBGLOG(DBG, "[MLPSolver::tupleMinus] enter"); 00976 IDSet temp; 00977 // insert into one ID set 00978 Tuple::const_iterator it = minusTuple.begin(); 00979 while ( it != minusTuple.end() ) { 00980 temp.get<impl::ElementTag>().insert(*it); 00981 it++; 00982 } 00983 // loop over source 00984 it = source.begin(); 00985 while ( it != source.end() ) { 00986 // if not in minusTuple, put in the result 00987 if ( ! containID(*it, temp) ) result.push_back(*it); 00988 it++; 00989 } 00990 } 00991 00992 00993 // get the bottom of input splitting set 00994 void MLPSolver::collectBottom(const ModuleAtom& moduleAtom, const Tuple& rules, Tuple& result) 00995 { 00996 DBGLOG(DBG, "[MLPSolver::collectBottom] enter"); 00997 result.clear(); 00998 Tuple predsSearched; 00999 Tuple::const_iterator itPred = moduleAtom.inputs.begin(); 01000 while ( itPred != moduleAtom.inputs.end() ) { 01001 collectAllRulesDefined(*itPred, rules, predsSearched, result); 01002 itPred++; 01003 } 01004 } 01005 01006 01007 // actualInputs: Tuple of predicate name (predicate term) in the module atom (caller) 01008 // formalInputs: Tuple of predicate name (predicate term) in the module list (module header) 01009 void MLPSolver::restrictionAndRenaming(const Interpretation& intr, const Tuple& actualInputs, const Tuple& formalInputs, Tuple& resultRestriction, Tuple& resultRenaming) 01010 { 01011 DBGLOG(DBG,"[MLPSolver::restrictionAndRenaming] enter "); 01012 resultRestriction.clear(); 01013 resultRenaming.clear(); 01014 if ( intr.isClear() ) { 01015 return; 01016 } 01017 // collect all of the atoms in the interpretation 01018 Interpretation::Storage bits = intr.getStorage(); 01019 Interpretation::Storage::enumerator it = bits.first(); 01020 while ( it!=bits.end() ) { 01021 const OrdinaryAtom& atomR = registrySolver->ogatoms.getByAddress(*it); 01022 DBGLOG(DBG,"[MLPSolver::restrictionAndRenaming] atom in the interpretation: " << atomR); 01023 // get the predicate name of the atom 01024 ID predName = atomR.tuple.front(); 01025 // try to find in the actual inputs restriction 01026 Tuple::const_iterator itA = actualInputs.begin(); 01027 bool found = false; 01028 int ctr = 0; 01029 while ( itA != actualInputs.end() && found == false) { 01030 if (*itA == predName) { 01031 // if found in the actual input restriction 01032 resultRestriction.push_back(registrySolver->ogatoms.getIDByString(atomR.text)); 01033 OrdinaryAtom atomRnew = atomR; 01034 DBGLOG(DBG, "[MLPSolver::restrictionAndRenaming] atomR: " << atomR); 01035 DBGLOG(DBG, "[MLPSolver::restrictionAndRenaming] atomRnew: " << atomRnew); 01036 // rename! 01037 atomRnew.tuple.front() = formalInputs.at(ctr); 01038 atomRnew.text = getAtomTextFromTuple(atomRnew.tuple); 01039 DBGLOG(DBG, "[MLPSolver::restrictionAndRenaming] atomRnew after renaming: " << atomRnew); 01040 // store in the ogatoms 01041 ID id = registrySolver->ogatoms.getIDByTuple(atomRnew.tuple); 01042 DBGLOG(DBG, "[MLPSolver::restrictionAndRenaming] id found: " << id); 01043 if ( id == ID_FAIL ) { 01044 id = registrySolver->ogatoms.storeAndGetID(atomRnew); 01045 DBGLOG(DBG, "[MLPSolver::restrictionAndRenaming] id after storing: " << id); 01046 } 01047 resultRenaming.push_back(id); 01048 found = true; 01049 } 01050 itA++; 01051 ctr++; 01052 } 01053 it++; 01054 } 01055 } 01056 01057 01058 void MLPSolver::createInterpretationFromTuple(const Tuple& tuple, Interpretation& result) 01059 { 01060 result.setRegistry(registrySolver); 01061 result.clear(); 01062 // iterate over the tuple of fact, create a new interpretation s 01063 Tuple::const_iterator it = tuple.begin(); 01064 while ( it != tuple.end() ) { 01065 result.setFact((*it).address); 01066 it++; 01067 } 01068 } 01069 01070 01071 int MLPSolver::addOrGetModuleIstantiation(const std::string& moduleName, const Interpretation& s) 01072 { 01073 DBGLOG(DBG, "[MLPSolver::addOrGetModuleIstantiation] got interpretation: " << s); 01074 01075 // look up s in the sTable 01076 MLPSolver::ITElementIndex::iterator itIndex = sTable.get<impl::ElementTag>().find(s); 01077 if ( itIndex == sTable.get<impl::ElementTag>().end() ) { 01078 sTable.get<impl::ElementTag>().insert(s); 01079 DBGLOG(DBG, "[MLPSolver::addOrGetModuleIstantiation] insert into sTable: " << s); 01080 } 01081 MLPSolver::ITElementIndex::iterator itS = sTable.get<impl::ElementTag>().find(s); 01082 01083 // get the module index 01084 int idxModule = registrySolver->moduleTable.getAddressByName(moduleName); 01085 ModuleInst PiS(idxModule, sTable.project<impl::AddressTag>(itS) - sTable.get<impl::AddressTag>().begin() ); 01086 01087 DBGLOG(DBG, "[MLPSolver::addOrGetModuleIstantiation] PiS.idxModule = " << PiS.idxModule); 01088 DBGLOG(DBG, "[MLPSolver::addOrGetModuleIstantiation] PiS.idxS = " << PiS.idxS); 01089 01090 // try to locate the module instantiation => idxModule and idxS 01091 MLPSolver::MIElementIndex::iterator itMI = moduleInstTable.get<impl::ElementTag>().find( boost::make_tuple(PiS.idxModule, PiS.idxS) ); 01092 if ( itMI == moduleInstTable.get<impl::ElementTag>().end() ) { 01093 // if not found, insert 01094 moduleInstTable.get<impl::ElementTag>().insert( PiS ); 01095 } 01096 itMI = moduleInstTable.get<impl::ElementTag>().find( boost::make_tuple(PiS.idxModule, PiS.idxS) ); 01097 int idxMI = moduleInstTable.project<impl::AddressTag>( itMI ) - moduleInstTable.get<impl::AddressTag>().begin(); 01098 DBGLOG(DBG, "[MLPSolver::addOrGetModuleIstantiation] return value idxMI = " << idxMI); 01099 return idxMI; 01100 } 01101 01102 01103 // resize A if the size <= idxPjT 01104 void MLPSolver::resizeIfNeededA(int idxPjT) 01105 { 01106 if (A.size() <= idxPjT) { 01107 A.resize(idxPjT+1); 01108 } 01109 } 01110 01111 01112 // we treat Fin as ID_FAIL 01113 bool MLPSolver::containFin(const std::vector<IDSet>& VectorOfIDSet, int idxPjT) 01114 { 01115 IDSet Ai = VectorOfIDSet.at(idxPjT); 01116 MLPSolver::IDSElementIndex::iterator itAi = Ai.get<impl::ElementTag>().find( ID_FAIL ); 01117 if ( itAi == Ai.get<impl::ElementTag>().end() ) return false; 01118 else return true; 01119 } 01120 01121 01122 int MLPSolver::getInstIndexOfRule(const Rule& r) 01123 { 01124 assert(r.head.size()>0 || r.body.size()>0); 01125 ID atomID = ID_FAIL; 01126 // try get an atom from the head 01127 if ( r.head.size()>0 ) { 01128 int i = 0; 01129 bool found = false; 01130 while ( i<r.head.size() && found == false ) { 01131 atomID=r.head.at(i); 01132 if ( atomID.isAtom() || atomID.isLiteral() ) found = true; 01133 i++; 01134 } 01135 } 01136 // if did not find any atom, try the body: 01137 if ( atomID == ID_FAIL && r.body.size()>0 ) { 01138 int i = 0; 01139 bool found = false; 01140 while ( i<r.body.size() && found == false ) { 01141 atomID=r.body.at(i); 01142 if ( atomID.isAtom() || atomID.isLiteral() ) found = true; 01143 i++; 01144 } 01145 } 01146 // if an atom is found, extract the predicate name 01147 if ( atomID != ID_FAIL ) { 01148 ID predID = getPredIDFromAtomID( atomID ); 01149 const Predicate& p = registrySolver->preds.getByID(predID); 01150 int separator = p.symbol.find(MODULEINSTSEPARATOR); 01151 return atoi( p.symbol.substr(1, separator-1).c_str() ); 01152 } 01153 return -1; // means no head and no body? what kind of rules is this? 01154 } 01155 01156 01157 void MLPSolver::updateTop(std::vector<IDSet>& Top, const Tuple& top) 01158 { 01159 bm::bvector<> clearance; // to remember which instantiation that has been cleared 01160 clearance.clear(); 01161 Tuple::const_iterator it = top.begin(); 01162 while ( it != top.end() ) { 01163 // get the instantiation index for each rule 01164 const Rule& r = registrySolver->rules.getByID(*it); 01165 int n = getInstIndexOfRule(r); 01166 DBGLOG(DBG, "[MLPSolver::updateTop] inst Index of rules: " << n); 01167 // get the Top_i/S 01168 IDSet& rSet = Top.at(n); 01169 // if has never been cleared before, clear it! 01170 if ( clearance.get_bit(n) == false ) { 01171 clearance.set(n); 01172 rSet.clear(); 01173 } 01174 rSet.get<impl::ElementTag>().insert(*it); 01175 it++; 01176 } 01177 } 01178 01179 01180 // comp() from the paper 01181 bool MLPSolver::comp(ValueCallsType C) 01182 { 01183 01184 //recording time for rewrite 01185 struct timeval timeStruct; 01186 double startTimeRewrite = 0.0; 01187 double endTimeRewrite = 0.0; 01188 double startTimePartB = 0.0; 01189 double endTimePartB = 0.0; 01190 double startTimePartC = 0.0; 01191 double endTimePartC = 0.0; 01192 double startTimePost = 0.0; 01193 double endTimePost = 0.0; 01194 double startTimeCallDLV = 0.0; 01195 double endTimeCallDLV = 0.0; 01196 double startTimePushBack = 0.0; 01197 double endTimePushBack = 0.0; 01198 double startTimeCPathA = 0.0; 01199 double endTimeCPathA = 0.0; 01200 double startTimePartA = 0.0; 01201 double endTimePartA = 0.0; 01202 double startTimeUpdateTop = 0.0; 01203 double endTimeUpdateTop = 0.0; 01204 01205 // for ASPSolver 01206 //...ASPSolver::DLVSoftware::Configuration configDLV; 01207 //...ASPSolver::ClingoSoftware::Configuration configClingo; 01208 ASPSolverManager mgr; 01209 01210 std::ostringstream oss; 01211 01212 // declare the stack 01213 std::vector< int > stackStatus; 01214 std::vector< ASPSolverManager::ResultsPtr > stackAnsRes; 01215 std::vector< InterpretationPtr > stackAns; 01216 std::vector< ValueCallsType > stackC; 01217 std::vector< std::vector<ValueCallsType> > stackPath; 01218 std::vector< InterpretationPtr > stackM; 01219 std::vector< std::vector<IDSet> > stackA; 01220 std::vector< std::vector<IDSet> > stackTop; 01221 // remove this? No. 01222 std::vector< RegistryPtr > stackRegistry; 01223 // remove this? No. 01224 std::vector< ModuleInstTable > stackMInst; 01225 std::vector< ID > stackModuleSrcAtom; 01226 01227 std::vector< Graph > stackCallGraph; 01228 std::vector< std::vector<std::string> > stackEdgeName; 01229 01230 stackStatus.push_back(0); 01231 stackC.push_back(C); 01232 int status = 0; //status=0 for the first time 01233 ID idAlpha; 01234 int maxStackSize = 0; 01235 while (stackC.size()>0) { 01236 if ( stackC.size() > maxStackSize ) maxStackSize = stackC.size(); 01237 01238 C = stackC.back(); 01239 status = stackStatus.back(); 01240 01241 // recording time for post processing ans bu 01242 if ( recordingTime == 1 ) { 01243 gettimeofday(&timeStruct, NULL); 01244 startTimePost = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01245 } 01246 01247 // 1 = from part b, 2 = from part c 01248 if ( status == 1 || status == 2) { 01249 path = stackPath.back(); 01250 *M = *stackM.back(); 01251 A = stackA.back(); 01252 if ( instSplitting == 1 ) Top = stackTop.back(); 01253 if ( forget == 1 ) { // if forget is activated 01254 RegistryPtr R2(new Registry(*stackRegistry.back() )); 01255 registrySolver = R2; 01256 moduleInstTable = stackMInst.back(); 01257 } 01258 M->setRegistry(registrySolver); 01259 if (status == 2) idAlpha = stackModuleSrcAtom.back(); 01260 Interpretation currAns = *stackAns.back(); 01261 DBGLOG(DBG,"[MLPSolver::comp] got an answer set from ans(b(R))" << currAns); 01262 DBGLOG(DBG,"[MLPSolver::comp] M before integrate answer " << *M); 01263 01264 // union M and N 01265 M->add( currAns ); 01266 ctrASFromDLV++; 01267 if ( (printLevel & Logger::INFO) != 0 ) { 01268 callGraph = stackCallGraph.back(); 01269 edgeName = stackEdgeName.back(); 01270 } 01271 stackAns.erase(stackAns.end()-1); 01272 AnswerSet::Ptr ansBack = stackAnsRes.back()->getNextAnswerSet(); 01273 if ( ansBack != 0 ) { 01274 stackAns.push_back((ansBack->interpretation)); 01275 } 01276 else { 01277 stackStatus.erase(stackStatus.end()-1); 01278 stackAnsRes.erase(stackAnsRes.end()-1); 01279 stackC.erase(stackC.end()-1); 01280 stackPath.erase(stackPath.end()-1); 01281 stackM.erase(stackM.end()-1); 01282 stackA.erase(stackA.end()-1); 01283 if ( instSplitting == 1 ) stackTop.erase(stackTop.end()-1); 01284 if ( forget == 1 ) { 01285 stackRegistry.erase(stackRegistry.end()-1); 01286 stackMInst.erase(stackMInst.end()-1); 01287 } 01288 if ( (printLevel & Logger::INFO) != 0 ) { 01289 stackCallGraph.erase(stackCallGraph.end()-1); 01290 stackEdgeName.erase(stackEdgeName.end()-1); 01291 } 01292 if ( status == 2) stackModuleSrcAtom.erase(stackModuleSrcAtom.end()-1); 01293 } 01294 if ( status == 1 ) { 01295 // from: recursion from part b 01296 } 01297 else if ( status == 2 ) { 01298 // from: recursion from part c 01299 // restriction and renaming 01300 // get the formal input paramater, tuple of predicate term 01301 const ModuleAtom& alpha = registrySolver->matoms.getByID( idAlpha); 01302 const Module& alphaJ = registrySolver->moduleTable.getModuleByName(alpha.actualModuleName); 01303 const Tuple& formalInputs = registrySolver->inputList.at(alphaJ.inputList); 01304 Tuple restrictT; 01305 Tuple newT; 01306 restrictionAndRenaming( currAns, alpha.inputs, formalInputs, restrictT, newT); 01307 DBGLOG(DBG,"[MLPSolver::comp] newT: " << printvector(newT)); 01308 01309 // defining Pj T 01310 InterpretationType intrNewT; 01311 createInterpretationFromTuple(newT, intrNewT); 01312 int idxPjT = addOrGetModuleIstantiation(alphaJ.moduleName, intrNewT); 01313 01314 // next: defining the new C and path 01315 // resize if A size <=idxPjT 01316 resizeIfNeededA(idxPjT); 01317 01318 if ( containFin(A, idxPjT) ) { 01319 } 01320 else { 01321 if ( (printLevel & Logger::INFO) != 0 ) { 01322 // add the call graph here: 01323 const VCAddressIndex& idx = C.get<impl::AddressTag>(); 01324 VCAddressIndex::const_iterator it = idx.begin(); 01325 while ( it != idx.end() ) { 01326 boost::add_edge(*it, idxPjT, callGraph); 01327 // add edge name T here 01328 InterpretationType intrRestrictT; 01329 createInterpretationFromTuple(restrictT, intrRestrictT); 01330 oss.str(""); 01331 intrRestrictT.setRegistry(registrySolver); 01332 intrRestrictT.printWithoutPrefix(oss); 01333 edgeName.push_back(oss.str()); 01334 it++; 01335 } 01336 } 01337 path.push_back(C); 01338 C.clear(); 01339 C.push_back(idxPjT); 01340 } 01341 } // if status==2 01342 } // if status == 1 || status == 2 01343 else if ( status == 0 ) { 01344 // from the beginnning 01345 stackC.erase(stackC.end()-1); 01346 } 01347 // recording time for post processing ans bu 01348 if ( recordingTime == 1 ) { 01349 gettimeofday(&timeStruct, NULL); 01350 endTimePost = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01351 totalTimePost = totalTimePost + endTimePost - startTimePost; 01352 } 01353 01354 // print the C: 01355 if ( (printLevel & Logger::INFO) != 0 ) { 01356 DBGLOG(INFO,"[MLPSolver::comp] Enter comp with C: "); 01357 oss.str(""); 01358 printValueCallsType(oss, registrySolver, C); 01359 DBGLOG(INFO,oss.str()); 01360 // print the path: 01361 DBGLOG(INFO,"[MLPSolver::comp] with path: "); 01362 oss.str(""); 01363 printPath(oss,registrySolver, path); 01364 DBGLOG(INFO,oss.str()); 01365 // print the M: 01366 DBGLOG(INFO,"[MLPSolver::comp] with M: " << *M); 01367 // print the A: 01368 DBGLOG(INFO,"[MLPSolver::comp] with A: "); 01369 oss.str(""); 01370 printA(oss,registrySolver, A); 01371 DBGLOG(INFO,oss.str()); 01372 } 01373 01374 // part a 01375 01376 //recording time part a 01377 if ( recordingTime == 1 ) { 01378 gettimeofday(&timeStruct, NULL); 01379 startTimePartA = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01380 } 01381 01382 ValueCallsType CPrev; 01383 int PiSResult; 01384 bool wasInLoop = false; 01385 if ( foundCinPath(C, path, CPrev, PiSResult) ) { 01386 DBGLOG(DBG, "[MLPSolver::comp] found value-call-loop in value calls"); 01387 /* not needed for i-stratified 01388 if ( foundNotEmptyInst(C) ) 01389 { 01390 DBGLOG(DBG, "[MLPSolver::comp] not ic-stratified program because foundNotEmptyInst(C)"); 01391 DBGLOG(DBG, "[MLPSolver::comp] path: "); 01392 oss.str(""); 01393 printPath(oss,ctxSolver, path); 01394 DBGLOG(DBG, oss.str()); 01395 throw FatalError("[MLPSolver::comp] Error: not c stratified program "); 01396 return false; 01397 } 01398 */ 01399 DBGLOG(DBG, "[MLPSolver::comp] ic-stratified test 1 passed"); 01400 ValueCallsType C2; 01401 do { 01402 C2 = path.back(); 01403 path.erase(path.end()-1); 01404 /* not needed for i-stratified 01405 if ( foundNotEmptyInst(C2) ) 01406 { 01407 DBGLOG(DBG, "[MLPSolver::comp] not ic-stratified program because foundNotEmptyInst(C2)"); 01408 throw FatalError("[MLPSolver::comp] Error: not c stratified program "); 01409 return false; 01410 } 01411 */ 01412 DBGLOG(DBG, "[MLPSolver::comp] ic-stratified test 2 passed"); 01413 unionCtoFront(C, C2); 01414 DBGLOG(DBG, "[MLPSolver::comp] C size after union: " << C.size()); 01415 } 01416 while ( C2 != CPrev ); 01417 wasInLoop = true; 01418 } // if ( foundCinPath.... 01419 else { 01420 DBGLOG(DBG, "[MLPSolver::comp] found no value-call-loop in value calls"); 01421 } 01422 01423 //finish recording time part a 01424 if ( recordingTime == 1 ) { 01425 gettimeofday(&timeStruct, NULL); 01426 endTimePartA = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01427 totalTimePartA = totalTimePartA + endTimePartA - startTimePartA; 01428 } 01429 01430 //recording time rewrite 01431 if ( recordingTime == 1 ) { 01432 gettimeofday(&timeStruct, NULL); 01433 startTimeRewrite = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01434 } 01435 01436 InterpretationPtr edbRewrite; 01437 Tuple idbRewrite; 01438 rewrite(C, edbRewrite, idbRewrite); 01439 01440 if ( recordingTime == 1 ) { 01441 gettimeofday(&timeStruct, NULL); 01442 endTimeRewrite = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01443 totalTimeRewrite = totalTimeRewrite + endTimeRewrite - startTimeRewrite; 01444 } 01445 01446 DBGLOG(DBG, "[MLPSolver::comp] after rewrite: "); 01447 if ( printProgramInformation == true ) 01448 printEdbIdb(registrySolver, edbRewrite, idbRewrite); 01449 01450 if ( isOrdinary(idbRewrite) ) { 01451 // start recording time part b 01452 //...int cint; 01453 //...std::cin >> cint; 01454 01455 countB++; 01456 if ( recordingTime == 1 ) { 01457 gettimeofday(&timeStruct, NULL); 01458 startTimePartB = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01459 } 01460 01461 DBGLOG(DBG, "[MLPSolver::comp] enter isOrdinary"); 01462 if ( path.size() == 0 ) { 01463 //printProgram(ctxSolver,edbRewrite, idbRewrite); 01464 DBGLOG(DBG, "[MLPSolver::comp] enter path size empty"); 01465 // try to get the answer set: 01466 01467 ASPSolverManager::ResultsPtr res; 01468 OrdinaryASPProgram program(registrySolver, idbRewrite, edbRewrite, 0); 01469 01470 // recording time to call DLV 01471 if ( recordingTime == 1 ) { 01472 gettimeofday(&timeStruct, NULL); 01473 startTimeCallDLV = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01474 } 01475 01476 //staticSolver res = mgr.solve(config, program); 01477 res = mgr.solve(*ctx.getASPSoftware(), program); 01478 ctrCallToDLV++; 01479 01480 if ( recordingTime == 1 ) { 01481 gettimeofday(&timeStruct, NULL); 01482 endTimeCallDLV = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01483 totalTimeCallDLV = totalTimeCallDLV + endTimeCallDLV - startTimeCallDLV; 01484 } 01485 01486 AnswerSet::Ptr int0 = res->getNextAnswerSet(); 01487 01488 while (int0 !=0 ) { 01489 01490 InterpretationPtr M2(new Interpretation(registrySolver)); 01491 *M2 = *M; 01492 // integrate the answer 01493 M2->add( *(int0->interpretation) ); 01494 ctrASFromDLV++; 01495 01496 // collect the full answer set 01497 ctrAS++; 01498 oss.str(""); 01499 DBGLOG(INFO, "[MLPSolver::comp] Got an answer set" << std::endl << "ANSWER SET" << std::endl << ctrAS); 01500 printASinSlot(oss, registrySolver, M2); 01501 std::string asString = oss.str(); 01502 std::cout << asString << std::endl; 01503 //std::cout << ctrAS << std::endl; 01504 struct timeval currentTimeStruct; 01505 gettimeofday(¤tTimeStruct, NULL); 01506 double currentTime = currentTimeStruct.tv_sec+(currentTimeStruct.tv_usec/1000000.0); 01507 DBGLOG(STATS, std::endl << ctrAS << std::endl << moduleInstTable.size() << std::endl << registrySolver->ogatoms.getSize() << std::endl << ctrASFromDLV << std::endl << ctrCallToDLV << std::endl << (currentTime - startTime)); 01508 if ( (printLevel & Logger::INFO) != 0) { 01509 // print the call graph 01510 oss.str(""); 01511 printCallGraph(oss, callGraph, asString); 01512 DBGLOG(INFO, std::endl << " ==== call graph begin here ==== " << std::endl << ctrAS << ".dot" << std::endl << oss.str() << std::endl << " ==== call graph end here ==== "); 01513 DBGLOG(INFO, "Instantiation information: "); 01514 std::ostringstream oss; 01515 for (int i=0; i<moduleInstTable.size(); i++) { 01516 oss.str(""); 01517 oss << "m" << i << ": "; 01518 printModuleInst(oss, registrySolver, i); 01519 DBGLOG(INFO, oss.str()); 01520 } 01521 DBGLOG(INFO, "Registry information: "); 01522 DBGLOG(INFO, *registrySolver); 01523 } 01524 01525 if ( nASReturned > 0 && ctrAS == nASReturned) return true; 01526 01527 // get the next answer set 01528 int0 = res->getNextAnswerSet(); 01529 } // while (int0... 01530 } // if path.size == 0 ... 01531 else { 01532 // part b, if path is not empty... 01533 ValueCallsType C2 = path.back(); 01534 if ( (printLevel & Logger::DBG) != 0 ) { 01535 DBGLOG(DBG,"[MLPSolver::comp] path before erase: "); 01536 oss.str(""); 01537 printPath(oss, registrySolver, path); 01538 DBGLOG(DBG,oss.str()); 01539 } 01540 path.erase(path.end()-1); 01541 if ( (printLevel & Logger::DBG) != 0 ) { 01542 DBGLOG(DBG,"[MLPSolver::comp] path after erase: "); 01543 oss.str(""); 01544 printPath(oss, registrySolver, path); 01545 DBGLOG(DBG,oss.str()); 01546 } 01547 const VCAddressIndex& idx = C.get<impl::AddressTag>(); 01548 VCAddressIndex::const_iterator it = idx.begin(); 01549 while ( it != idx.end() ) { 01550 IDSet& a = A.at(*it); 01551 assignFin(a); 01552 it++; 01553 } 01554 if ( instSplitting == 1 ) { 01555 it = idx.begin(); 01556 while ( it != idx.end() ) { 01557 if (Top.size() > *it) { 01558 IDSet& t = Top.at(*it); 01559 t.clear(); 01560 } 01561 it++; 01562 } 01563 } 01564 01565 // for all ans(newCtx) here 01566 // try to get the answer set: 01567 01568 ASPSolverManager::ResultsPtr res; 01569 OrdinaryASPProgram program(registrySolver, idbRewrite, edbRewrite, 0); 01570 01571 // recording time to call DLV 01572 if ( recordingTime == 1 ) { 01573 gettimeofday(&timeStruct, NULL); 01574 startTimeCallDLV = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01575 } 01576 01577 //staticSolver res = mgr.solve(config, program); 01578 res = mgr.solve(*ctx.getASPSoftware(), program); 01579 ctrCallToDLV++; 01580 01581 if ( recordingTime == 1 ) { 01582 gettimeofday(&timeStruct, NULL); 01583 endTimeCallDLV = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01584 totalTimeCallDLV = totalTimeCallDLV + endTimeCallDLV - startTimeCallDLV; 01585 } 01586 01587 // for the recursion part b 01588 AnswerSet::Ptr int0 = res->getNextAnswerSet(); 01589 if ( int0!=0 ) { 01590 01591 // start recording time for push back part b 01592 if ( recordingTime == 1 ) { 01593 gettimeofday(&timeStruct, NULL); 01594 startTimePushBack = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01595 } 01596 01597 stackAns.push_back((int0->interpretation)); 01598 stackAnsRes.push_back(res); 01599 stackStatus.push_back(1); 01600 01601 if ( recordingTime == 1 ) { 01602 gettimeofday(&timeStruct, NULL); 01603 startTimeCPathA = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01604 } 01605 01606 stackC.push_back(C2); 01607 stackPath.push_back(path); 01608 stackA.push_back(A); 01609 if ( instSplitting == 1 ) stackTop.push_back(Top); 01610 if ( recordingTime == 1 ) { 01611 gettimeofday(&timeStruct, NULL); 01612 endTimeCPathA = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01613 totalTimeCPathA = totalTimeCPathA + endTimeCPathA - startTimeCPathA; 01614 } 01615 01616 InterpretationPtr M2(new Interpretation(registrySolver)); 01617 *M2 = *M; 01618 stackM.push_back(M2); 01619 if ( forget == 1 ) { 01620 RegistryPtr R2(new Registry(*registrySolver) ); 01621 stackRegistry.push_back( R2 ); 01622 stackMInst.push_back(moduleInstTable); 01623 } 01624 if ( (printLevel & Logger::INFO) != 0 ) { 01625 stackCallGraph.push_back(callGraph); 01626 stackEdgeName.push_back(edgeName); 01627 } 01628 01629 // ending recording time for push back part b 01630 if ( recordingTime == 1 ) { 01631 gettimeofday(&timeStruct, NULL); 01632 endTimePushBack = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01633 totalTimePushBack = totalTimePushBack + endTimePushBack - startTimePushBack; 01634 } 01635 01636 } 01637 } // else if path size = 0, else 01638 // finish recording time part b 01639 if ( recordingTime == 1 ) { 01640 gettimeofday(&timeStruct, NULL); 01641 endTimePartB = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01642 totalTimePartB = totalTimePartB + endTimePartB - startTimePartB; 01643 } 01644 } // if isOrdinary ( idb... 01645 else { // if not ordinary 01646 // part c 01647 countC++; 01648 // start recording time part c 01649 if ( recordingTime == 1 ) { 01650 gettimeofday(&timeStruct, NULL); 01651 startTimePartC = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01652 } 01653 DBGLOG(DBG, "[MLPSolver::comp] enter not ordinary part"); 01654 ID idAlpha = smallestILL(idbRewrite); 01655 if ( idAlpha == ID_FAIL ) { 01656 // not i-stratified 01657 throw FatalError("[MLPSolver::comp] Error: not i stratified program; cannot find an all-prepared-input module atom"); 01658 return false; 01659 } 01660 const ModuleAtom& alpha = registrySolver->matoms.getByID(idAlpha); 01661 DBGLOG(DBG, "[MLPSolver::comp] smallest ill by: " << idAlpha); 01662 // check the size of A 01663 DBGLOG(DBG, "[MLPSolver::comp] moduleInstTable size: " << moduleInstTable.size()); 01664 DBGLOG(DBG, "[MLPSolver::comp] A size: " << A.size()); 01665 if ( A.size() < moduleInstTable.size() ) A.resize( moduleInstTable.size() ); 01666 01667 // loop over PiS in C, insert id into AiS 01668 const VCAddressIndex& idx = C.get<impl::AddressTag>(); 01669 VCAddressIndex::const_iterator it = idx.begin(); 01670 while ( it != idx.end() ) { 01671 A.at(*it).get<impl::ElementTag>().insert(idAlpha); 01672 it++; 01673 } 01674 01675 Tuple bottom; 01676 if ( instSplitting == 0 ) { 01677 //...Tuple top; 01678 //...collectLargestBottom(idbRewrite, bottom, top); 01679 collectBottom(alpha, idbRewrite, bottom); 01680 if ( printProgramInformation == true ) { 01681 DBGLOG(DBG, "[MLPSolver::comp] Edb Idb after collect bottom for id: " << idAlpha); 01682 printEdbIdb(registrySolver, edbRewrite, bottom); 01683 } 01684 //...int cint; 01685 //...std::cin >> cint; 01686 //...std::cout << "[MLPSolver::comp] Edb Idb after collect bottom for id: " << idAlpha << std::endl; 01687 //...printEdbIdb(registrySolver, edbRewrite, bottom); 01688 } 01689 else if ( instSplitting == 1 ) { 01690 Tuple top; 01691 //...collectBottom(alpha, idbRewrite, bottom); 01692 //...tupleMinus(idbRewrite, bottom, top); 01693 //...DBGLOG(DBG, "[MLPSolver::comp] Edb Idb after collect bottom for id: " << idAlpha); 01694 collectLargestBottom(alpha, idbRewrite, bottom, top); 01695 if ( printProgramInformation == true ) { 01696 DBGLOG(DBG, "[MLPSolver::comp] Edb Idb after collect largest bottom: "); 01697 printEdbIdb(registrySolver, edbRewrite, bottom); 01698 } 01699 //...int cint; 01700 //...std::cin >> cint; 01701 //...std::cout << "[MLPSolver::comp] Edb Idb after collect largest bottom: " << std::endl; 01702 //...printEdbIdb(registrySolver, edbRewrite, bottom); 01703 // here add rmlpize 01704 if ( Top.size() < moduleInstTable.size() ) Top.resize( moduleInstTable.size() ); 01705 01706 // record time for updateTop 01707 if ( recordingTime == 1 ) { 01708 gettimeofday(&timeStruct, NULL); 01709 startTimeUpdateTop = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01710 } 01711 updateTop(Top, top); 01712 if ( recordingTime == 1 ) { 01713 gettimeofday(&timeStruct, NULL); 01714 endTimeUpdateTop = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01715 totalTimeUpdateTop = totalTimeUpdateTop + endTimeUpdateTop - startTimeUpdateTop; 01716 } 01717 01718 if ( (printLevel & Logger::INFO) != 0 ) { 01719 oss.str(""); 01720 printA(oss, registrySolver, Top); 01721 DBGLOG(INFO,"[MLPSolver::comp] with M: " << *M); 01722 DBGLOG(DBG, "[MLPSolver::comp] after updateTop: " << oss.str()); 01723 } 01724 } 01725 // get the module name 01726 const Module& alphaJ = registrySolver->moduleTable.getModuleByName(alpha.actualModuleName); 01727 if (alphaJ.moduleName=="") { 01728 DBGLOG(DBG,"[MLPSolver::comp] Error: Looking for module "<< alpha.actualModuleName << " got an empty module: " << alphaJ); 01729 return false; 01730 } 01731 DBGLOG(DBG,"[MLPSolver::comp] alphaJ: " << alphaJ); 01732 01733 // for all N in ans(bu(R)) 01734 // try to get the answer of the bottom: 01735 01736 ASPSolverManager::ResultsPtr res; 01737 01738 OrdinaryASPProgram program(registrySolver, bottom, edbRewrite, 0); 01739 01740 // recording time to call DLV 01741 if ( recordingTime == 1 ) { 01742 gettimeofday(&timeStruct, NULL); 01743 startTimeCallDLV = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01744 } 01745 01746 //staticSolver res = mgr.solve(config, program); 01747 res = mgr.solve(*ctx.getASPSoftware(), program); 01748 ctrCallToDLV++; 01749 01750 if ( recordingTime == 1 ) { 01751 gettimeofday(&timeStruct, NULL); 01752 endTimeCallDLV = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01753 totalTimeCallDLV = totalTimeCallDLV + endTimeCallDLV - startTimeCallDLV; 01754 } 01755 01756 AnswerSet::Ptr int0 = res->getNextAnswerSet(); 01757 01758 if ( int0!=0 ) { 01759 // recording time for push back part c 01760 if ( recordingTime == 1 ) { 01761 gettimeofday(&timeStruct, NULL); 01762 startTimePushBack = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01763 } 01764 01765 stackAns.push_back((int0->interpretation)); 01766 stackAnsRes.push_back(res); 01767 stackStatus.push_back(2); 01768 01769 if ( recordingTime == 1 ) { 01770 gettimeofday(&timeStruct, NULL); 01771 startTimeCPathA = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01772 } 01773 01774 stackC.push_back(C); 01775 stackPath.push_back(path); 01776 stackA.push_back(A); 01777 if ( instSplitting == 1 ) stackTop.push_back(Top); 01778 if ( recordingTime == 1 ) { 01779 gettimeofday(&timeStruct, NULL); 01780 endTimeCPathA = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01781 totalTimeCPathA = totalTimeCPathA + endTimeCPathA - startTimeCPathA; 01782 } 01783 01784 InterpretationPtr M2(new Interpretation(registrySolver)); 01785 *M2 = *M; 01786 stackM.push_back(M2); 01787 if ( forget == 1 ) { 01788 RegistryPtr R2(new Registry(*registrySolver) ); 01789 stackRegistry.push_back( R2 ); 01790 stackMInst.push_back(moduleInstTable); 01791 } 01792 stackModuleSrcAtom.push_back(idAlpha); 01793 if ( (printLevel & Logger::INFO) != 0 ) { 01794 stackCallGraph.push_back(callGraph); 01795 stackEdgeName.push_back(edgeName); 01796 } 01797 01798 // recording time for push back part c 01799 if ( recordingTime == 1 ) { 01800 gettimeofday(&timeStruct, NULL); 01801 endTimePushBack = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01802 totalTimePushBack = totalTimePushBack + endTimePushBack - startTimePushBack; 01803 } 01804 01805 } 01806 // finish recording time part c 01807 if ( recordingTime == 1 ) { 01808 gettimeofday(&timeStruct, NULL); 01809 endTimePartC = timeStruct.tv_sec+(timeStruct.tv_usec/1000000.0); 01810 totalTimePartC = totalTimePartC + endTimePartC - startTimePartC; 01811 } 01812 01813 } // else (if ordinary ... else ...) 01814 01815 } // while stack is not empty 01816 01817 01818 DBGLOG(DBG, "[MLPSolver::comp] finished"); 01819 01820 return true; 01821 } 01822 01823 01824 bool MLPSolver::solve() 01825 { 01826 recordingTime = 0; 01827 if ( (printLevel & Logger::ANALYZE) != 0 ) recordingTime = 1; 01828 totalTimePost = 0.0; 01829 totalTimePartA = 0.0; 01830 totalTimeRewrite = 0.0; 01831 totalTimePartB = 0.0; 01832 totalTimePartC = 0.0; 01833 totalTimeCallDLV = 0.0; 01834 totalTimePushBack = 0.0; 01835 totalTimeCPathA = 0.0; 01836 countB = 0; 01837 countC = 0; 01838 printProgramInformation = false; 01839 DBGLOG(STATS, "1st row: '80'-> ignore this; 2nd row: ctrAS; 3rd row: #moduleInstantiation, 4th row: #ordinaryGroundAtoms, 5th row: #ASFromDLV, 6th row: #callToDLV, 7th row: TimeElapsed"); 01840 DBGLOG(DBG, "[MLPSolver::solve] started"); 01841 // find all main modules in the program 01842 std::vector<int> mainModules = foundMainModules(); 01843 std::vector<int>::const_iterator it = mainModules.begin(); 01844 int i = 0; 01845 dataReset(); 01846 01847 // to record time 01848 struct timeval startTimeStruct; 01849 gettimeofday(&startTimeStruct, NULL); 01850 startTime = startTimeStruct.tv_sec+(startTimeStruct.tv_usec/1000000.0); 01851 01852 ctrAS = 0; 01853 ctrCallToDLV = 0; 01854 ctrASFromDLV = 0; 01855 01856 //recording time for comp 01857 double compStartTime; 01858 double compEndTime; 01859 if ( recordingTime ==1 ) { 01860 gettimeofday(&startTimeStruct, NULL); 01861 compStartTime = startTimeStruct.tv_sec+(startTimeStruct.tv_usec/1000000.0); 01862 } 01863 while ( it != mainModules.end() ) { 01864 A.clear(); 01865 Top.clear(); 01866 M->clear(); 01867 RegistryPtr R2(new Registry( *ctx.registry() )); 01868 registrySolver = R2; 01869 moduleInstTable.clear(); 01870 DBGLOG(INFO, " "); 01871 DBGLOG(INFO, "[MLPSolver::solve] ==================== main module solve ctr: ["<< i << "] =================================="); 01872 DBGLOG(INFO, "[MLPSolver::solve] main module id inspected: " << *it); 01873 if ( comp(createValueCallsMainModule(*it)) == false ) { 01874 throw FatalError("MLP solve: comp() return false"); 01875 return false; 01876 } 01877 i++; 01878 it++; 01879 } 01880 gettimeofday(&startTimeStruct, NULL); 01881 //recording time... 01882 if ( recordingTime ==1 ) { 01883 compEndTime = startTimeStruct.tv_sec+(startTimeStruct.tv_usec/1000000.0); 01884 std::cerr << "Total comp time: " << compEndTime-compStartTime << std::endl; 01885 std::cerr << "Post process ans(bu) Time: " << totalTimePost << std::endl; 01886 std::cerr << "Part A time: " << totalTimePartA << std::endl; 01887 std::cerr << "Rewrite Time: " << totalTimeRewrite << ", countRwr: " << countB+countC << ", avgtimeRwr: " << totalTimeRewrite/(countB+countC) << std::endl; 01888 std::cerr << "Part B time: " << totalTimePartB << ", countB: " << countB << ", avgtimeB: " << totalTimePartB/countB << std::endl; 01889 std::cerr << "Part C time: " << totalTimePartC << ", countC: " << countC << ", avgtimeC: " << totalTimePartC/countC << std::endl; 01890 std::cerr << "UpdateTop time: " << totalTimeUpdateTop << ", countUpdateTop: " << countC << ", avgtimeUpdateTop: " << totalTimeUpdateTop/countC << std::endl; 01891 std::cerr << "Call DLV time: " << totalTimeCallDLV << ", countCallDLV: " << ctrCallToDLV << ", avgtimeCallDLV: " << totalTimeCallDLV/ctrCallToDLV << std::endl; 01892 std::cerr << "Push back time: " << totalTimePushBack << std::endl; 01893 std::cerr << "PushBack CPathA Time: " << totalTimeCPathA << std::endl; 01894 } 01895 DBGLOG(INFO, "Total answer set: " << ctrAS); 01896 /* 01897 DBGLOG(INFO, "Instantiation information: "); 01898 std::ostringstream oss; 01899 for (int i=0; i<moduleInstTable.size(); i++) 01900 { 01901 oss.str(""); 01902 oss << "m" << i << ": "; 01903 printModuleInst(oss, registrySolver, i); 01904 DBGLOG(INFO, oss.str()); 01905 } 01906 01907 DBGLOG(INFO, "Registry information: "); 01908 DBGLOG(INFO, *registrySolver); 01909 */ 01910 DBGLOG(INFO, "[MLPSolver::solve] finished"); 01911 01912 return true; 01913 } 01914 01915 01916 void MLPSolver::printValueCallsType(std::ostringstream& oss, const RegistryPtr& reg1, const ValueCallsType& C) const 01917 { 01918 oss << "{ "; 01919 const VCAddressIndex& idx = C.get<impl::AddressTag>(); 01920 VCAddressIndex::const_iterator it = idx.begin(); 01921 bool first = true; 01922 while ( it != idx.end() ) { 01923 ModuleInst mi = moduleInstTable.at(*it); 01924 std::string moduleName = reg1->moduleTable.getByAddress(mi.idxModule).moduleName; 01925 Interpretation s = sTable.at(mi.idxS); 01926 s.setRegistry(reg1); 01927 if ( first == false ) oss << ", "; 01928 oss << moduleName << "[" << s << "]"; 01929 it++; 01930 first = false; 01931 } 01932 oss << " }"; 01933 } 01934 01935 01936 void MLPSolver::printPath(std::ostringstream& oss, const RegistryPtr& reg1, const std::vector<ValueCallsType>& path) const 01937 { 01938 std::vector<ValueCallsType>::const_iterator it = path.begin(); 01939 while ( it != path.end() ) { 01940 printValueCallsType(oss, reg1, *it); 01941 it++; 01942 if (it != path.end() ) oss << std::endl; 01943 } 01944 } 01945 01946 01947 void MLPSolver::printA(std::ostringstream& oss, const RegistryPtr& reg1, const std::vector<IDSet>& A) const 01948 { 01949 RawPrinter printer(oss, reg1); 01950 01951 std::vector<IDSet>::const_iterator it = A.begin(); 01952 int i=0; 01953 bool first; 01954 while ( it != A.end() ) { 01955 oss << "A[" << i << "][size:" << (*it).size() << "]: "; 01956 IDSAddressIndex::const_iterator itIDSet = (*it).begin(); 01957 first = true; 01958 while ( itIDSet != (*it).end() ) { 01959 // print here 01960 if (first == false) oss << ", "; 01961 if ( *itIDSet == ID_FAIL ) 01962 oss << "fin"; 01963 else { 01964 printer.print(*itIDSet); 01965 } 01966 01967 itIDSet++; 01968 first = false; 01969 } 01970 oss << std::endl; 01971 i++; 01972 it++; 01973 } 01974 } 01975 01976 01977 // print the text of module instantiation, given the module index (index to the instantiation table) 01978 // example: p1[{q(a),q(b)}] 01979 void MLPSolver::printModuleInst(std::ostream& out, const RegistryPtr& reg, int moduleInstIdx) 01980 { 01981 // get the module index 01982 int idxM = extractPi(moduleInstIdx); 01983 out << reg->moduleTable.getByAddress(idxM).moduleName ; 01984 01985 // get the interpetretation index 01986 int idxS = extractS(moduleInstIdx); 01987 Interpretation intrS = sTable.get<impl::AddressTag>().at(idxS); 01988 intrS.setRegistry( reg ); 01989 out << "["; 01990 intrS.printWithoutPrefix(out); 01991 out << "]"; 01992 } 01993 01994 01995 void MLPSolver::printASinSlot(std::ostream& out, const RegistryPtr& reg, const InterpretationPtr& intr) 01996 { 01997 // Interpretation newIntr( reg ); 01998 InterpretationPtr newIntr (new Interpretation(reg) ); 01999 out << "("; 02000 bool first = true; 02001 for (int i=0; i<moduleInstTable.size();i++) { 02002 createMiS(i, intr, newIntr); 02003 if ( !( newIntr->isClear() ) ) { 02004 if (first == false) out << ", "; 02005 printModuleInst(out,reg,i); 02006 out << "="; 02007 newIntr->printWithoutPrefix(out); 02008 first = false; 02009 02010 } 02011 } 02012 out << ")"; 02013 } 02014 02015 02016 void MLPSolver::printCallGraph(std::ostream& oss, const Graph& graph, const std::string& graphLabel) 02017 { 02018 // produce all module instantiation table 02019 std::ostringstream ss; 02020 std::vector<std::string> vertexName(moduleInstTable.size()); 02021 for (int i=0;i<moduleInstTable.size();i++) { 02022 ss.str(""); 02023 printModuleInst(ss, registrySolver, i); 02024 vertexName[i] = ss.str(); 02025 } 02026 // print the preliminary 02027 oss << std::endl; 02028 oss << "digraph G {" << std::endl; 02029 // get the maximum number of vertex 02030 VertexIterator itg, itg_end; 02031 boost::tie(itg, itg_end) = boost::vertices(callGraph); 02032 oss << *itg_end << "[label=\"" << graphLabel << "\", shape=box];" << std::endl; 02033 02034 // print the edge 02035 EdgeIterator ite, ite_end; 02036 boost::tie(ite, ite_end) = boost::edges(callGraph); 02037 int ie=0; 02038 std::vector<std::string>::const_iterator itEN = edgeName.begin(); 02039 while (ite != ite_end ) { 02040 if ( itEN == edgeName.end() ) { 02041 DBGLOG(ERROR, "Not sync edge and edge name"); 02042 return; 02043 } 02044 oss << boost::source(*ite,callGraph) << "->" << boost::target(*ite,callGraph) << "[label=\"" << *itEN << "\"];" << std::endl; 02045 oss << boost::source(*ite,callGraph) << "[label=\"" << vertexName[boost::source(*ite,callGraph)] << "\"];" << std::endl; 02046 oss << boost::target(*ite,callGraph) << "[label=\"" << vertexName[boost::target(*ite,callGraph)] << "\"];" << std::endl; 02047 itEN++; 02048 ite++; 02049 ie++; 02050 } 02051 oss << "}" << std::endl; 02052 // boost::write_graphviz(ofsGraph, callGraph, boost::make_label_writer(vertexName)); 02053 } 02054 02055 02056 void MLPSolver::printProgram(const RegistryPtr& reg1, const InterpretationPtr& edb, const Tuple& idb) 02057 { 02058 DBGLOG(DBG, *reg1); 02059 RawPrinter printer(std::cerr, reg1); 02060 Interpretation::Storage bits = edb->getStorage(); 02061 Interpretation::Storage::enumerator it = bits.first(); 02062 while ( it!=bits.end() ) { 02063 DBGLOG(DBG, "[MLPSolver::printProgram] address: " << *it); 02064 it++; 02065 } 02066 std::cerr << "edb = " << *edb << std::endl; 02067 DBGLOG(DBG, "idb begin"); 02068 printer.printmany(idb,"\n"); 02069 std::cerr << std::endl; 02070 DBGLOG(DBG, "idb end"); 02071 } 02072 02073 02074 void MLPSolver::printIdb(const RegistryPtr& reg1, const Tuple& idb) 02075 { 02076 RawPrinter printer(std::cerr, reg1); 02077 DBGLOG(DBG, "idb begin"); 02078 printer.printmany(idb,"\n"); 02079 std::cerr << std::endl; 02080 DBGLOG(DBG, "idb end"); 02081 } 02082 02083 02084 void MLPSolver::printEdbIdb(const RegistryPtr& reg1, const InterpretationPtr& edb, const Tuple& idb) 02085 { 02086 std::cerr << "edb = " << *edb << std::endl; 02087 RawPrinter printer(std::cerr, reg1); 02088 DBGLOG(DBG, "idb begin"); 02089 printer.printmany(idb,"\n"); 02090 std::cerr << std::endl; 02091 DBGLOG(DBG, "idb end"); 02092 } 02093 02094 02095 const Tuple& MLPSolver::getOgatomsInInst(int instIdx) 02096 { 02097 // check the size of ogatoms, 02098 // whether we should update our indexing mechanisms 02099 if ( registrySolver->ogatoms.getSize() > totalSizeInstOgatoms ) { 02100 // update instOgatoms 02101 instOgatoms.resize( moduleInstTable.size() ); 02102 for (int i=totalSizeInstOgatoms; i<registrySolver->ogatoms.getSize();i++ ) { 02103 const OrdinaryAtom& oa = registrySolver->ogatoms.getByAddress(i); 02104 int n = oa.text.find( MODULEINSTSEPARATOR ); 02105 if ( n != std::string::npos ) { 02106 // MODULEINSTSEPARATOR found 02107 std::string pref = oa.text.substr(0, n); 02108 pref = pref.substr( 1 ); 02109 int instIdx = atoi( pref.c_str() ); 02110 instOgatoms.at(instIdx).push_back( ID(oa.kind, i) ); 02111 } 02112 02113 } 02114 totalSizeInstOgatoms = registrySolver->ogatoms.getSize(); 02115 } 02116 return instOgatoms.at(instIdx); 02117 } 02118 02119 02120 DLVHEX_NAMESPACE_END 02121 #endif 02122 02123 02124 // vim:expandtab:ts=4:sw=4: 02125 // mode: C++ 02126 // End: