dlvhex  2.5.0
src/ID.cpp
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 #ifdef HAVE_CONFIG_H
00035 #include "config.h"
00036 #endif                           // HAVE_CONFIG_H
00037 
00038 #include "dlvhex2/ID.h"
00039 #include <boost/functional/hash.hpp>
00040 #include <iomanip>
00041 
00042 DLVHEX_NAMESPACE_BEGIN
00043 
00044 std::size_t hash_value(const ID& id)
00045 {
00046     std::size_t seed = 0;
00047     boost::hash_combine(seed, id.kind);
00048     boost::hash_combine(seed, id.address);
00049     return seed;
00050 }
00051 
00052 
00053 std::ostream& ID::print(std::ostream& o) const
00054 {
00055     if( *this == ID_FAIL )
00056         return o << "ID_FAIL";
00057     o << "ID(0x" <<
00058         std::setfill('0') << std::hex << std::setw(8) << kind << "," << std::setfill(' ') <<
00059         std::dec << std::setw(4) << address;
00060 
00061     if( !!(kind & NAF_MASK) )
00062         o << " naf";
00063     const unsigned MAINKIND_MAX = 4;
00064     const char* mainkinds[MAINKIND_MAX] = {
00065         " atom",
00066         " term",
00067         " literal",
00068         " rule",
00069     };
00070     const unsigned mainkind = (kind & MAINKIND_MASK) >> MAINKIND_SHIFT;
00071     assert(mainkind < MAINKIND_MAX);
00072     o << mainkinds[mainkind];
00073 
00074     const unsigned SUBKIND_MAX = 11;
00075     const char* subkinds[MAINKIND_MAX][SUBKIND_MAX] = {
00076         { " ordinary_ground", " ordinary_nonground", " builtin",         " aggregate", "", "", " external", "", "", "", " module"},
00077         { " constant",        " integer",            " variable",        " builtin",   " predicate", " nested", ""          },
00078         { " ordinary_ground", " ordinary_nonground", " builtin",         " aggregate", "", "", " external", "", "", "", " module"},
00079         { " regular",         " constraint",         " weak_constraint", "weight_rule",           "", "", ""          }
00080     };
00081     const unsigned subkind = (kind & SUBKIND_MASK) >> SUBKIND_SHIFT;
00082     assert(subkind < SUBKIND_MAX);
00083     assert(subkinds[mainkind][subkind][0] != 0);
00084     o << subkinds[mainkind][subkind];
00085     return o << ")";
00086 }
00087 
00088 
00089 // returns builtin term ID
00090 // static
00091 ID ID::termFromBuiltinString(const std::string& op)
00092 {
00093     assert(!op.empty());
00094     switch(op.size()) {
00095         case 1:
00096             switch(op[0]) {
00097                 case '=': return ID::termFromBuiltin(ID::TERM_BUILTIN_EQ);
00098                 case '<': return ID::termFromBuiltin(ID::TERM_BUILTIN_LT);
00099                 case '>': return ID::termFromBuiltin(ID::TERM_BUILTIN_GT);
00100                 case '*': return ID::termFromBuiltin(ID::TERM_BUILTIN_MUL);
00101                 case '+': return ID::termFromBuiltin(ID::TERM_BUILTIN_ADD);
00102                 case '-': return ID::termFromBuiltin(ID::TERM_BUILTIN_SUB);
00103                 case '/': return ID::termFromBuiltin(ID::TERM_BUILTIN_DIV);
00104                 default: assert(false); return ID_FAIL;
00105             }
00106         case 2:
00107             if( op == "==" ) {
00108                 return ID::termFromBuiltin(ID::TERM_BUILTIN_EQ);
00109             }
00110             else if( op == "!=" || op == "<>" ) {
00111                 return ID::termFromBuiltin(ID::TERM_BUILTIN_NE);
00112             }
00113             else if( op == "<=" ) {
00114                 return ID::termFromBuiltin(ID::TERM_BUILTIN_LE);
00115             }
00116             else if( op == ">=" ) {
00117                 return ID::termFromBuiltin(ID::TERM_BUILTIN_GE);
00118             }
00119             else {
00120                 assert(false); return ID_FAIL;
00121             }
00122     }
00123     if( op == "#succ" )
00124         { return ID::termFromBuiltin(ID::TERM_BUILTIN_SUCC); }
00125         else if( op == "#int" )
00126             { return ID::termFromBuiltin(ID::TERM_BUILTIN_INT); }
00127             else if( op == "#count" )
00128                 { return ID::termFromBuiltin(ID::TERM_BUILTIN_AGGCOUNT); }
00129                 else if( op == "#min" )
00130                     { return ID::termFromBuiltin(ID::TERM_BUILTIN_AGGMIN); }
00131                     else if( op == "#max" )
00132                         { return ID::termFromBuiltin(ID::TERM_BUILTIN_AGGMAX); }
00133                         else if( op == "#sum" )
00134                             { return ID::termFromBuiltin(ID::TERM_BUILTIN_AGGSUM); }
00135                             else if( op == "#times" )
00136                                 { return ID::termFromBuiltin(ID::TERM_BUILTIN_AGGTIMES); }
00137                                 else if( op == "#avg" )
00138                                     { return ID::termFromBuiltin(ID::TERM_BUILTIN_AGGAVG); }
00139                                     else if( op == "#any" )
00140                                         { return ID::termFromBuiltin(ID::TERM_BUILTIN_AGGANY); }
00141                                         else if( op == "#mod" )
00142                                             { return ID::termFromBuiltin(ID::TERM_BUILTIN_MOD); }
00143                                         else {
00144                                             assert(false);
00145         return ID_FAIL;
00146     }
00147 }
00148 
00149 
00150 namespace
00151 {
00152     const char* builtinTerms[] = {
00153         "=",
00154         "!=",
00155         "<",
00156         "<=",
00157         ">",
00158         ">=",
00159         "*",
00160         "+",
00161         "-",
00162         "/",
00163         "#count",
00164         "#min",
00165         "#max",
00166         "#sum",
00167         "#times",
00168         "#avg",
00169         "#any",
00170         "#int",
00171         "#succ",
00172         "#mod",
00173     };
00174 }
00175 
00176 
00177 const char* ID::stringFromBuiltinTerm(IDAddress addr)
00178 {
00179     assert(addr < (sizeof(builtinTerms)/sizeof(const char*)));
00180     return builtinTerms[addr];
00181 }
00182 
00183 
00184 DLVHEX_NAMESPACE_END
00185 
00186 // vim:expandtab:ts=4:sw=4:
00187 // mode: C++
00188 // End: