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 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: