dlvhex  2.5.0
src/EvalGraphBuilder.cpp
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 #ifdef HAVE_CONFIG_H
00035 #include "config.h"
00036 #endif                           // HAVE_CONFIG_H
00037 
00038 #include "dlvhex2/EvalGraphBuilder.h"
00039 #include "dlvhex2/PlainModelGenerator.h"
00040 #include "dlvhex2/WellfoundedModelGenerator.h"
00041 #include "dlvhex2/GuessAndCheckModelGenerator.h"
00042 #include "dlvhex2/GenuinePlainModelGenerator.h"
00043 #include "dlvhex2/GenuineWellfoundedModelGenerator.h"
00044 #include "dlvhex2/GenuineGuessAndCheckModelGenerator.h"
00045 #include "dlvhex2/Logger.h"
00046 #include "dlvhex2/Registry.h"
00047 #include "dlvhex2/ProgramCtx.h"
00048 #include "dlvhex2/PluginInterface.h"
00049 
00050 #include <boost/range/iterator_range.hpp>
00051 
00052 #include <sstream>
00053 
00054 DLVHEX_NAMESPACE_BEGIN
00055 
00056 namespace
00057 {
00058     typedef ComponentGraph::ComponentSet ComponentSet;
00059     typedef ComponentGraph::ComponentInfo ComponentInfo;
00060     typedef ComponentGraph::DependencyInfo DependencyInfo;
00061     typedef ComponentGraph::DepMap DepMap;
00062 }
00063 
00064 
00065 EvalGraphBuilder::EvalGraphBuilder(
00066 ProgramCtx& ctx,
00067 ComponentGraph& cg,
00068 EvalGraphT& eg,
00069 ASPSolverManager::SoftwareConfigurationPtr externalEvalConfig):
00070 ctx(ctx),
00071 clonedcgptr(cg.clone()),
00072 cg(*clonedcgptr),
00073 eg(eg),
00074 externalEvalConfig(externalEvalConfig),
00075 mapping(),
00076 unusedEdgeFilter(&cg, &mapping),
00077 unusedVertexFilter(&mapping),
00078 cgrest(cg.getInternalGraph(), unusedEdgeFilter, unusedVertexFilter)
00079 {
00080 }
00081 
00082 
00083 EvalGraphBuilder::~EvalGraphBuilder()
00084 {
00085 }
00086 
00087 
00088 RegistryPtr EvalGraphBuilder::registry()
00089 {
00090     return ctx.registry();
00091 }
00092 
00093 
00094 namespace
00095 {
00096     typedef FinalEvalGraph::EvalUnitPropertyBundle EvalUnitProperties;
00097     typedef FinalEvalGraph::EvalUnitDepPropertyBundle EvalUnitDepProperties;
00098 
00099     EvalUnitProperties eup_empty;
00100 }
00101 
00102 
00103 EvalGraphBuilder::Component EvalGraphBuilder::getComponentForUnit(EvalGraphBuilder::EvalUnit u) const
00104 {
00105     ComponentEvalUnitMapping::right_map::const_iterator it =
00106         mapping.right.find(u);
00107     if( it == mapping.right.end() )
00108         throw std::runtime_error("tried to get component for unit not created here!");
00109     return it->second;
00110 }
00111 
00112 
00113 EvalGraphBuilder::EvalUnit
00114 EvalGraphBuilder::createEvalUnit(
00115 const std::list<Component>& comps, const std::list<Component>& ccomps)
00116 {
00117     LOG_SCOPE(ANALYZE,"cEU",true);
00118     if( Logger::Instance().shallPrint(Logger::DBG) ) {
00119         DBGLOG(DBG,"= EvalGraphBuilder::createEvalUnit(" << printrange(comps) << "," << printrange(ccomps) << ")");
00120         BOOST_FOREACH(Component c, comps) {
00121             const ComponentInfo& ci = cg.propsOf(c);
00122             if( !ci.innerEatoms.empty() )
00123                 DBGLOG(DBG," compi " << printManyToString<RawPrinter>(ci.innerEatoms, ",", registry()));
00124             if( !ci.outerEatoms.empty() )
00125                 DBGLOG(DBG," compo " << printManyToString<RawPrinter>(ci.outerEatoms, ",", registry()));
00126             if( !ci.innerRules.empty() )
00127                 DBGLOG(DBG," compr " << printManyToString<RawPrinter>(ci.innerRules, "\n", registry()));
00128             if( !ci.innerConstraints.empty() )
00129                 DBGLOG(DBG," compc " << printManyToString<RawPrinter>(ci.innerConstraints, "\n", registry()));
00130         }
00131         BOOST_FOREACH(Component c, ccomps) {
00132             const ComponentInfo& ci = cg.propsOf(c);
00133             assert( ci.innerRules.empty() && ci.innerEatoms.empty() && ci.outerEatoms.empty() );
00134             if( !ci.innerConstraints.empty() )
00135                 DBGLOG(DBG," ccompc " << printManyToString<RawPrinter>(ci.innerConstraints, "\n", registry()));
00136         }
00137     }
00138 
00139     // collapse components into new eval unit
00140     // (this verifies necessary conditions and computes new dependencies)
00141     Component newComp;
00142     {
00143         // TODO perhaps directly take ComponentSet as inputs
00144         ComponentSet scomps(comps.begin(), comps.end());
00145         ComponentSet sccomps(ccomps.begin(), ccomps.end());
00146         newComp = cg.collapseComponents(scomps, sccomps);
00147     }
00148     const ComponentInfo& newUnitInfo = cg.propsOf(newComp);
00149 
00150     // create eval unit
00151     EvalUnit u = eg.addUnit(eup_empty);
00152     LOG(DBG,"created unit " << u << " for new comp " << newComp);
00153 
00154     // associate new comp with eval unit
00155     {
00156         typedef ComponentEvalUnitMapping::value_type MappedPair;
00157         bool success = mapping.insert(MappedPair(newComp, u)).second;
00158         assert(success);         // component must not already exist here
00159     }
00160 
00161     // configure unit
00162     EvalUnitProperties& uprops = eg.propsOf(u);
00163 
00164     // configure model generator factory, depending on type of component
00165     {
00166         const ComponentGraph::ComponentInfo& ci = newUnitInfo;
00167 
00168         if (!!ctx.customModelGeneratorProvider) {
00169             LOG(DBG,"configuring custom model generator factory for eval unit " << u);
00170             uprops.mgf = ctx.customModelGeneratorProvider->getCustomModelGeneratorFactory(ctx, ci);
00171         }
00172         else {
00173             if( ci.innerEatoms.empty() && !ctx.config.getOption("ForceGC") ) {
00174                 // no inner external atoms -> plain model generator factory
00175                 LOG(DBG,"configuring plain model generator factory for eval unit " << u);
00176                 if (ctx.config.getOption("GenuineSolver") > 0) {
00177                     uprops.mgf.reset(new GenuinePlainModelGeneratorFactory(
00178                         ctx, ci, externalEvalConfig));
00179                 }
00180                 else {
00181                     uprops.mgf.reset(new PlainModelGeneratorFactory(
00182                         ctx, ci, externalEvalConfig));
00183                 }
00184             }
00185             else {
00186                 if( !ci.innerEatomsNonmonotonic && !ci.recursiveAggregates && !ci.negativeDependencyBetweenRules && !ci.disjunctiveHeads && !ctx.config.getOption("ForceGC") ) {
00187                     // inner external atoms and only in positive cycles and monotonic and no disjunctive rules
00188                     // -> wellfounded/fixpoint model generator factory
00189                     LOG(DBG,"configuring wellfounded model generator factory for eval unit " << u);
00190                     if (ctx.config.getOption("GenuineSolver") > 0) {
00191                         uprops.mgf.reset(new GenuineWellfoundedModelGeneratorFactory(
00192                             ctx, ci, externalEvalConfig));
00193                     }
00194                     else {
00195                         uprops.mgf.reset(new WellfoundedModelGeneratorFactory(
00196                             ctx, ci, externalEvalConfig));
00197                     }
00198                 }
00199                 else {
00200                     // everything else -> guess and check model generator factory
00201                     LOG(DBG,"configuring guess and check model generator factory for eval unit " << u);
00202                     if (ctx.config.getOption("GenuineSolver") > 0) {
00203                         uprops.mgf.reset(new GenuineGuessAndCheckModelGeneratorFactory(
00204                             ctx, ci, externalEvalConfig));
00205                     }
00206                     else {
00207                         uprops.mgf.reset(new GuessAndCheckModelGeneratorFactory(
00208                             ctx, ci, externalEvalConfig));
00209                     }
00210                 }
00211             }
00212         }
00213     }
00214 
00215     // create dependencies
00216     unsigned joinOrder = 0;      // TODO define join order in a more intelligent way?
00217     ComponentGraph::PredecessorIterator dit, dend;
00218     for(boost::tie(dit, dend) = cg.getDependencies(newComp);
00219     dit != dend; dit++) {
00220         Component tocomp = cg.targetOf(*dit);
00221 
00222         // get eval unit corresponding to tocomp
00223         ComponentEvalUnitMapping::left_map::iterator itdo =
00224             mapping.left.find(tocomp);
00225         assert(itdo != mapping.left.end());
00226         EvalUnit dependsOn = itdo->second;
00227 
00228         const DependencyInfo& di = cg.propsOf(*dit);
00229         DBGLOG(DBG,"adding dependency to unit " << dependsOn << " with joinOrder " << joinOrder);
00230         eg.addDependency(u, dependsOn, EvalUnitDepProperties(joinOrder));
00231         joinOrder++;
00232     }
00233 
00234     return u;
00235 }
00236 
00237 
00238 DLVHEX_NAMESPACE_END
00239 
00240 
00241 // vim:expandtab:ts=4:sw=4:
00242 // mode: C++
00243 // End: