dlvhex  2.5.0
include/dlvhex2/TermTable.h
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 #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: