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 #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: