|
| 1 | +/* |
| 2 | + * Souffle - A Datalog Compiler |
| 3 | + * Copyright (c) 2023, The Souffle Developers. All rights reserved |
| 4 | + * Licensed under the Universal Permissive License v 1.0 as shown at: |
| 5 | + * - https://opensource.org/licenses/UPL |
| 6 | + * - <souffle root>/licenses/SOUFFLE-UPL.txt |
| 7 | + */ |
| 8 | + |
| 9 | +#include "ast/Lattice.h" |
| 10 | +#include "souffle/utility/MiscUtil.h" |
| 11 | +#include "souffle/utility/StreamUtil.h" |
| 12 | + |
| 13 | +#include <utility> |
| 14 | + |
| 15 | +namespace souffle::ast { |
| 16 | + |
| 17 | +std::optional<LatticeOperator> latticeOperatorFromString(const std::string& str) { |
| 18 | + if (str == "Bottom") return Bottom; |
| 19 | + if (str == "Top") return Top; |
| 20 | + if (str == "Lub") return Lub; |
| 21 | + if (str == "Glb") return Glb; |
| 22 | + if (str == "Leq") return Leq; |
| 23 | + return std::nullopt; |
| 24 | +} |
| 25 | + |
| 26 | +std::string latticeOperatorToString(const LatticeOperator op) { |
| 27 | + switch (op) { |
| 28 | + case Bottom: return "Bottom"; |
| 29 | + case Top: return "Top"; |
| 30 | + case Lub: return "Lub"; |
| 31 | + case Glb: return "Glb"; |
| 32 | + case Leq: return "Leq"; |
| 33 | + default: assert(false && "unknown lattice operator"); |
| 34 | + } |
| 35 | + return ""; |
| 36 | +} |
| 37 | + |
| 38 | +Lattice::Lattice(QualifiedName name, std::map<LatticeOperator, Own<ast::Argument>> ops, SrcLocation loc) |
| 39 | + : Node(std::move(loc)), name(std::move(name)), operators(std::move(ops)) {} |
| 40 | + |
| 41 | +void Lattice::setQualifiedName(QualifiedName name) { |
| 42 | + this->name = std::move(name); |
| 43 | +} |
| 44 | + |
| 45 | +const std::map<LatticeOperator, const ast::Argument*> Lattice::getOperators() const { |
| 46 | + std::map<LatticeOperator, const ast::Argument*> ops; |
| 47 | + for (const auto& [op, arg] : operators) { |
| 48 | + ops.emplace(std::make_pair(op, arg.get())); |
| 49 | + } |
| 50 | + return ops; |
| 51 | +} |
| 52 | + |
| 53 | +bool Lattice::hasGlb() const { |
| 54 | + return operators.count(Glb) > 0; |
| 55 | +} |
| 56 | + |
| 57 | +bool Lattice::hasLub() const { |
| 58 | + return operators.count(Lub) > 0; |
| 59 | +} |
| 60 | + |
| 61 | +bool Lattice::hasBottom() const { |
| 62 | + return operators.count(Bottom) > 0; |
| 63 | +} |
| 64 | + |
| 65 | +bool Lattice::hasTop() const { |
| 66 | + return operators.count(Top) > 0; |
| 67 | +} |
| 68 | + |
| 69 | +const ast::Argument* Lattice::getLub() const { |
| 70 | + return operators.at(Lub).get(); |
| 71 | +} |
| 72 | + |
| 73 | +const ast::Argument* Lattice::getGlb() const { |
| 74 | + return operators.at(Glb).get(); |
| 75 | +} |
| 76 | + |
| 77 | +const ast::Argument* Lattice::getBottom() const { |
| 78 | + return operators.at(Bottom).get(); |
| 79 | +} |
| 80 | + |
| 81 | +const ast::Argument* Lattice::getTop() const { |
| 82 | + return operators.at(Top).get(); |
| 83 | +} |
| 84 | + |
| 85 | +void Lattice::print(std::ostream& os) const { |
| 86 | + os << ".lattice " << getQualifiedName() << " {\n "; |
| 87 | + bool first = true; |
| 88 | + for (const auto& [op, arg] : operators) { |
| 89 | + if (!first) { |
| 90 | + os << ",\n "; |
| 91 | + } |
| 92 | + os << latticeOperatorToString(op) << " -> " << *arg; |
| 93 | + first = false; |
| 94 | + } |
| 95 | + os << "\n}"; |
| 96 | +} |
| 97 | + |
| 98 | +bool Lattice::equal(const Node& node) const { |
| 99 | + const auto& other = asAssert<Lattice>(node); |
| 100 | + return getQualifiedName() == other.getQualifiedName() && equal_targets(operators, other.operators); |
| 101 | +} |
| 102 | + |
| 103 | +Lattice* Lattice::cloning() const { |
| 104 | + return new Lattice(getQualifiedName(), clone(operators), getSrcLoc()); |
| 105 | +} |
| 106 | + |
| 107 | +} // namespace souffle::ast |
0 commit comments