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 RULETABLE_HPP_INCLUDED__12102010 00035 #define RULETABLE_HPP_INCLUDED__12102010 00036 00037 #include "dlvhex2/PlatformDefinitions.h" 00038 #include "dlvhex2/fwd.h" 00039 #include "dlvhex2/Rule.h" 00040 #include "dlvhex2/Table.h" 00041 00042 #include <boost/multi_index/hashed_index.hpp> 00043 #include <boost/multi_index/member.hpp> 00044 #include <boost/multi_index/random_access_index.hpp> 00045 #include <boost/multi_index/ordered_index.hpp> 00046 #include <boost/multi_index/composite_key.hpp> 00047 00048 DLVHEX_NAMESPACE_BEGIN 00049 00051 class RuleTable: 00052 public Table< 00053 // value type is symbol struct 00054 Rule, 00055 // index is 00056 boost::multi_index::indexed_by< 00057 // address = running ID for constant access 00058 boost::multi_index::random_access< 00059 boost::multi_index::tag<impl::AddressTag> 00060 >, 00061 // kind 00062 boost::multi_index::ordered_non_unique< 00063 boost::multi_index::tag<impl::KindTag>, 00064 BOOST_MULTI_INDEX_MEMBER(Rule,IDKind,kind) 00065 >, 00066 // element 00067 boost::multi_index::hashed_unique< 00068 boost::multi_index::tag<impl::ElementTag>, 00069 boost::multi_index::composite_key< 00070 Rule, 00071 BOOST_MULTI_INDEX_MEMBER(Rule,IDKind,kind), 00072 BOOST_MULTI_INDEX_MEMBER(Rule,Tuple,head), 00073 BOOST_MULTI_INDEX_MEMBER(Rule,Tuple,body), 00074 BOOST_MULTI_INDEX_MEMBER(Rule,Tuple,headGuard), 00075 BOOST_MULTI_INDEX_MEMBER(Rule,Tuple,bodyWeightVector), 00076 BOOST_MULTI_INDEX_MEMBER(Rule,ID,bound), 00077 BOOST_MULTI_INDEX_MEMBER(Rule,ID,weight), 00078 BOOST_MULTI_INDEX_MEMBER(Rule,ID,level), 00079 BOOST_MULTI_INDEX_MEMBER(Rule,Tuple,weakconstraintVector) 00080 > 00081 > 00082 > 00083 > 00084 { 00085 // types 00086 public: 00087 typedef Container::index<impl::AddressTag>::type AddressIndex; 00088 typedef Container::index<impl::KindTag>::type KindIndex; 00089 typedef Container::index<impl::ElementTag>::type ElementIndex; 00090 typedef AddressIndex::iterator AddressIterator; 00091 typedef ElementIndex::iterator ElementIterator; 00092 // methods 00093 public: 00100 inline const Rule& getByID(ID id) const throw (); 00101 00105 inline ID getIDByElement(const Rule& rule) const throw(); 00106 00113 inline ID storeAndGetID(const Rule& rule) throw(); 00115 inline void clear(); 00116 00123 inline void update( 00124 const Rule& oldStorage, Rule& newStorage) throw(); 00125 00133 std::ostream& print(std::ostream& o, RegistryPtr reg) const throw(); 00134 00139 inline std::pair<AddressIterator, AddressIterator> 00140 getAllByAddress() const throw(); 00141 }; 00142 00143 // retrieve by ID 00144 // assert that id.kind is correct for Rule 00145 // assert that ID exists 00146 const Rule& 00147 RuleTable::getByID( 00148 ID id) const throw () 00149 { 00150 assert(id.isRule()); 00151 assert(id.isRegularRule() || id.isConstraint() || id.isWeakConstraint() || id.isWeightRule()); 00152 ReadLock lock(mutex); 00153 const AddressIndex& idx = container.get<impl::AddressTag>(); 00154 // the following check only works for random access indices, but here it is ok 00155 assert( id.address < idx.size() ); 00156 return idx.at(id.address); 00157 } 00158 00159 00160 // getID by rule 00161 ID RuleTable::getIDByElement(const Rule& rule) const throw() 00162 { 00163 ReadLock lock(mutex); 00164 const ElementIndex& sidx = container.get<impl::ElementTag>(); 00165 ElementIndex::const_iterator it = sidx.find( boost::make_tuple(rule.kind, rule.head, rule.body, rule.headGuard, rule.bodyWeightVector, rule.bound, rule.weight, rule.level, rule.weakconstraintVector) ); 00166 if( it == sidx.end() ) 00167 return ID_FAIL; 00168 else { 00169 const AddressIndex& aidx = container.get<impl::AddressTag>(); 00170 return ID( 00171 it->kind, // kind 00172 // address 00173 container.project<impl::AddressTag>(it) - aidx.begin() 00174 ); 00175 } 00176 } 00177 00178 00179 // store rule 00180 ID RuleTable::storeAndGetID( 00181 const Rule& rule) throw() 00182 { 00183 assert(ID(rule.kind,0).isRule()); 00184 assert(ID(rule.kind,0).isRegularRule() || 00185 ID(rule.kind,0).isConstraint() || 00186 ID(rule.kind,0).isWeakConstraint() || 00187 ID(rule.kind,0).isWeightRule()); 00188 assert(!(rule.head.empty() && rule.body.empty())); 00189 assert(!(rule.head.empty() && ID(rule.kind,0).isRegularRule())); 00190 assert(!(rule.head.size() > 1 && !ID(rule.kind,0).isRuleDisjunctive())); 00191 00192 AddressIndex::const_iterator it; 00193 bool success; 00194 00195 WriteLock lock(mutex); 00196 AddressIndex& idx = container.get<impl::AddressTag>(); 00197 boost::tie(it, success) = idx.push_back(rule); 00198 (void)success; 00199 assert(success); 00200 00201 return ID( 00202 rule.kind, // kind 00203 // address 00204 container.project<impl::AddressTag>(it) - idx.begin() 00205 ); 00206 } 00207 00208 00209 void RuleTable::clear() 00210 { 00211 WriteLock lock(mutex); 00212 container.clear(); 00213 } 00214 00215 00216 void RuleTable::update( 00217 const Rule& oldStorage, Rule& newStorage) throw() 00218 { 00219 bool success; 00220 00221 WriteLock lock(mutex); 00222 AddressIndex& idx = container.get<impl::AddressTag>(); 00223 AddressIndex::iterator it(idx.iterator_to(oldStorage)); 00224 assert(it != idx.end()); 00225 success = idx.replace(it, newStorage); 00226 (void)success; 00227 assert(success); 00228 } 00229 00230 00231 // get range over all rules sorted by address 00232 // NOTE: you may need to lock the mutex also while iterating! 00233 std::pair<RuleTable::AddressIterator, RuleTable::AddressIterator> 00234 RuleTable::getAllByAddress() const throw() 00235 { 00236 ReadLock lock(mutex); 00237 const AddressIndex& idx = container.get<impl::AddressTag>(); 00238 return std::make_pair(idx.begin(), idx.end()); 00239 } 00240 00241 00242 DLVHEX_NAMESPACE_END 00243 #endif // RULETABLE_HPP_INCLUDED__12102010 00244 00245 // vim:expandtab:ts=4:sw=4: 00246 // mode: C++ 00247 // End: