Skip to content

Commit c17bbab

Browse files
authored
Lattice support (#2438)
introduce support of lattice types
1 parent 01f1177 commit c17bbab

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+2171
-399
lines changed

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ set(SOUFFLE_SOURCES
3434
ast/FunctionalConstraint.cpp
3535
ast/IntrinsicFunctor.cpp
3636
ast/IterationCounter.cpp
37+
ast/Lattice.cpp
3738
ast/Negation.cpp
3839
ast/NilConstant.cpp
3940
ast/Node.cpp
@@ -87,6 +88,7 @@ set(SOUFFLE_SOURCES
8788
ast/transform/GroundedTermsChecker.cpp
8889
ast/transform/GroundWitnesses.cpp
8990
ast/transform/InlineRelations.cpp
91+
ast/transform/InsertLatticeOperations.cpp
9092
ast/transform/MagicSet.cpp
9193
ast/transform/MaterializeAggregationQueries.cpp
9294
ast/transform/MaterializeSingletonAggregation.cpp

src/MainDriver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "ast/transform/IOAttributes.h"
3838
#include "ast/transform/IODefaults.h"
3939
#include "ast/transform/InlineRelations.h"
40+
#include "ast/transform/InsertLatticeOperations.h"
4041
#include "ast/transform/MagicSet.h"
4142
#include "ast/transform/MaterializeAggregationQueries.h"
4243
#include "ast/transform/MaterializeSingletonAggregation.h"
@@ -479,6 +480,7 @@ Own<ast::transform::PipelineTransformer> astTransformationPipeline(Global& glb)
479480
// Main pipeline
480481
auto pipeline = mk<ast::transform::PipelineTransformer>(mk<ast::transform::ComponentChecker>(),
481482
mk<ast::transform::ComponentInstantiationTransformer>(),
483+
mk<ast::transform::LatticeTransformer>(),
482484
mk<ast::transform::DebugDeltaRelationTransformer>(),
483485
mk<ast::transform::IODefaultsTransformer>(),
484486
mk<ast::transform::SimplifyAggregateTargetExpressionTransformer>(),

src/RelationTag.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ enum class RelationRepresentation {
5858
BTREE, // use btree data-structure
5959
BTREE_DELETE, // use btree_delete data-structure
6060
EQREL, // use union data-structure
61-
PROVENANCE, // use custom btree data-structure with provenance extras
6261
INFO, // info relation for provenance
6362
};
6463

@@ -168,7 +167,6 @@ inline std::ostream& operator<<(std::ostream& os, RelationRepresentation represe
168167
case RelationRepresentation::BTREE_DELETE: return os << "btree_delete";
169168
case RelationRepresentation::BRIE: return os << "brie";
170169
case RelationRepresentation::EQREL: return os << "eqrel";
171-
case RelationRepresentation::PROVENANCE: return os << "provenance";
172170
case RelationRepresentation::INFO: return os << "info";
173171
case RelationRepresentation::DEFAULT: return os;
174172
}

src/ast/Attribute.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,29 @@
1414
namespace souffle::ast {
1515

1616
Attribute::Attribute(std::string n, QualifiedName t, SrcLocation loc)
17-
: Node(std::move(loc)), name(std::move(n)), typeName(std::move(t)) {}
17+
: Node(std::move(loc)), name(std::move(n)), typeName(std::move(t)), isLattice(false) {}
18+
19+
Attribute::Attribute(std::string n, QualifiedName t, bool isLattice, SrcLocation loc)
20+
: Node(std::move(loc)), name(std::move(n)), typeName(std::move(t)), isLattice(isLattice) {}
1821

1922
void Attribute::setTypeName(QualifiedName name) {
2023
typeName = std::move(name);
2124
}
2225

2326
void Attribute::print(std::ostream& os) const {
2427
os << name << ":" << typeName;
28+
if (isLattice) {
29+
os << "<>";
30+
}
2531
}
2632

2733
bool Attribute::equal(const Node& node) const {
2834
const auto& other = asAssert<Attribute>(node);
29-
return name == other.name && typeName == other.typeName;
35+
return name == other.name && typeName == other.typeName && isLattice == other.isLattice;
3036
}
3137

3238
Attribute* Attribute::cloning() const {
33-
return new Attribute(name, typeName, getSrcLoc());
39+
return new Attribute(name, typeName, isLattice, getSrcLoc());
3440
}
3541

3642
} // namespace souffle::ast

src/ast/Attribute.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ namespace souffle::ast {
3535
class Attribute : public Node {
3636
public:
3737
Attribute(std::string n, QualifiedName t, SrcLocation loc = {});
38+
Attribute(std::string n, QualifiedName t, bool isLattice, SrcLocation loc = {});
3839

3940
/** Return attribute name */
4041
const std::string& getName() const {
@@ -49,6 +50,10 @@ class Attribute : public Node {
4950
/** Set type name */
5051
void setTypeName(QualifiedName name);
5152

53+
bool getIsLattice() const {
54+
return isLattice;
55+
}
56+
5257
protected:
5358
void print(std::ostream& os) const override;
5459

@@ -63,6 +68,9 @@ class Attribute : public Node {
6368

6469
/** Type name */
6570
QualifiedName typeName;
71+
72+
/** Is lattice element */
73+
bool isLattice;
6674
};
6775

6876
} // namespace souffle::ast

src/ast/Component.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ std::vector<Type*> Component::getTypes() const {
3939
return toPtrVector(types);
4040
}
4141

42+
void Component::addLattice(Own<Lattice> t) {
43+
assert(t != nullptr);
44+
lattices.push_back(std::move(t));
45+
}
46+
47+
std::vector<Lattice*> Component::getLattices() const {
48+
return toPtrVector(lattices);
49+
}
50+
4251
void Component::copyBaseComponents(const Component& other) {
4352
baseComponents = clone(other.baseComponents);
4453
}

src/ast/Component.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "ast/ComponentInit.h"
2121
#include "ast/ComponentType.h"
2222
#include "ast/Directive.h"
23+
#include "ast/Lattice.h"
2324
#include "ast/Node.h"
2425
#include "ast/Relation.h"
2526
#include "ast/Type.h"
@@ -64,6 +65,11 @@ class Component : public Node {
6465
/** Get types */
6566
std::vector<Type*> getTypes() const;
6667

68+
/** Add lattice */
69+
void addLattice(Own<Lattice> lat);
70+
71+
std::vector<Lattice*> getLattices() const;
72+
6773
/** Copy base components */
6874
void copyBaseComponents(const Component& other);
6975

@@ -129,6 +135,9 @@ class Component : public Node {
129135
/** Types declarations */
130136
VecOwn<Type> types;
131137

138+
/** Types declarations */
139+
VecOwn<Lattice> lattices;
140+
132141
/** Relations */
133142
VecOwn<Relation> relations;
134143

src/ast/Lattice.cpp

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
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

src/ast/Lattice.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
/************************************************************************
10+
*
11+
* @file Lattice.h
12+
*
13+
* Defines the Lattice class
14+
*
15+
***********************************************************************/
16+
17+
#pragma once
18+
19+
#include "ast/Argument.h"
20+
#include "ast/Node.h"
21+
#include "ast/QualifiedName.h"
22+
#include "parser/SrcLocation.h"
23+
24+
#include <map>
25+
#include <optional>
26+
27+
namespace souffle::ast {
28+
29+
enum LatticeOperator { Bottom = 0, Top, Lub, Glb, Leq };
30+
31+
std::optional<LatticeOperator> latticeOperatorFromString(const std::string& str);
32+
33+
/**
34+
* @class Lattice
35+
* @brief An class to define Lattice attributes for a type
36+
*/
37+
class Lattice : public Node {
38+
public:
39+
Lattice(QualifiedName name, std::map<LatticeOperator, Own<ast::Argument>> operators,
40+
SrcLocation loc = {});
41+
42+
/** Return type name */
43+
const QualifiedName& getQualifiedName() const {
44+
return name;
45+
}
46+
47+
/** Set type name */
48+
void setQualifiedName(QualifiedName name);
49+
50+
const std::map<LatticeOperator, const ast::Argument*> getOperators() const;
51+
52+
bool hasGlb() const;
53+
bool hasLub() const;
54+
bool hasBottom() const;
55+
bool hasTop() const;
56+
57+
const ast::Argument* getLub() const;
58+
const ast::Argument* getGlb() const;
59+
const ast::Argument* getBottom() const;
60+
const ast::Argument* getTop() const;
61+
62+
protected:
63+
void print(std::ostream& os) const override;
64+
65+
private:
66+
bool equal(const Node& node) const override;
67+
68+
Lattice* cloning() const override;
69+
70+
private:
71+
/** type name */
72+
QualifiedName name;
73+
74+
const std::map<LatticeOperator, Own<ast::Argument>> operators;
75+
};
76+
77+
} // namespace souffle::ast

0 commit comments

Comments
 (0)