dlvhex  2.5.0
include/dlvhex2/MLPSolver.h
Go to the documentation of this file.
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 
00047 #if !defined(_DLVHEX_MLPSOLVER_H)
00048 #define _DLVHEX_MLPSOLVER_H
00049 
00050 #ifdef HAVE_CONFIG_H
00051 #include "config.h"
00052 #endif
00053 
00054 #ifdef HAVE_MLP
00055 
00056 #include "dlvhex2/ID.h"
00057 #include "dlvhex2/Interpretation.h"
00058 #include "dlvhex2/Table.h"
00059 #include "dlvhex2/ProgramCtx.h"
00060 #include "dlvhex2/ASPSolver.h"
00061 #include "dlvhex2/ASPSolverManager.h"
00062 #include "dlvhex2/AnswerSet.h"
00063 #include "dlvhex2/Printer.h"
00064 
00065 #include <boost/multi_index_container.hpp>
00066 #include <boost/multi_index/member.hpp>
00067 #include <boost/multi_index/ordered_index.hpp>
00068 #include <boost/multi_index/hashed_index.hpp>
00069 #include <boost/multi_index/random_access_index.hpp>
00070 #include <boost/multi_index/identity.hpp>
00071 #include <boost/multi_index/composite_key.hpp>
00072 
00073 #include <boost/graph/adjacency_list.hpp>
00074 #include <boost/graph/graph_traits.hpp>
00075 #include <boost/graph/graphviz.hpp>
00076 
00077 #include <iostream>
00078 #include <string>
00079 #include <fstream>
00080 #include <time.h>
00081 #include <sys/time.h>
00082 
00083 DLVHEX_NAMESPACE_BEGIN
00084 
00088 class DLVHEX_EXPORT MLPSolver
00089 {
00090 
00091     typedef Interpretation InterpretationType;
00092 
00093     // to store/index S
00094     typedef boost::multi_index_container<
00095         InterpretationType,
00096         boost::multi_index::indexed_by<
00097         boost::multi_index::random_access<boost::multi_index::tag<impl::AddressTag> >,
00098         boost::multi_index::hashed_unique<boost::multi_index::tag<impl::ElementTag>, boost::multi_index::identity<InterpretationType> >
00099         >
00100         > InterpretationTable;
00101     typedef InterpretationTable::index<impl::AddressTag>::type ITAddressIndex;
00102     typedef InterpretationTable::index<impl::ElementTag>::type ITElementIndex;
00103 
00104     InterpretationTable sTable;
00105 
00106     // to store/index module instantiation = to store complete Pi[S]
00107     struct ModuleInst
00108     {
00109         int idxModule;
00110         int idxS;
00111         ModuleInst(
00112             int idxModule,
00113             int idxS):
00114         idxModule(idxModule),idxS(idxS)
00115             {}
00116     };
00117 
00118     typedef boost::multi_index_container<
00119         ModuleInst,
00120         boost::multi_index::indexed_by<
00121         boost::multi_index::random_access<boost::multi_index::tag<impl::AddressTag> >,
00122         boost::multi_index::hashed_unique<boost::multi_index::tag<impl::ElementTag>,
00123         boost::multi_index::composite_key<
00124         ModuleInst,
00125         boost::multi_index::member<ModuleInst, int, &ModuleInst::idxModule>,
00126         boost::multi_index::member<ModuleInst, int, &ModuleInst::idxS>
00127         >
00128         >
00129         >
00130         > ModuleInstTable;
00131     typedef ModuleInstTable::index<impl::AddressTag>::type MIAddressIndex;
00132     typedef ModuleInstTable::index<impl::ElementTag>::type MIElementIndex;
00133 
00134     ModuleInstTable moduleInstTable;
00135 
00136     // to store/index value calls = to store C
00137     typedef boost::multi_index_container<
00138         int,                     // index to the ModuleInstTable
00139         boost::multi_index::indexed_by<
00140         boost::multi_index::random_access<boost::multi_index::tag<impl::AddressTag> >,
00141         boost::multi_index::hashed_unique<boost::multi_index::tag<impl::ElementTag>, boost::multi_index::identity<int> >
00142         >
00143         > ValueCallsType;
00144     typedef ValueCallsType::index<impl::AddressTag>::type VCAddressIndex;
00145     typedef ValueCallsType::index<impl::ElementTag>::type VCElementIndex;
00146 
00147     // to store/index ID
00148     typedef boost::multi_index_container<
00149         ID,
00150         boost::multi_index::indexed_by<
00151         boost::multi_index::random_access<boost::multi_index::tag<impl::AddressTag> >,
00152         boost::multi_index::hashed_unique<boost::multi_index::tag<impl::ElementTag>, boost::multi_index::identity<ID> >
00153         >
00154         > IDSet;
00155     typedef IDSet::index<impl::AddressTag>::type IDSAddressIndex;
00156     typedef IDSet::index<impl::ElementTag>::type IDSElementIndex;
00157     // vector of IDTable, the index of the i/S should match with the index in tableInst
00158     std::vector<IDSet> A;
00159     std::vector<IDSet> Top;      // to store top rules (in instantiation splitting mode)
00160 
00161     // type for the Mi/S
00162     typedef std::vector<InterpretationType> VectorOfInterpretation;
00163     // vector of Interpretation, the index of the i/S should match with the index in tableInst
00164     InterpretationPtr M;
00165 
00166     // all about graph here:
00167     //typedef boost::property<boost::edge_name_t, std::string> EdgeNameProperty;
00168     //typedef boost::property<boost::vertex_name_t, std::string> VertexNameProperty;
00169     //typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, VertexNameProperty, EdgeNameProperty> Graph;
00170 
00171     typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, int, int> Graph;
00172     typedef boost::graph_traits<Graph> Traits;
00173 
00174     typedef Graph::vertex_descriptor Vertex;
00175     typedef Graph::edge_descriptor Edge;
00176     typedef Traits::vertex_iterator VertexIterator;
00177     typedef Traits::edge_iterator EdgeIterator;
00178     typedef Traits::out_edge_iterator OutEdgeIterator;
00179     typedef Traits::in_edge_iterator InEdgeIterator;
00180     Graph callGraph;
00181     std::vector<std::string> edgeName;
00182     // ending graph
00183 
00184     std::vector<ValueCallsType> path;
00185 
00186     ProgramCtx ctx;
00187     RegistryPtr registrySolver;
00188 
00189     void dataReset();
00190     bool foundCinPath(const ValueCallsType& C, const std::vector<ValueCallsType>& path, ValueCallsType& CPrev, int& PiSResult);
00191     int extractS(int PiS);
00192     int extractPi(int PiS);
00193     bool isEmptyInterpretation(int S);
00194     bool foundNotEmptyInst(const ValueCallsType& C);
00195     void unionCtoFront(ValueCallsType& C, const ValueCallsType& C2);
00196     std::string getAtomTextFromTuple(const Tuple& tuple);
00197 
00198     ID rewriteOrdinaryAtom(ID oldAtomID, int idxMI);
00199     ID rewriteModuleAtom(const ModuleAtom& oldAtom, int idxMI);
00200     ID rewritePredicate(const Predicate& oldPred, int idxMI);
00201     void rewriteTuple(Tuple& tuple, int idxMI);
00202     void createMiS(int instIdx, const InterpretationPtr& intr, InterpretationPtr& intrResult);
00203     void replacedModuleAtoms(int instIdx, InterpretationPtr& edb, Tuple& idb);
00204     void rewrite(const ValueCallsType& C, InterpretationPtr& edbResult, Tuple& idbResult);
00205 
00206     bool isOrdinary(const Tuple& idb);
00207     std::vector<int> foundMainModules();
00208     ValueCallsType createValueCallsMainModule(int idxModule);
00209     void assignFin(IDSet& t);
00210 
00211     void findAllModulesAtom(const Tuple& newRules, Tuple& result);
00212     bool containsPredName(const Tuple& tuple, const ID& id);
00213     ID getPredIDFromAtomID(const ID& atomID);
00214     bool defined(const Tuple& preds, const Tuple& ruleHead);
00215     void collectAllRulesDefined(ID predicate, const Tuple& rules, Tuple& predsSearched, Tuple& rulesResult);
00216     bool allPrepared(const ID& moduleAtom, const Tuple& rules);
00217     ID smallestILL(const Tuple& newRules);
00218     void addHeadOfModuleAtom(const Tuple& rules, IDSet& atomsForbid, IDSet& rulesForbid);
00219     bool tupleContainPredNameIDSet(const Tuple& tuple, const IDSet& idset);
00220     bool containID(ID id, const IDSet& idSet);
00221     void addTuplePredNameToIDSet(const Tuple& tuple, IDSet& idSet);
00222     void addTupleToIDSet(const Tuple& tuple, IDSet& idSet);
00223     void addHeadPredsForbid(const Tuple& rules, IDSet& atomsForbid, IDSet& rulesForbid);
00224     void IDSetToTuple(const IDSet& idSet, Tuple& result);
00225     void collectLargestBottom(const ModuleAtom& moduleAtom, const Tuple& rulesSource, Tuple& bottom, Tuple& top);
00226     void tupleMinus(const Tuple& source, const Tuple& minusTuple, Tuple& result);
00227     void collectBottom(const ModuleAtom& moduleAtom, const Tuple& rules, Tuple& result);
00228 
00229     void restrictionAndRenaming(const Interpretation& intr, const Tuple& actualInputs, const Tuple& formalInputs, Tuple& resultRestriction, Tuple& resultRenaming);
00230     void createInterpretationFromTuple(const Tuple& tuple, Interpretation& result);
00231     int addOrGetModuleIstantiation(const std::string& moduleName, const Interpretation& s);
00232     void resizeIfNeededA(int idxPjT);
00233     bool containFin(const std::vector<IDSet>& VectorOfIDSet, int idxPjT);
00234     int getInstIndexOfRule(const Rule& r);
00235     void updateTop(std::vector<IDSet>& Top, const Tuple& top);
00236     bool comp(ValueCallsType C); // return false if the program is not ic-stratified
00237 
00238     // for instantiation - ogatoms indexing
00239     std::vector<std::vector<ID> > instOgatoms;
00240     int totalSizeInstOgatoms;
00241     const Tuple& getOgatomsInInst(int instIdx);
00242 
00243     std::ofstream ofsGraph;
00244     std::ofstream ofsLog;
00245     bool printProgramInformation;
00246     int printLevel;
00247     bool writeLog;
00248     int nASReturned;
00249     int forget;
00250     int instSplitting;
00251     int recordingTime;
00252     double totalTimePost;
00253     double totalTimePartA;
00254     double totalTimeRewrite;
00255     double totalTimePartB;
00256     double totalTimePartC;
00257     double totalTimeCallDLV;
00258     double totalTimePushBack;
00259     double totalTimeCPathA;
00260     double totalTimeUpdateTop;
00261     int countB;
00262     int countC;
00263 
00264     void printValueCallsType(std::ostringstream& oss, const RegistryPtr& reg1, const ValueCallsType& C) const;
00265     void printPath(std::ostringstream& oss, const RegistryPtr& reg1, const std::vector<ValueCallsType>& path) const;
00266     void printA(std::ostringstream& oss, const RegistryPtr& reg1, const std::vector<IDSet>& A) const;
00267     void printModuleInst(std::ostream& out, const RegistryPtr& reg, int moduleInstIdx);
00268     void printASinSlot(std::ostream& out, const RegistryPtr& reg, const InterpretationPtr& intr);
00269     void printCallGraph(std::ostream& out, const Graph& graph, const std::string& graphLabel);
00270     void printIdb(const RegistryPtr& reg1, const Tuple& idb);
00271     void printEdbIdb(const RegistryPtr& reg1, const InterpretationPtr& edb, const Tuple& idb);
00272     void printProgram(const RegistryPtr& reg1, const InterpretationPtr& edb, const Tuple& idb);
00273 
00274     double startTime;            // in miliseconds
00275 
00276     public:
00277         int ctrAS;
00278         int ctrASFromDLV;
00279         int ctrCallToDLV;
00280         MLPSolver(ProgramCtx& ctx1);
00281         void setNASReturned(int n);
00282         void setForget(int n);
00283         void setInstSplitting(int n);
00284         void setPrintLevel(int level);
00285         bool solve();            // return false if the program is not ic-stratified
00286 
00287 };
00288 
00289 DLVHEX_NAMESPACE_END
00290 #endif                           /* _DLVHEX_MLPSOLVER_H */
00291 #endif
00292 
00293 // vim:expandtab:ts=4:sw=4:
00294 // mode: C++
00295 // End: