dlvhex  2.5.0
include/dlvhex2/ID.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 ID_HPP_INCLUDED__08102010
00035 #define ID_HPP_INCLUDED__08102010
00036 
00037 #include "dlvhex2/PlatformDefinitions.h"
00038 #include "dlvhex2/Printhelpers.h"
00039 
00040 DLVHEX_NAMESPACE_BEGIN
00041 
00042 typedef uint32_t IDKind;
00043 typedef uint32_t IDAddress;
00044 
00056 struct DLVHEX_EXPORT ID:
00057 private ostream_printable<ID>
00058 {
00069     IDKind kind;
00071     IDAddress address;
00073     ID(): kind(ALL_ONES), address(ALL_ONES) {}
00078     ID(IDKind kind, IDAddress address): kind(kind), address(address) {}
00079     // no virtual here!
00080     // this struct must fit into an uint64_t and have no vtable!
00081 
00083     static const uint32_t ALL_ONES =             0xFFFFFFFF;
00084 
00086     static const IDKind NAF_MASK =               0x80000000;
00088     static const IDKind MAINKIND_MASK =          0x70000000;
00090     static const uint8_t MAINKIND_SHIFT =        28;
00092     static const IDKind SUBKIND_MASK =           0x0F000000;
00094     static const uint8_t SUBKIND_SHIFT =         24;
00096     static const IDKind PROPERTY_MASK =          0x00FF0000;
00098     static const uint8_t PROPERTY_SHIFT =        16;
00100     static const IDKind UNUSED_MASK =            0x0000FFFF;
00101 
00103     static const IDKind MAINKIND_ATOM =          0x00000000;
00105     static const IDKind MAINKIND_TERM =          0x10000000;
00107     static const IDKind MAINKIND_LITERAL =       0x20000000;
00109     static const IDKind MAINKIND_RULE =          0x30000000;
00110 
00112     static const IDKind SUBKIND_TERM_CONSTANT =  0x00000000;
00114     static const IDKind SUBKIND_TERM_INTEGER =   0x01000000;
00116     static const IDKind SUBKIND_TERM_VARIABLE =  0x02000000;
00118     static const IDKind SUBKIND_TERM_BUILTIN =   0x03000000;
00120     static const IDKind SUBKIND_TERM_PREDICATE = 0x04000000;
00122     static const IDKind SUBKIND_TERM_NESTED =    0x05000000;
00123 
00125     static const IDKind SUBKIND_ATOM_ORDINARYG = 0x00000000;
00127     static const IDKind SUBKIND_ATOM_ORDINARYN = 0x01000000;
00129     static const IDKind SUBKIND_ATOM_BUILTIN =   0x02000000;
00131     static const IDKind SUBKIND_ATOM_AGGREGATE = 0x03000000;
00133     static const IDKind SUBKIND_ATOM_EXTERNAL =  0x06000000;
00135     static const IDKind SUBKIND_ATOM_MODULE =    0x0A000000;
00136 
00138     static const IDKind SUBKIND_RULE_REGULAR =        0x00000000;
00140     static const IDKind SUBKIND_RULE_CONSTRAINT =     0x01000000;
00142     static const IDKind SUBKIND_RULE_WEAKCONSTRAINT = 0x02000000;
00144                                  // lparse weight rules (not to be confused with weak constraints!)
00145     static const IDKind SUBKIND_RULE_WEIGHT =         0x03000000;
00146 
00153     static const IDKind PROPERTY_ATOM_HIDDEN     = 0x00010000;
00154 
00156     static const IDKind PROPERTY_VAR_ANONYMOUS   = 0x00010000;
00158     static const IDKind PROPERTY_RULE_EXTATOMS   = 0x00080000;
00160     static const IDKind PROPERTY_RULE_DISJ       = 0x00100000;
00162     static const IDKind PROPERTY_RULE_HEADGUARD  = 0x00300000;
00164     static const IDKind PROPERTY_RULE_MODATOMS   = 0x00400000;
00166     static const IDKind PROPERTY_RULE_UNMODATOMS = 0xFFBFFFFF;
00168     static const IDKind PROPERTY_TERM_RANGE =     0x00010000;
00169 
00176     static const IDKind PROPERTY_AUX             = 0x00800000;
00183     static const IDKind PROPERTY_EXTERNALAUX     = 0x00400000;
00190     static const IDKind PROPERTY_EXTERNALINPUTAUX= 0x00200000;
00202     static const IDKind PROPERTY_GUARDAUX   = 0x00A00000;
00204     static const IDKind PROPERTY_FLPAUX     = 0x00100000;
00205 
00211     enum TermBuiltinAddress
00212     {
00213         // first we have the infix builtins (see isInfixBuiltin)
00215         TERM_BUILTIN_EQ,
00217         TERM_BUILTIN_NE,
00219         TERM_BUILTIN_LT,
00221         TERM_BUILTIN_LE,
00223         TERM_BUILTIN_GT,
00225         TERM_BUILTIN_GE,
00227         TERM_BUILTIN_MUL,
00229         TERM_BUILTIN_ADD,
00231         TERM_BUILTIN_SUB,
00233         TERM_BUILTIN_DIV,
00234         // then the prefix builtins (see isInfixBuiltin)
00236         TERM_BUILTIN_AGGCOUNT,
00238         TERM_BUILTIN_AGGMIN,
00240         TERM_BUILTIN_AGGMAX,
00242         TERM_BUILTIN_AGGSUM,
00244         TERM_BUILTIN_AGGTIMES,
00246         TERM_BUILTIN_AGGAVG,
00248         TERM_BUILTIN_AGGANY,
00250         TERM_BUILTIN_INT,
00252         TERM_BUILTIN_SUCC,
00254         TERM_BUILTIN_MOD,
00255     };
00256 
00262     static inline IDAddress reverseBinaryOperator(IDAddress op) {
00263         // reverse operator if necessary (< switches with >, <= switches with >=)
00264         switch(static_cast<IDAddress>(op)) {
00265             case ID::TERM_BUILTIN_LT: return ID::TERM_BUILTIN_GT;
00266             case ID::TERM_BUILTIN_LE: return ID::TERM_BUILTIN_GE;
00267             case ID::TERM_BUILTIN_GT: return ID::TERM_BUILTIN_LT;
00268             case ID::TERM_BUILTIN_GE: return ID::TERM_BUILTIN_LE;
00269             case ID::TERM_BUILTIN_EQ: return ID::TERM_BUILTIN_EQ;
00270             case ID::TERM_BUILTIN_NE: return ID::TERM_BUILTIN_NE;
00271             default:
00272                 return op;
00273         }
00274     }
00275 
00282     static inline IDAddress negateBinaryOperator(IDAddress op) {
00283         // reverse operator if necessary (< switches with >, <= switches with >=)
00284         switch(static_cast<IDAddress>(op)) {
00285             case ID::TERM_BUILTIN_LT: return ID::TERM_BUILTIN_GE;
00286             case ID::TERM_BUILTIN_LE: return ID::TERM_BUILTIN_GT;
00287             case ID::TERM_BUILTIN_GT: return ID::TERM_BUILTIN_LE;
00288             case ID::TERM_BUILTIN_GE: return ID::TERM_BUILTIN_LT;
00289             case ID::TERM_BUILTIN_EQ: return ID::TERM_BUILTIN_NE;
00290             case ID::TERM_BUILTIN_NE: return ID::TERM_BUILTIN_EQ;
00291             default:
00292                 return op;
00293         }
00294     }
00295 
00301     static inline ID termFromInteger(uint32_t i)
00302         { return ID(ID::MAINKIND_TERM | ID::SUBKIND_TERM_INTEGER, i); }
00303 
00309     static inline ID termFromBuiltin(TermBuiltinAddress b)
00310         { return ID(ID::MAINKIND_TERM | ID::SUBKIND_TERM_BUILTIN, b); }
00311 
00319     static ID termFromBuiltinString(const std::string& op);
00320 
00328     static const char* stringFromBuiltinTerm(IDAddress addr);
00329 
00335     static inline ID posLiteralFromAtom(ID atom)
00336         { assert(atom.isAtom()); return ID(atom.kind | MAINKIND_LITERAL, atom.address); }
00337 
00343     static inline ID nafLiteralFromAtom(ID atom)
00344         { assert(atom.isAtom()); return ID(atom.kind | MAINKIND_LITERAL | NAF_MASK, atom.address); }
00345 
00352     static inline ID literalFromAtom(ID atom, bool naf)
00353         { assert(atom.isAtom()); return (naf?nafLiteralFromAtom(atom):posLiteralFromAtom(atom)); }
00354 
00360     static inline ID atomFromLiteral(ID literal) {
00361         assert(literal.isLiteral());
00362         return ID((literal.kind & (~(NAF_MASK|MAINKIND_MASK))) | MAINKIND_ATOM, literal.address);
00363     }
00366     inline bool isTerm() const          { return (kind & MAINKIND_MASK) == MAINKIND_TERM; }
00371     inline bool isConstantTerm() const  { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_CONSTANT; }
00376     inline bool isIntegerTerm() const   { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_INTEGER; }
00381     inline bool isVariableTerm() const  { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_VARIABLE; }
00386     inline bool isBuiltinTerm() const   { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_BUILTIN; }
00391     inline bool isPredicateTerm() const { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_PREDICATE; }
00396     inline bool isNestedTerm() const { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_NESTED; }
00401     inline bool isRangeTerm() const { assert(isTerm()); return (kind & PROPERTY_MASK) == PROPERTY_TERM_RANGE; }
00402 
00405     inline bool isAtom() const          { return (kind & MAINKIND_MASK) == MAINKIND_ATOM; }
00410     inline bool isHiddenAtom() const  { assert(isAtom() || isLiteral()); return (kind & PROPERTY_ATOM_HIDDEN) == PROPERTY_ATOM_HIDDEN; }
00415     inline bool isOrdinaryAtom() const  { assert(isAtom() || isLiteral()); return (kind & SUBKIND_ATOM_BUILTIN) != SUBKIND_ATOM_BUILTIN; }
00420     inline bool isOrdinaryGroundAtom() const     { assert(isAtom() || isLiteral()); return !(kind & SUBKIND_MASK); }
00425     inline bool isOrdinaryNongroundAtom() const  { assert(isAtom() || isLiteral()); return (kind & SUBKIND_MASK) == SUBKIND_ATOM_ORDINARYN; }
00430     inline bool isBuiltinAtom() const   { assert(isAtom() || isLiteral()); return (kind & SUBKIND_MASK) == SUBKIND_ATOM_BUILTIN; }
00435     inline bool isAggregateAtom() const { assert(isAtom() || isLiteral()); return (kind & SUBKIND_MASK) == SUBKIND_ATOM_AGGREGATE; }
00440     inline bool isExternalAtom() const  { assert(isAtom() || isLiteral()); return (kind & SUBKIND_MASK) == SUBKIND_ATOM_EXTERNAL; }
00445     inline bool isModuleAtom() const    { assert(isAtom() || isLiteral()); return (kind & SUBKIND_MASK) == SUBKIND_ATOM_MODULE; }
00449     inline bool isLiteral() const       { return (kind & MAINKIND_MASK) == MAINKIND_LITERAL; }
00453     inline bool isNaf() const           { return (kind & NAF_MASK) == NAF_MASK; }
00457     inline bool isAuxiliary() const     { return (kind & PROPERTY_AUX) == PROPERTY_AUX; }
00461     inline bool isExternalAuxiliary() const     { return (kind & PROPERTY_EXTERNALAUX) == PROPERTY_EXTERNALAUX; }
00465     inline bool isExternalInputAuxiliary() const     { return (kind & PROPERTY_EXTERNALINPUTAUX) == PROPERTY_EXTERNALINPUTAUX; }
00469     inline bool isGuardAuxiliary() const     { return (kind & PROPERTY_GUARDAUX) == PROPERTY_GUARDAUX; }
00473     inline bool isFLPAuxiliary() const     { return (kind & PROPERTY_FLPAUX) == PROPERTY_FLPAUX; }
00474 
00478     inline bool isRule() const          { return (kind & MAINKIND_MASK) == MAINKIND_RULE; }
00484     inline bool isRegularRule() const   { assert(isRule()); return (kind & SUBKIND_MASK) == SUBKIND_RULE_REGULAR; }
00490     inline bool isConstraint() const    { assert(isRule()); return (kind & SUBKIND_MASK) == SUBKIND_RULE_CONSTRAINT; }
00496     inline bool isWeakConstraint() const{ assert(isRule()); return (kind & SUBKIND_MASK) == SUBKIND_RULE_WEAKCONSTRAINT; }
00502     inline bool isWeightRule() const    { assert(isRule()); return (kind & SUBKIND_MASK) == SUBKIND_RULE_WEIGHT; }
00503 
00509     inline bool doesRuleContainExtatoms() const{ assert(isRule()); return (kind & PROPERTY_RULE_EXTATOMS) == PROPERTY_RULE_EXTATOMS; }
00515     inline bool doesRuleContainModatoms() const{ assert(isRule()); return (kind & PROPERTY_RULE_MODATOMS) == PROPERTY_RULE_MODATOMS; }
00521     inline bool isRuleDisjunctive() const { assert(isRule()); return (kind & PROPERTY_RULE_DISJ) == PROPERTY_RULE_DISJ; }
00527     inline bool hasRuleHeadGuard() const { assert(isRule()); return (kind & PROPERTY_RULE_HEADGUARD) == PROPERTY_RULE_HEADGUARD; }
00533     inline bool isAnonymousVariable() const { assert(isVariableTerm()); return (kind & PROPERTY_VAR_ANONYMOUS) == PROPERTY_VAR_ANONYMOUS; }
00534 
00539     inline bool operator==(const ID& id2) const { return kind == id2.kind && address == id2.address; }
00544     inline bool operator!=(const ID& id2) const { return kind != id2.kind || address != id2.address; }
00549     inline ID operator|(const ID& id2) const    { return ID(kind | id2.kind, address | id2.address); }
00554     inline ID operator&(const ID& id2) const    { return ID(kind & id2.kind, address & id2.address); }
00556     inline operator uint64_t() const            { return *reinterpret_cast<const uint64_t*>(this); }
00557 
00563     std::ostream& print(std::ostream& o) const;
00564 };
00565 
00566 DLVHEX_EXPORT std::size_t hash_value(const ID& id);
00567 
00568 const ID ID_FAIL(ID::ALL_ONES, ID::ALL_ONES);
00569 
00570 typedef std::vector<ID> Tuple;
00571 
00572 DLVHEX_NAMESPACE_END
00573 #endif                           // ID_HPP_INCLUDED__08102010
00574 
00575 // vim:expandtab:ts=4:sw=4:
00576 // mode: C++
00577 // End: