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 00034 #ifndef COMPONENT_GRAPH_HPP_INCLUDED__18102010 00035 #define COMPONENT_GRAPH_HPP_INCLUDED__18102010 00036 00037 #include "dlvhex2/DependencyGraph.h" 00038 00039 #include <boost/concept/assert.hpp> 00040 #include <boost/concept_check.hpp> 00041 #include "boost/tuple/tuple.hpp" 00042 00043 #ifndef NDEBUG 00044 # define COMPGRAPH_SOURCESDEBUG 00045 #endif 00046 00047 DLVHEX_NAMESPACE_BEGIN 00048 00071 class DLVHEX_EXPORT ComponentGraph 00072 { 00073 BOOST_CONCEPT_ASSERT((boost::Convertible<DependencyGraph::Node, unsigned int>)); 00075 // types 00077 public: 00079 struct DLVHEX_EXPORT ComponentInfo: 00080 public ostream_printable<ComponentInfo> 00081 { 00082 #ifdef COMPGRAPH_SOURCESDEBUG 00083 00084 std::list<DependencyGraph::Node> sources; 00085 #endif 00086 00088 std::vector<ID> outerEatoms; 00089 00091 std::vector<ID> innerRules; 00093 std::vector<ID> innerEatoms; 00095 std::vector<ID> innerConstraints; 00097 boost::unordered_map<ID, std::set<ID> > stronglySafeVariables; 00099 boost::unordered_map<ID, std::set<ID> > stratifiedLiterals; 00101 std::set<ID> predicatesDefinedInComponent; 00103 std::set<ID> predicatesOccurringInComponent; 00104 00105 // this is determined by calculateComponents 00106 // and used for selecting model generator factories 00108 bool disjunctiveHeads; 00110 bool negativeDependencyBetweenRules; 00112 bool innerEatomsNonmonotonic; 00114 bool outerEatomsNonmonotonic; 00116 bool componentIsMonotonic; 00118 bool fixedDomain; 00120 bool recursiveAggregates; 00121 00123 ComponentInfo(): 00124 disjunctiveHeads(false), 00125 negativeDependencyBetweenRules(false), 00126 innerEatomsNonmonotonic(false), 00127 outerEatomsNonmonotonic(false), 00128 componentIsMonotonic(true), 00129 fixedDomain(true), 00130 recursiveAggregates(false){} 00131 std::ostream& print(std::ostream& o) const; 00132 }; 00133 00135 struct DependencyInfo: 00136 public DependencyGraph::DependencyInfo, 00137 public ostream_printable<DependencyInfo> 00138 { 00139 #ifdef COMPGRAPH_SOURCESDEBUG 00140 00141 std::set<DependencyGraph::Dependency> sources; 00142 #endif 00143 00144 typedef boost::tuple<ID, ID, DependencyGraph::DependencyInfo> DepEdge; 00146 std::vector<DepEdge> depEdges; 00147 00149 DependencyInfo() {} 00152 DependencyInfo(const DependencyGraph::DependencyInfo& other): 00153 DependencyGraph::DependencyInfo(other) {} 00154 const DependencyInfo& operator|=(const DependencyInfo& other); 00155 std::ostream& print(std::ostream& o) const; 00156 }; 00157 00158 // we need listS because this graph will be changed a lot by collapsing nodes 00159 // use setS for out-edges because we don't want to have multiple edges 00160 typedef boost::adjacency_list< 00161 boost::setS, boost::listS, boost::bidirectionalS, 00162 ComponentInfo, DependencyInfo> Graph; 00163 typedef boost::graph_traits<Graph> Traits; 00164 00165 typedef Graph::vertex_descriptor Component; 00166 typedef Graph::edge_descriptor Dependency; 00167 typedef Traits::vertex_iterator ComponentIterator; 00168 typedef Traits::edge_iterator DependencyIterator; 00169 typedef Traits::out_edge_iterator PredecessorIterator; 00170 typedef Traits::in_edge_iterator SuccessorIterator; 00171 00172 typedef std::set<Component> ComponentSet; 00173 typedef std::map<Component, DependencyInfo> DepMap; 00174 00176 // members 00178 protected: 00180 ProgramCtx& ctx; 00182 RegistryPtr reg; 00183 #ifdef COMPGRAPH_SOURCESDEBUG 00184 00186 const DependencyGraph& dg; 00187 #endif 00188 00189 Graph cg; 00190 00192 // methods 00194 protected: 00199 ComponentGraph(const ComponentGraph& other); 00200 public: 00205 ComponentGraph(const DependencyGraph& dg, ProgramCtx& ctx, RegistryPtr reg); 00207 virtual ~ComponentGraph(); 00208 00211 ComponentGraph* clone() const; 00212 00213 // 00214 // modifiers 00215 // 00216 00217 // collapse several components into one 00218 // originals are put into new component and then removed 00219 // shared are just copied into new component 00220 Component collapseComponents( 00221 const ComponentSet& originals, const ComponentSet& shared=ComponentSet()); 00222 00223 // 00224 // mighty helper for collapsing components 00225 // 00226 00241 void computeCollapsedComponentInfos( 00242 const ComponentSet& comps, const ComponentSet& sharedcomps, 00243 DepMap& newIncomingDependencies, DepMap& newOutgoingDependencies, 00244 // see comment above about const! 00245 ComponentInfo& newComponentInfo) const; 00246 00247 // 00248 // accessors 00249 // 00250 00251 // get const graph to apply external algorithms 00252 inline const Graph& getInternalGraph() 00253 const { return cg; } 00254 00258 virtual void writeGraphViz(std::ostream& o, bool verbose) const; 00259 00262 inline std::pair<ComponentIterator, ComponentIterator> getComponents() const 00263 { return boost::vertices(cg); } 00266 inline std::pair<DependencyIterator, DependencyIterator> getDependencies() const 00267 { return boost::edges(cg); } 00268 00273 inline const ComponentInfo& getComponentInfo(Component c) const 00274 { return cg[c]; } 00275 00279 inline const DependencyInfo& getDependencyInfo(Dependency dep) const 00280 { return cg[dep]; } 00281 00285 inline std::pair<PredecessorIterator, PredecessorIterator> 00286 getDependencies(Component c) const 00287 { return boost::out_edges(c, cg); } 00288 00292 inline std::pair<SuccessorIterator, SuccessorIterator> 00293 getProvides(Component c) const 00294 { return boost::in_edges(c, cg); } 00295 00299 inline Component sourceOf(Dependency d) const 00300 { return boost::source(d, cg); } 00301 00305 inline Component targetOf(Dependency d) const 00306 { return boost::target(d, cg); } 00307 00311 inline const ComponentInfo& propsOf(Component c) const 00312 { return cg[c]; } 00316 inline ComponentInfo& propsOf(Component c) 00317 { return cg[c]; } 00321 inline const DependencyInfo& propsOf(Dependency d) const 00322 { return cg[d]; } 00326 inline DependencyInfo& propsOf(Dependency d) 00327 { return cg[d]; } 00328 00329 // counting -> mainly for allocating and testing 00332 inline unsigned countComponents() const 00333 { return boost::num_vertices(cg); } 00336 inline unsigned countDependencies() const 00337 { return boost::num_edges(cg); } 00338 00339 // 00340 // helpers 00341 // 00342 protected: 00343 // helpers for writeGraphViz: extend for more output 00349 virtual void writeGraphVizComponentLabel(std::ostream& o, Component c, unsigned index, bool verbose) const; 00354 virtual void writeGraphVizDependencyLabel(std::ostream& o, Dependency dep, bool verbose) const; 00355 00356 protected: 00357 // helpers for constructor 00360 void calculateComponents(const DependencyGraph& dg); 00361 00365 bool calculateFixedDomain(ComponentInfo& ci) const; 00369 bool computeRecursiveAggregatesInComponent(ComponentInfo& ci) const; 00370 00371 public: 00375 static void calculateStratificationInfo(RegistryPtr reg, ComponentInfo& ci); 00379 static void calculatePredicatesOfComponent(RegistryPtr reg, ComponentInfo& ci); 00380 }; 00381 00382 DLVHEX_NAMESPACE_END 00383 #endif // DEPENDENCY_GRAPH_HPP_INCLUDED__18102010 00384 00385 // vim:expandtab:ts=4:sw=4: 00386 // mode: C++ 00387 // End: