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/ExtSourceProperties.h" 00039 #include "dlvhex2/Atoms.h" 00040 #include "dlvhex2/PluginInterface.h" 00041 00042 #include "boost/lexical_cast.hpp" 00043 00044 DLVHEX_NAMESPACE_BEGIN 00045 00046 ExtSourceProperties& ExtSourceProperties::operator|=(const ExtSourceProperties& prop2) 00047 { 00048 monotonicInputPredicates.insert(prop2.monotonicInputPredicates.begin(), prop2.monotonicInputPredicates.end()); 00049 antimonotonicInputPredicates.insert(prop2.antimonotonicInputPredicates.begin(), prop2.antimonotonicInputPredicates.end()); 00050 predicateParameterNameIndependence.insert(prop2.predicateParameterNameIndependence.begin(), prop2.predicateParameterNameIndependence.end()); 00051 finiteOutputDomain.insert(prop2.finiteOutputDomain.begin(), prop2.finiteOutputDomain.end()); 00052 relativeFiniteOutputDomain.insert(prop2.relativeFiniteOutputDomain.begin(), prop2.relativeFiniteOutputDomain.end()); 00053 functional |= prop2.functional; 00054 functionalStart = functionalStart > prop2.functionalStart ? functionalStart : prop2.functionalStart; 00055 atomlevellinear |= prop2.atomlevellinear; 00056 tuplelevellinear |= prop2.tuplelevellinear; 00057 usesEnvironment |= prop2.usesEnvironment; 00058 finiteFiber |= prop2.finiteFiber; 00059 BOOST_FOREACH (int i, prop2.finiteOutputDomain) finiteOutputDomain.insert(i); 00060 wellorderingStrlen.insert(prop2.wellorderingStrlen.begin(), prop2.wellorderingStrlen.end()); 00061 wellorderingNatural.insert(prop2.wellorderingNatural.begin(), prop2.wellorderingNatural.end()); 00062 onlySafeSupportSets |= prop2.onlySafeSupportSets; 00063 supportSets |= prop2.supportSets; 00064 completePositiveSupportSets |= prop2.completePositiveSupportSets; 00065 completeNegativeSupportSets |= prop2.completeNegativeSupportSets; 00066 variableOutputArity |= prop2.variableOutputArity; 00067 caresAboutAssigned |= prop2.caresAboutAssigned; 00068 caresAboutChanged |= prop2.caresAboutChanged; 00069 providesPartialAnswer |= prop2.providesPartialAnswer; 00070 return *this; 00071 } 00072 00076 bool ExtSourceProperties::isMonotonic() const 00077 { 00078 00079 PluginAtom* pa = ea ? ea->pluginAtom : this->pa; 00080 assert (pa); 00081 const std::vector<PluginAtom::InputType>& it = pa->getInputTypes(); 00082 int i = 0; 00083 BOOST_FOREACH (PluginAtom::InputType t, it) { 00084 if (t == PluginAtom::PREDICATE && !isMonotonic(i)) return false; 00085 i++; 00086 } 00087 return true; 00088 } 00089 00090 00094 bool ExtSourceProperties::isAntimonotonic() const 00095 { 00096 00097 PluginAtom* pa = ea ? ea->pluginAtom : this->pa; 00098 assert (pa); 00099 const std::vector<PluginAtom::InputType>& it = pa->getInputTypes(); 00100 int i = 0; 00101 BOOST_FOREACH (PluginAtom::InputType t, it) { 00102 if (t == PluginAtom::PREDICATE && !isAntimonotonic(i)) return false; 00103 i++; 00104 } 00105 return true; 00106 } 00107 00111 bool ExtSourceProperties::isNonmonotonic() const 00112 { 00113 return !isMonotonic(); 00114 } 00115 00116 void ExtSourceProperties::interpretProperties(RegistryPtr reg, const ExternalAtom& atom, const std::vector<std::vector<std::string> >& props) 00117 { 00118 00119 DBGLOG(DBG, "Interpreting external source properties"); 00120 typedef std::vector<std::string> Prop; 00121 BOOST_FOREACH (Prop p, props) { 00122 // parameter interpretation 00123 ID param1 = ID_FAIL; 00124 ID param2 = ID_FAIL; 00125 if (p.size() > 1) { 00126 try 00127 { 00128 param1 = ID::termFromInteger(boost::lexical_cast<int>(p[1])); 00129 } 00130 catch(boost::bad_lexical_cast&) { 00131 param1 = reg->storeConstantTerm(p[1]); 00132 } 00133 } 00134 if (p.size() > 2) { 00135 try 00136 { 00137 param2 = ID::termFromInteger(boost::lexical_cast<int>(p[2])); 00138 } 00139 catch(boost::bad_lexical_cast&) { 00140 param2 = reg->storeConstantTerm(p[2]); 00141 } 00142 } 00143 00144 // property interpretation 00145 std::string name = p[0]; 00146 if (name == "functional") { 00147 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"functional\" expects no parameters"); 00148 DBGLOG(DBG, "External Atom is functional"); 00149 functional = true; 00150 } 00151 else if (name == "monotonic") { 00152 if (param2 != ID_FAIL) throw GeneralError("Property \"monotonic\" expects less than two parameters"); 00153 if (param1 == ID_FAIL) { 00154 DBGLOG(DBG, "External Atom is monotonic in all input parameters"); 00155 for (uint32_t i = 0; i < atom.inputs.size(); ++i) { 00156 monotonicInputPredicates.insert(i); 00157 } 00158 } 00159 else { 00160 bool found = false; 00161 for (uint32_t i = 0; i < atom.inputs.size(); ++i) { 00162 if (atom.inputs[i] == param1) { 00163 DBGLOG(DBG, "External Atom is monotonic in parameter " << i); 00164 monotonicInputPredicates.insert(i); 00165 found = true; 00166 break; 00167 } 00168 } 00169 if (!found) throw SyntaxError("Property refers to invalid input parameter"); 00170 } 00171 } 00172 else if (name == "antimonotonic") { 00173 if (param2 != ID_FAIL) throw GeneralError("Property \"antimonotonic\" expects less than two parameters"); 00174 if (param1 == ID_FAIL) { 00175 DBGLOG(DBG, "External Atom is antimonotonic in all input parameters"); 00176 for (uint32_t i = 0; i < atom.inputs.size(); ++i) { 00177 antimonotonicInputPredicates.insert(i); 00178 } 00179 } 00180 else { 00181 bool found = false; 00182 for (uint32_t i = 0; i < atom.inputs.size(); ++i) { 00183 if (atom.inputs[i] == param1) { 00184 DBGLOG(DBG, "External Atom is antimonotonic in parameter " << i); 00185 antimonotonicInputPredicates.insert(i); 00186 found = true; 00187 break; 00188 } 00189 } 00190 if (!found) throw SyntaxError("Property refers to invalid input parameter"); 00191 } 00192 } 00193 else if (name == "atomlevellinear" || name == "fullylinear") { 00194 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"atomlevellinear\" expects no parameters"); 00195 DBGLOG(DBG, "External Atom is linear on atom level"); 00196 atomlevellinear = true; 00197 } 00198 else if (name == "tuplelevellinear") { 00199 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"tuplelevellinear\" expects no parameters"); 00200 DBGLOG(DBG, "External Atom is linear on tuple level"); 00201 tuplelevellinear = true; 00202 } 00203 else if (name == "usesenvironment") { 00204 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"usesenvironment\" expects no parameters"); 00205 DBGLOG(DBG, "External Atom uses environment"); 00206 usesEnvironment = true; 00207 } 00208 else if (name == "finitedomain") { 00209 if (param2 != ID_FAIL) throw GeneralError("Property \"finitedomain\" expects less than two parameters"); 00210 if (param1 == ID_FAIL) { 00211 DBGLOG(DBG, "External Atom has a finite domain in all output positions"); 00212 for (uint32_t i = 0; i < atom.tuple.size(); ++i) { 00213 finiteOutputDomain.insert(i); 00214 } 00215 } 00216 else { 00217 bool found = false; 00218 if (!param1.isIntegerTerm()) throw GeneralError("The parameter of property \"finitedomain\" must be an integer"); 00219 finiteOutputDomain.insert(param1.address); 00220 } 00221 } 00222 else if (name == "relativefinitedomain") { 00223 if (param1 == ID_FAIL || param2 == ID_FAIL) throw GeneralError("Property \"relativefinitedomain\" expects two parameters"); 00224 int wrt; 00225 bool found = false; 00226 for (uint32_t i = 0; i < atom.inputs.size(); ++i) { 00227 if (atom.inputs[i] == param2) { 00228 wrt = i; 00229 found = true; 00230 break; 00231 } 00232 } 00233 if (!found) throw SyntaxError("Property refers to invalid input parameter"); 00234 if (!param1.isIntegerTerm()) throw GeneralError("The first parameter of property \"relativefinitedomain\" must be an integer"); 00235 relativeFiniteOutputDomain.insert(std::pair<int, int>(param1.address, wrt)); 00236 } 00237 else if (name == "finitefiber") { 00238 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"finitefiber\" expects no parameters"); 00239 DBGLOG(DBG, "External Atom has a finite fiber"); 00240 finiteFiber = true; 00241 } 00242 else if (name == "wellorderingstrlen") { 00243 if (param1 == ID_FAIL || param2 == ID_FAIL) throw GeneralError("Property \"wellordering\" expects two parameters"); 00244 DBGLOG(DBG, "External Atom has a wellordering using strlen"); 00245 wellorderingStrlen.insert(std::pair<int, int>(param1.address, param2.address)); 00246 } 00247 else if (name == "wellordering") { 00248 if (param1 == ID_FAIL || param2 == ID_FAIL) throw GeneralError("Property \"wellordering\" expects two parameters"); 00249 DBGLOG(DBG, "External Atom has a wellordering using natural"); 00250 wellorderingNatural.insert(std::pair<int, int>(param1.address, param2.address)); 00251 } 00252 else if (name == "onlysafesupportsets") { 00253 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"onlysafesupportsets\" expects no parameters"); 00254 DBGLOG(DBG, "External Atom provides only safe support sets"); 00255 onlySafeSupportSets = true; 00256 } 00257 else if (name == "supportsets") { 00258 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"supportsets\" expects no parameters"); 00259 DBGLOG(DBG, "External Atom provides support sets"); 00260 supportSets = true; 00261 } 00262 else if (name == "completepositivesupportsets") { 00263 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"completepositivesupportsets\" expects no parameters"); 00264 DBGLOG(DBG, "External Atom provides complete positive support sets"); 00265 supportSets = true; 00266 completePositiveSupportSets = true; 00267 } 00268 else if (name == "completenegativesupportsets") { 00269 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"completepositivesupportsets\" expects no parameters"); 00270 DBGLOG(DBG, "External Atom provides complete negative support sets"); 00271 supportSets = true; 00272 completeNegativeSupportSets = true; 00273 } 00274 else if (name == "variableoutputarity") { 00275 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"variableoutputarity\" expects no parameters"); 00276 DBGLOG(DBG, "External Atom has a variable output arity"); 00277 variableOutputArity = true; 00278 } 00279 else if (name == "caresaboutassigned") { 00280 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"caresaboutassigned\" expects no parameters"); 00281 DBGLOG(DBG, "External Atom cares about assigned atoms"); 00282 caresAboutAssigned = true; 00283 } 00284 else if (name == "caresaboutchanged") { 00285 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"caresaboutchanged\" expects no parameters"); 00286 DBGLOG(DBG, "External Atom has a variable output arity"); 00287 caresAboutChanged = true; 00288 } 00289 else if (name == "providespartialanswer") { 00290 if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"providesPartialAnswer\" expects no parameters"); 00291 DBGLOG(DBG, "External Atom provides partial answer"); 00292 providesPartialAnswer = true; 00293 } 00294 else { 00295 throw SyntaxError("Property \"" + name + "\" unrecognized"); 00296 } 00297 } 00298 } 00299 00300 00301 DLVHEX_NAMESPACE_END 00302 00303 // vim:expandtab:ts=4:sw=4: 00304 // mode: C++ 00305 // End: