/
Relation.h
176 lines (147 loc) · 4.79 KB
/
Relation.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
* Souffle - A Datalog Compiler
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved
* Licensed under the Universal Permissive License v 1.0 as shown at:
* - https://opensource.org/licenses/UPL
* - <souffle root>/licenses/SOUFFLE-UPL.txt
*/
/************************************************************************
*
* @file Relation.h
*
* Defines class Relation that represents relations in a Datalog program.
* A relation can either be an IDB or EDB relation.
*
***********************************************************************/
#pragma once
#include "RelationTag.h"
#include "SrcLocation.h"
#include "ast/Attribute.h"
#include "ast/Node.h"
#include "ast/QualifiedName.h"
#include "utility/ContainerUtil.h"
#include "utility/StreamUtil.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <memory>
#include <ostream>
#include <set>
#include <string>
#include <utility>
#include <vector>
namespace souffle {
/*!
* @class Relation
* @brief Intermediate representation of a datalog relation
*
* A relation has a name, types of its arguments, qualifier type,
* and dependencies to other relations.
*
*/
class AstRelation : public AstNode {
public:
AstRelation() = default;
AstRelation(AstQualifiedName name, SrcLocation loc = {}) : name(std::move(name)) {
setSrcLoc(std::move(loc));
}
/** get qualified relation name */
const AstQualifiedName& getQualifiedName() const {
return name;
}
/** Set name for this relation */
void setQualifiedName(AstQualifiedName n) {
name = std::move(n);
}
/** Add a new used type to this relation */
void addAttribute(Own<AstAttribute> attr) {
assert(attr && "Undefined attribute");
attributes.push_back(std::move(attr));
}
/** Return the arity of this relation */
size_t getArity() const {
return attributes.size();
}
/** Set relation attributes */
void setAttributes(VecOwn<AstAttribute> attrs) {
attributes = std::move(attrs);
}
/** Get relation attributes */
std::vector<AstAttribute*> getAttributes() const {
return toPtrVector(attributes);
}
/** Get relation qualifiers */
const std::set<RelationQualifier>& getQualifiers() const {
return qualifiers;
}
/** Add qualifier to this relation */
void addQualifier(RelationQualifier q) {
qualifiers.insert(q);
}
/** Remove qualifier from this relation */
void removeQualifier(RelationQualifier q) {
qualifiers.erase(q);
}
/** Get relation representation */
RelationRepresentation getRepresentation() const {
return representation;
}
/** Set relation representation */
void setRepresentation(RelationRepresentation representation) {
this->representation = representation;
}
/** check for a relation qualifier */
bool hasQualifier(RelationQualifier q) const {
return qualifiers.find(q) != qualifiers.end();
}
AstRelation* clone() const override {
auto res = new AstRelation(name, getSrcLoc());
res->attributes = souffle::clone(attributes);
res->qualifiers = qualifiers;
res->representation = representation;
return res;
}
void apply(const AstNodeMapper& map) override {
for (auto& cur : attributes) {
cur = map(std::move(cur));
}
}
std::vector<const AstNode*> getChildNodes() const override {
std::vector<const AstNode*> res;
for (const auto& cur : attributes) {
res.push_back(cur.get());
}
return res;
}
protected:
void print(std::ostream& os) const override {
os << ".decl " << getQualifiedName() << "(" << join(attributes, ", ") << ")" << join(qualifiers, " ")
<< " " << representation;
}
bool equal(const AstNode& node) const override {
const auto& other = static_cast<const AstRelation&>(node);
return name == other.name && equal_targets(attributes, other.attributes);
}
/** Name of relation */
AstQualifiedName name;
/** Attributes of the relation */
VecOwn<AstAttribute> attributes;
/** Qualifiers of relation */
std::set<RelationQualifier> qualifiers;
/** Datastructure to use for this relation */
RelationRepresentation representation{RelationRepresentation::DEFAULT};
};
/**
* Lexicographical order for AstRelation
* using the qualified name as an ordering criteria.
*/
struct AstNameComparison {
bool operator()(const AstRelation* x, const AstRelation* y) const {
if (x != nullptr && y != nullptr) {
return x->getQualifiedName() < y->getQualifiedName();
}
return y != nullptr;
}
};
using AstRelationSet = std::set<const AstRelation*, AstNameComparison>;
} // end of namespace souffle