dlvhex  2.5.0
include/dlvhex2/ComponentGraph.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 
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: