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 TERMTABLE_HPP_INCLUDED__12102010 00035 #define TERMTABLE_HPP_INCLUDED__12102010 00036 00037 #include "dlvhex2/PlatformDefinitions.h" 00038 #include "dlvhex2/Logger.h" 00039 #include "dlvhex2/ID.h" 00040 #include "dlvhex2/Term.h" 00041 #include "dlvhex2/Table.h" 00042 00043 #include <boost/multi_index/member.hpp> 00044 #include <boost/multi_index/hashed_index.hpp> 00045 #include <boost/multi_index/random_access_index.hpp> 00046 00047 DLVHEX_NAMESPACE_BEGIN 00048 00050 class TermTable: 00051 public Table< 00052 // value type is symbol struct 00053 Term, 00054 // index is 00055 boost::multi_index::indexed_by< 00056 // address = running ID for constant access 00057 boost::multi_index::random_access< 00058 boost::multi_index::tag<impl::AddressTag> 00059 >, 00060 // unique IDs for unique symbol strings 00061 boost::multi_index::hashed_unique< 00062 boost::multi_index::tag<impl::TermTag>, 00063 BOOST_MULTI_INDEX_MEMBER(Term,std::string,symbol) 00064 > 00065 > 00066 > 00067 { 00068 // types 00069 public: 00070 typedef Container::index<impl::AddressTag>::type AddressIndex; 00071 typedef Container::index<impl::TermTag>::type TermIndex; 00072 00073 // methods 00074 public: 00082 inline const Term& getByID(ID id) const throw (); 00083 00088 inline ID getIDByString(const std::string& str) const throw(); 00089 00096 inline ID storeAndGetID(const Term& symb) throw(); 00097 00098 // retrieve range by kind (return lower/upper bound iterators, +provide method to get ID from iterator) 00099 }; 00100 00101 // retrieve by ID 00102 // assert that id.kind is correct for Term 00103 // assert that ID exists 00104 const Term& 00105 TermTable::getByID( 00106 ID id) const throw () 00107 { 00108 assert(id.isTerm()); 00109 // integers are not allowed in this table! 00110 assert(id.isConstantTerm() || id.isVariableTerm() || id.isNestedTerm()); 00111 ReadLock lock(mutex); 00112 const AddressIndex& idx = container.get<impl::AddressTag>(); 00113 // the following check only works for random access indices, but here it is ok 00114 assert( id.address < idx.size() ); 00115 return idx.at(id.address); 00116 } 00117 00118 00119 // given string, look if already stored 00120 // if no, return ID_FAIL, otherwise return ID 00121 ID TermTable::getIDByString( 00122 const std::string& str) const throw() 00123 { 00124 typedef Container::index<impl::TermTag>::type TermIndex; 00125 ReadLock lock(mutex); 00126 const TermIndex& sidx = container.get<impl::TermTag>(); 00127 TermIndex::const_iterator it = sidx.find(str); 00128 if( it == sidx.end() ) 00129 return ID_FAIL; 00130 else { 00131 const AddressIndex& aidx = container.get<impl::AddressTag>(); 00132 return ID( 00133 it->kind, // kind 00134 // address 00135 container.project<impl::AddressTag>(it) - aidx.begin() 00136 ); 00137 } 00138 } 00139 00140 00141 #if 0 00142 // given an argument vector, look if already stored 00143 // if no, return ID_FAIL, otherwise return ID 00144 ID TermTable::getIDByArguments( 00145 const std::vector<ID>& args) const throw() 00146 { 00147 typedef Container::index<impl::TupleTag>::type ArgIndex; 00148 ReadLock lock(mutex); 00149 const ArgIndex& sidx = container.get<impl::TupleTag>(); 00150 ArgIndex::const_iterator it = sidx.find(args); 00151 if( it == sidx.end() ) 00152 return ID_FAIL; 00153 else { 00154 const AddressIndex& aidx = container.get<impl::AddressTag>(); 00155 return ID( 00156 it->kind, // kind 00157 // address 00158 container.project<impl::AddressTag>(it) - aidx.begin() 00159 ); 00160 } 00161 } 00162 #endif 00163 00164 // store symbol, assuming it does not exist 00165 // assert that symbol did not exist 00166 ID TermTable::storeAndGetID( 00167 const Term& symb) throw() 00168 { 00169 assert(ID(symb.kind,0).isTerm()); 00170 // integers are not allowed in this table! 00171 assert(ID(symb.kind,0).isConstantTerm() || ID(symb.kind,0).isVariableTerm() || ID(symb.kind,0).isNestedTerm()); 00172 assert(!symb.symbol.empty()); 00173 00174 bool success; 00175 AddressIndex::const_iterator it; 00176 00177 WriteLock lock(mutex); 00178 AddressIndex& idx = container.get<impl::AddressTag>(); 00179 boost::tie(it, success) = idx.push_back(symb); 00180 (void)success; 00181 assert(success); 00182 00183 return ID( 00184 symb.kind, // kind 00185 // address 00186 container.project<impl::AddressTag>(it) - idx.begin() 00187 ); 00188 } 00189 00190 00191 DLVHEX_NAMESPACE_END 00192 #endif // TERMTABLE_HPP_INCLUDED__12102010 00193 00194 // vim:expandtab:ts=4:sw=4: 00195 // mode: C++ 00196 // End: