dlvhex  2.1.0
include/dlvhex2/ID.h
Go to the documentation of this file.
00001 /* dlvhex -- Answer-Set Programming with external interfaces.
00002  * Copyright (C) 2005, 2006, 2007 Roman Schindlauer
00003  * Copyright (C) 2006, 2007, 2008, 2009, 2010 Thomas Krennwallner
00004  * Copyright (C) 2009, 2010 Peter Schüller
00005  * 
00006  * This file is part of dlvhex.
00007  *
00008  * dlvhex is free software; you can redistribute it and/or modify it
00009  * under the terms of the GNU Lesser General Public License as
00010  * published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * dlvhex is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with dlvhex; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00021  * 02110-1301 USA.
00022  */
00023 
00031 #ifndef ID_HPP_INCLUDED__08102010
00032 #define ID_HPP_INCLUDED__08102010
00033 
00034 #include "dlvhex2/PlatformDefinitions.h"
00035 #include "dlvhex2/Printhelpers.h"
00036 
00037 DLVHEX_NAMESPACE_BEGIN
00038 
00039 typedef uint32_t IDKind;
00040 typedef uint32_t IDAddress;
00041 
00042 struct ID:
00043   private ostream_printable<ID>
00044 {
00045     IDKind kind;
00046     IDAddress address;
00047     ID(): kind(ALL_ONES), address(ALL_ONES) {}
00048     ID(IDKind kind, IDAddress address): kind(kind), address(address) {}
00049     // no virtual here!
00050     // this struct must fit into an uint64_t and have no vtable!
00051 
00052     static const uint32_t ALL_ONES =             0xFFFFFFFF;
00053 
00054     static const IDKind NAF_MASK =               0x80000000;
00055     static const IDKind MAINKIND_MASK =          0x70000000;
00056     static const uint8_t MAINKIND_SHIFT =        28;
00057     static const IDKind SUBKIND_MASK =           0x0F000000;
00058     static const uint8_t SUBKIND_SHIFT =         24;
00059     static const IDKind PROPERTY_MASK =          0x00FF0000;
00060     static const uint8_t PROPERTY_SHIFT =        16;
00061     static const IDKind UNUSED_MASK =            0x0000FFFF;
00062 
00063     static const IDKind MAINKIND_ATOM =          0x00000000;
00064     static const IDKind MAINKIND_TERM =          0x10000000;
00065     static const IDKind MAINKIND_LITERAL =       0x20000000;
00066     static const IDKind MAINKIND_RULE =          0x30000000;
00067 
00068     static const IDKind SUBKIND_TERM_CONSTANT =  0x00000000;
00069     static const IDKind SUBKIND_TERM_INTEGER =   0x01000000;
00070     static const IDKind SUBKIND_TERM_VARIABLE =  0x02000000;
00071     static const IDKind SUBKIND_TERM_BUILTIN =   0x03000000;
00072     static const IDKind SUBKIND_TERM_PREDICATE = 0x04000000;
00073 
00074     static const IDKind SUBKIND_ATOM_ORDINARYG = 0x00000000;
00075     static const IDKind SUBKIND_ATOM_ORDINARYN = 0x01000000;
00076     static const IDKind SUBKIND_ATOM_BUILTIN =   0x02000000;
00077     static const IDKind SUBKIND_ATOM_AGGREGATE = 0x03000000;
00078 // 6 and A -> check -> because of method isOrdinaryAtom that masked ID with builtin != builtin
00079     static const IDKind SUBKIND_ATOM_EXTERNAL =  0x06000000;
00080     static const IDKind SUBKIND_ATOM_MODULE =    0x0A000000;
00081 
00082     static const IDKind SUBKIND_RULE_REGULAR =        0x00000000;
00083     static const IDKind SUBKIND_RULE_CONSTRAINT =     0x01000000;
00084     static const IDKind SUBKIND_RULE_WEAKCONSTRAINT = 0x02000000;
00085     static const IDKind SUBKIND_RULE_WEIGHT =         0x03000000;   // lparse weight rules (not to be confused with weak constraints!)
00086 
00087     //                                             0x00FF0000
00088     static const IDKind PROPERTY_ATOM_HIDDEN     = 0x00010000;  // hidden atoms are skipped when printed for the user and excluded from predicate masks
00089                                     // the property is used for a large number of temporary atoms needed in the UFS check
00090                                     // (this would otherwise slow down predicate masks in the whole system)
00091     static const IDKind PROPERTY_VAR_ANONYMOUS   = 0x00010000;
00092     static const IDKind PROPERTY_RULE_EXTATOMS   = 0x00080000;
00093     static const IDKind PROPERTY_RULE_DISJ       = 0x00100000;
00094     static const IDKind PROPERTY_RULE_MODATOMS   = 0x00400000;
00095     static const IDKind PROPERTY_RULE_UNMODATOMS = 0xFFBFFFFF;
00096     static const IDKind PROPERTY_AUX             = 0x00800000;
00097     static const IDKind PROPERTY_EXTERNALAUX     = 0x00400000;  // used for auxiliaries which represent external atoms
00098                                     // (the genuine solver needs to distinct them from other auxiliaries like HO-, strong negation-replacements and EA-input)
00099     static const IDKind PROPERTY_EXTERNALINPUTAUX= 0x00200000;  // used for auxiliaries which represent aux input to external atoms
00100                                     // (the genuine solver needs to distinct them from other auxiliaries like HO-, strong negation-replacements and EA-input)
00101 
00102   // for builtin terms, this is the address part (no table)
00103   // beware: must be synchronized with isInfixBuiltin() and builtinTerms[]
00104   enum TermBuiltinAddress
00105   {
00106     // first we have the infix builtins (see isInfixBuiltin)
00107     TERM_BUILTIN_EQ,
00108     TERM_BUILTIN_NE,
00109     TERM_BUILTIN_LT,
00110     TERM_BUILTIN_LE,
00111     TERM_BUILTIN_GT,
00112     TERM_BUILTIN_GE,
00113     TERM_BUILTIN_MUL,
00114     TERM_BUILTIN_ADD,
00115     TERM_BUILTIN_SUB,
00116     TERM_BUILTIN_DIV,
00117     // then the prefix builtins (see isInfixBuiltin)
00118     TERM_BUILTIN_AGGCOUNT,
00119     TERM_BUILTIN_AGGMIN,
00120     TERM_BUILTIN_AGGMAX,
00121     TERM_BUILTIN_AGGSUM,
00122     TERM_BUILTIN_AGGTIMES,
00123     TERM_BUILTIN_AGGAVG,
00124     TERM_BUILTIN_AGGANY,
00125     TERM_BUILTIN_INT,
00126     TERM_BUILTIN_SUCC,
00127     TERM_BUILTIN_MOD,
00128   };
00129   
00130   static inline ID termFromInteger(uint32_t i)
00131     { return ID(ID::MAINKIND_TERM | ID::SUBKIND_TERM_INTEGER, i); }
00132   static inline ID termFromBuiltin(TermBuiltinAddress b)
00133     { return ID(ID::MAINKIND_TERM | ID::SUBKIND_TERM_BUILTIN, b); }
00134   static ID termFromBuiltinString(const std::string& op);
00135   static const char* stringFromBuiltinTerm(IDAddress addr);
00136   static inline ID posLiteralFromAtom(ID atom)
00137     { assert(atom.isAtom()); return ID(atom.kind | MAINKIND_LITERAL, atom.address); }
00138   static inline ID nafLiteralFromAtom(ID atom)
00139     { assert(atom.isAtom()); return ID(atom.kind | MAINKIND_LITERAL | NAF_MASK, atom.address); }
00140   static inline ID literalFromAtom(ID atom, bool naf)
00141     { assert(atom.isAtom()); return (naf?nafLiteralFromAtom(atom):posLiteralFromAtom(atom)); }
00142   static inline ID atomFromLiteral(ID literal)
00143     { assert(literal.isLiteral());
00144             return ID((literal.kind & (~(NAF_MASK|MAINKIND_MASK))) | MAINKIND_ATOM, literal.address); }
00145 
00146     inline bool isTerm() const          { return (kind & MAINKIND_MASK) == MAINKIND_TERM; }
00147     inline bool isConstantTerm() const  { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_CONSTANT; }
00148     inline bool isIntegerTerm() const   { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_INTEGER; }
00149     inline bool isVariableTerm() const  { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_VARIABLE; }
00150     inline bool isBuiltinTerm() const   { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_BUILTIN; }
00151     inline bool isPredicateTerm() const   { assert(isTerm()); return (kind & SUBKIND_MASK) == SUBKIND_TERM_PREDICATE; }
00152 
00153     inline bool isAtom() const          { return (kind & MAINKIND_MASK) == MAINKIND_ATOM; }
00154   // true for ground or nonground ordinary atoms
00155   // (special bit trick)
00156     inline bool isHiddenAtom() const  { assert(isAtom() || isLiteral()); return (kind & PROPERTY_ATOM_HIDDEN) == PROPERTY_ATOM_HIDDEN; }
00157     inline bool isOrdinaryAtom() const  { assert(isAtom() || isLiteral()); return (kind & SUBKIND_ATOM_BUILTIN) != SUBKIND_ATOM_BUILTIN; }
00158     inline bool isOrdinaryGroundAtom() const     { assert(isAtom() || isLiteral()); return !(kind & SUBKIND_MASK); }
00159     inline bool isOrdinaryNongroundAtom() const  { assert(isAtom() || isLiteral()); return (kind & SUBKIND_MASK) == SUBKIND_ATOM_ORDINARYN; }
00160     inline bool isBuiltinAtom() const   { assert(isAtom() || isLiteral()); return (kind & SUBKIND_MASK) == SUBKIND_ATOM_BUILTIN; }
00161     inline bool isAggregateAtom() const { assert(isAtom() || isLiteral()); return (kind & SUBKIND_MASK) == SUBKIND_ATOM_AGGREGATE; }
00162     inline bool isExternalAtom() const  { assert(isAtom() || isLiteral()); return (kind & SUBKIND_MASK) == SUBKIND_ATOM_EXTERNAL; }
00163     inline bool isModuleAtom() const    { assert(isAtom() || isLiteral()); return (kind & SUBKIND_MASK) == SUBKIND_ATOM_MODULE; }
00164 
00165     inline bool isLiteral() const       { return (kind & MAINKIND_MASK) == MAINKIND_LITERAL; }
00166     inline bool isNaf() const           { return (kind & NAF_MASK) == NAF_MASK; }
00167     inline bool isAuxiliary() const     { return (kind & PROPERTY_AUX) == PROPERTY_AUX; }
00168     inline bool isExternalAuxiliary() const     { return (kind & PROPERTY_EXTERNALAUX) == PROPERTY_EXTERNALAUX; }
00169     inline bool isExternalInputAuxiliary() const     { return (kind & PROPERTY_EXTERNALINPUTAUX) == PROPERTY_EXTERNALINPUTAUX; }
00170   
00171     inline bool isRule() const          { return (kind & MAINKIND_MASK) == MAINKIND_RULE; }
00172     inline bool isRegularRule() const   { assert(isRule()); return (kind & SUBKIND_MASK) == SUBKIND_RULE_REGULAR; }
00173     inline bool isConstraint() const    { assert(isRule()); return (kind & SUBKIND_MASK) == SUBKIND_RULE_CONSTRAINT; }
00174     inline bool isWeakConstraint() const{ assert(isRule()); return (kind & SUBKIND_MASK) == SUBKIND_RULE_WEAKCONSTRAINT; }
00175     inline bool isWeightRule() const    { assert(isRule()); return (kind & SUBKIND_MASK) == SUBKIND_RULE_WEIGHT; }
00176 
00177     inline bool doesRuleContainExtatoms() const{ assert(isRule()); return (kind & PROPERTY_RULE_EXTATOMS) == PROPERTY_RULE_EXTATOMS; }
00178     inline bool doesRuleContainModatoms() const{ assert(isRule()); return (kind & PROPERTY_RULE_MODATOMS) == PROPERTY_RULE_MODATOMS; }
00179     inline bool isRuleDisjunctive() const { assert(isRule()); return (kind & PROPERTY_RULE_DISJ) == PROPERTY_RULE_DISJ; }
00180     inline bool isAnonymousVariable() const { assert(isVariableTerm()); return (kind & PROPERTY_VAR_ANONYMOUS) == PROPERTY_VAR_ANONYMOUS; }
00181 
00182     inline bool operator==(const ID& id2) const { return kind == id2.kind && address == id2.address; }
00183     inline bool operator!=(const ID& id2) const { return kind != id2.kind || address != id2.address; }
00184     inline ID operator|(const ID& id2) const    { return ID(kind | id2.kind, address | id2.address); }
00185     inline ID operator&(const ID& id2) const    { return ID(kind & id2.kind, address & id2.address); }
00186     inline operator uint64_t() const            { return *reinterpret_cast<const uint64_t*>(this); }
00187 
00188     std::ostream& print(std::ostream& o) const;
00189 };
00190 
00191 std::size_t hash_value(const ID& id);
00192 
00193 const ID ID_FAIL(ID::ALL_ONES, ID::ALL_ONES);
00194 
00195 typedef std::vector<ID> Tuple;
00196 
00197 DLVHEX_NAMESPACE_END
00198 
00199 #endif // ID_HPP_INCLUDED__08102010