souffle  2.0.2-371-g6315b36
Type.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2013, 2015, Oracle and/or its affiliates. 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 Type.cpp
12  *
13  * Implements a collection of type analyses operating on AST constructs.
14  *
15  ***********************************************************************/
16 
17 #include "ast/analysis/Type.h"
18 #include "AggregateOp.h"
19 #include "FunctorOps.h"
20 #include "Global.h"
21 #include "ast/Aggregator.h"
22 #include "ast/Atom.h"
23 #include "ast/BinaryConstraint.h"
24 #include "ast/BranchInit.h"
25 #include "ast/Clause.h"
26 #include "ast/IntrinsicFunctor.h"
27 #include "ast/Negation.h"
28 #include "ast/NumericConstant.h"
29 #include "ast/RecordInit.h"
30 #include "ast/Relation.h"
31 #include "ast/TranslationUnit.h"
32 #include "ast/TypeCast.h"
33 #include "ast/UserDefinedFunctor.h"
34 #include "ast/Variable.h"
41 #include "ast/utility/NodeMapper.h"
42 #include "ast/utility/Utils.h"
43 #include "souffle/TypeAttribute.h"
48 #include <algorithm>
49 #include <cassert>
50 #include <cstddef>
51 #include <functional>
52 #include <map>
53 #include <memory>
54 #include <optional>
55 #include <set>
56 #include <sstream>
57 #include <string>
58 #include <utility>
59 
60 namespace souffle::ast::analysis {
61 
63  const Clause* clause, const std::map<const Argument*, TypeSet> argumentTypes) {
64  // Annotates each variable with its type based on a given type analysis result
65  struct TypeAnnotator : public NodeMapper {
66  const std::map<const Argument*, TypeSet>& types;
67 
68  TypeAnnotator(const std::map<const Argument*, TypeSet>& types) : types(types) {}
69 
70  Own<Node> operator()(Own<Node> node) const override {
71  if (auto* var = dynamic_cast<ast::Variable*>(node.get())) {
72  std::stringstream newVarName;
73  newVarName << var->getName() << "&isin;" << types.find(var)->second;
74  return mk<ast::Variable>(newVarName.str());
75  } else if (auto* var = dynamic_cast<UnnamedVariable*>(node.get())) {
76  std::stringstream newVarName;
77  newVarName << "_"
78  << "&isin;" << types.find(var)->second;
79  return mk<ast::Variable>(newVarName.str());
80  }
81  node->apply(*this);
82  return node;
83  }
84  };
85 
86  /* Note:
87  * Because the type of each argument is stored in the form [address -> type-set],
88  * the type-analysis result does not immediately apply to the clone due to differing
89  * addresses.
90  * Two ways around this:
91  * (1) Perform the type-analysis again for the cloned clause
92  * (2) Keep track of the addresses of equivalent arguments in the cloned clause
93  * Method (2) was chosen to avoid having to recompute the analysis each time.
94  */
95  auto annotatedClause = souffle::clone(clause);
96 
97  // Maps x -> y, where x is the address of an argument in the original clause, and y
98  // is the address of the equivalent argument in the clone.
99  std::map<const Argument*, const Argument*> memoryMap;
100 
101  std::vector<const Argument*> originalAddresses;
102  visitDepthFirst(*clause, [&](const Argument& arg) { originalAddresses.push_back(&arg); });
103 
104  std::vector<const Argument*> cloneAddresses;
105  visitDepthFirst(*annotatedClause, [&](const Argument& arg) { cloneAddresses.push_back(&arg); });
106 
107  assert(cloneAddresses.size() == originalAddresses.size());
108 
109  for (size_t i = 0; i < originalAddresses.size(); i++) {
110  memoryMap[originalAddresses[i]] = cloneAddresses[i];
111  }
112 
113  // Map the types to the clause clone
114  std::map<const Argument*, TypeSet> cloneArgumentTypes;
115  for (auto& pair : argumentTypes) {
116  cloneArgumentTypes[memoryMap[pair.first]] = pair.second;
117  }
118 
119  // Create the type-annotated clause
120  TypeAnnotator annotator(cloneArgumentTypes);
121  annotatedClause->apply(annotator);
122  return annotatedClause;
123 }
124 
125 std::map<const Argument*, TypeSet> TypeAnalysis::analyseTypes(
126  const TranslationUnit& tu, const Clause& clause, std::ostream* logs) {
127  return TypeConstraintsAnalysis(tu).analyse(clause, logs);
128 }
129 
130 void TypeAnalysis::print(std::ostream& os) const {
131  os << "-- Analysis logs --" << std::endl;
132  os << analysisLogs.str() << std::endl;
133  os << "-- Result --" << std::endl;
134  for (auto& cur : annotatedClauses) {
135  os << *cur << std::endl;
136  }
137 }
138 
140  assert(hasValidTypeInfo(functor) && "type of functor not processed");
141  if (auto* intrinsic = as<IntrinsicFunctor>(functor)) {
142  return functorInfo.at(intrinsic)->result;
143  } else if (const auto* udf = as<UserDefinedFunctor>(functor)) {
144  return udfDeclaration.at(udf->getName())->getReturnType();
145  }
146  fatal("Missing functor type.");
147 }
148 
149 TypeAttribute TypeAnalysis::getFunctorArgType(const Functor* functor, const size_t idx) const {
150  assert(hasValidTypeInfo(functor) && "type of functor not processed");
151  if (auto* intrinsic = as<IntrinsicFunctor>(functor)) {
152  auto* info = functorInfo.at(intrinsic);
153  return info->params.at(info->variadic ? 0 : idx);
154  } else if (auto* udf = as<UserDefinedFunctor>(functor)) {
155  return udfDeclaration.at(udf->getName())->getArgsTypes().at(idx);
156  }
157  fatal("Missing functor type.");
158 }
159 
160 const std::vector<TypeAttribute>& TypeAnalysis::getFunctorArgTypes(const UserDefinedFunctor& udf) const {
161  return udfDeclaration.at(udf.getName())->getArgsTypes();
162 }
163 
164 bool TypeAnalysis::isStatefulFunctor(const UserDefinedFunctor* udf) const {
165  return udfDeclaration.at(udf->getName())->isStateful();
166 }
167 
168 const std::map<const NumericConstant*, NumericConstant::Type>& TypeAnalysis::getNumericConstantTypes() const {
169  return numericConstantType;
170 }
171 
172 bool TypeAnalysis::isMultiResultFunctor(const Functor& functor) {
173  if (isA<UserDefinedFunctor>(functor)) {
174  return false;
175  } else if (auto* intrinsic = as<IntrinsicFunctor>(functor)) {
176  auto candidates = functorBuiltIn(intrinsic->getBaseFunctionOp());
177  assert(!candidates.empty() && "at least one op should match");
178  return candidates[0].get().multipleResults;
179  }
180  fatal("Missing functor type.");
181 }
182 
183 std::set<TypeAttribute> TypeAnalysis::getTypeAttributes(const Argument* arg) const {
184  std::set<TypeAttribute> typeAttributes;
185 
186  if (const auto* inf = dynamic_cast<const IntrinsicFunctor*>(arg)) {
187  // intrinsic functor type is its return type if its set
188  if (hasValidTypeInfo(inf)) {
189  typeAttributes.insert(getFunctorReturnType(inf));
190  return typeAttributes;
191  }
192  } else if (const auto* udf = dynamic_cast<const UserDefinedFunctor*>(arg)) {
193  if (hasValidTypeInfo(udf)) {
194  typeAttributes.insert(getFunctorReturnType(udf));
195  return typeAttributes;
196  }
197  }
198 
199  const auto& types = getTypes(arg);
200  if (types.isAll()) {
203  }
204  for (const auto& type : types) {
205  typeAttributes.insert(getTypeAttribute(type));
206  }
207  return typeAttributes;
208 }
209 
210 IntrinsicFunctors TypeAnalysis::getValidIntrinsicFunctorOverloads(const IntrinsicFunctor& inf) const {
211  // Get the info of all possible functors which can be used here
212  IntrinsicFunctors functorInfos = contains(functorInfo, &inf) ? functorBuiltIn(functorInfo.at(&inf)->op)
213  : functorBuiltIn(inf.getBaseFunctionOp());
214 
215  // Filter out the ones which don't fit in with the current knowledge
216  auto returnTypes = getTypeAttributes(&inf);
217  auto argTypes = map(inf.getArguments(), [&](const Argument* arg) { return getTypeAttributes(arg); });
218  auto isValidOverload = [&](const IntrinsicFunctorInfo& candidate) {
219  // Check for arity mismatch
220  if (!candidate.variadic && argTypes.size() != candidate.params.size()) {
221  return false;
222  }
223 
224  // Check that argument types match
225  for (size_t i = 0; i < argTypes.size(); ++i) {
226  const auto& expectedType = candidate.params[candidate.variadic ? 0 : i];
227  if (!contains(argTypes[i], expectedType)) {
228  return false;
229  }
230  }
231 
232  // Check that the return type matches
233  return contains(returnTypes, candidate.result);
234  };
235  auto candidates = filter(functorInfos, isValidOverload);
236 
237  // Sort them in a standardised way (so order is deterministic)
238  auto comparator = [&](const IntrinsicFunctorInfo& a, const IntrinsicFunctorInfo& b) {
239  if (a.result != b.result) return a.result < b.result;
240  if (a.variadic != b.variadic) return a.variadic < b.variadic;
241  return std::lexicographical_compare(
242  a.params.begin(), a.params.end(), b.params.begin(), b.params.end());
243  };
244  std::sort(candidates.begin(), candidates.end(), comparator);
245 
246  return candidates;
247 }
248 
249 bool TypeAnalysis::hasValidTypeInfo(const Argument* argument) const {
250  if (auto* inf = as<IntrinsicFunctor>(argument)) {
251  return contains(functorInfo, inf);
252  } else if (auto* udf = as<UserDefinedFunctor>(argument)) {
253  return contains(udfDeclaration, udf->getName());
254  } else if (auto* nc = as<NumericConstant>(argument)) {
256  } else if (auto* agg = as<Aggregator>(argument)) {
257  return contains(aggregatorType, agg);
258  }
259  return true;
260 }
261 
263  assert(hasValidTypeInfo(nc) && "numeric constant type not set");
264  return numericConstantType.at(nc);
265 }
266 
267 BinaryConstraintOp TypeAnalysis::getPolymorphicOperator(const BinaryConstraint* bc) const {
268  assert(contains(constraintType, bc) && "binary constraint operator not set");
269  return constraintType.at(bc);
270 }
271 
273  assert(hasValidTypeInfo(agg) && "aggregator operator not set");
274  return aggregatorType.at(agg);
275 }
276 
278  assert(hasValidTypeInfo(inf) && "functor type not set");
279  return functorInfo.at(inf)->op;
280 }
281 
282 bool TypeAnalysis::analyseIntrinsicFunctors(const TranslationUnit& translationUnit) {
283  bool changed = false;
284  const auto& program = translationUnit.getProgram();
285  visitDepthFirst(program, [&](const IntrinsicFunctor& functor) {
286  auto candidates = getValidIntrinsicFunctorOverloads(functor);
287  if (candidates.empty()) {
288  // No valid overloads - mark it as an invalid functor
289  if (contains(functorInfo, &functor)) {
290  functorInfo.erase(&functor);
291  changed = true;
292  }
293  return;
294  }
295 
296  // Update to the canonic representation if different
297  const auto* curInfo = &candidates.front().get();
298  if (contains(functorInfo, &functor) && functorInfo.at(&functor) == curInfo) {
299  return;
300  }
301  functorInfo[&functor] = curInfo;
302  changed = true;
303  });
304  return changed;
305 }
306 
307 bool TypeAnalysis::analyseNumericConstants(const TranslationUnit& translationUnit) {
308  bool changed = false;
309  const auto& program = translationUnit.getProgram();
310 
311  auto setNumericConstantType = [&](const NumericConstant& nc, NumericConstant::Type ncType) {
312  if (contains(numericConstantType, &nc) && numericConstantType.at(&nc) == ncType) {
313  return;
314  }
315  changed = true;
316  numericConstantType[&nc] = ncType;
317  };
318 
319  visitDepthFirst(program, [&](const NumericConstant& numericConstant) {
320  // Constant has a fixed type
321  if (numericConstant.getFixedType().has_value()) {
322  setNumericConstantType(numericConstant, numericConstant.getFixedType().value());
323  return;
324  }
325 
326  // Otherwise, type should be inferred
327  TypeSet types = getTypes(&numericConstant);
328  auto hasOfKind = [&](TypeAttribute kind) -> bool {
329  return any_of(types, [&](const analysis::Type& type) { return isOfKind(type, kind); });
330  };
331  if (hasOfKind(TypeAttribute::Signed)) {
332  setNumericConstantType(numericConstant, NumericConstant::Type::Int);
333  } else if (hasOfKind(TypeAttribute::Unsigned)) {
334  setNumericConstantType(numericConstant, NumericConstant::Type::Uint);
335  } else if (hasOfKind(TypeAttribute::Float)) {
336  setNumericConstantType(numericConstant, NumericConstant::Type::Float);
337  } else {
338  // Type information no longer valid
339  if (contains(numericConstantType, &numericConstant)) {
340  numericConstantType.erase(&numericConstant);
341  changed = true;
342  }
343  }
344  });
345 
346  return changed;
347 }
348 
349 bool TypeAnalysis::analyseAggregators(const TranslationUnit& translationUnit) {
350  bool changed = false;
351  const auto& program = translationUnit.getProgram();
352 
353  auto setAggregatorType = [&](const Aggregator& agg, TypeAttribute attr) {
354  auto overloadedType = convertOverloadedAggregator(agg.getBaseOperator(), attr);
355  if (contains(aggregatorType, &agg) && aggregatorType.at(&agg) == overloadedType) {
356  return;
357  }
358  changed = true;
359  aggregatorType[&agg] = overloadedType;
360  };
361 
362  visitDepthFirst(program, [&](const Aggregator& agg) {
364  auto* targetExpression = agg.getTargetExpression();
365  if (isFloat(targetExpression)) {
366  setAggregatorType(agg, TypeAttribute::Float);
367  } else if (isUnsigned(targetExpression)) {
368  setAggregatorType(agg, TypeAttribute::Unsigned);
369  } else {
370  setAggregatorType(agg, TypeAttribute::Signed);
371  }
372  } else {
373  if (contains(aggregatorType, &agg)) {
374  assert(aggregatorType.at(&agg) == agg.getBaseOperator() &&
375  "non-overloaded aggr types should always be the base operator");
376  return;
377  }
378  changed = true;
379  aggregatorType[&agg] = agg.getBaseOperator();
380  }
381  });
382 
383  return changed;
384 }
385 
386 bool TypeAnalysis::analyseBinaryConstraints(const TranslationUnit& translationUnit) {
387  bool changed = false;
388  const auto& program = translationUnit.getProgram();
389 
390  auto setConstraintType = [&](const BinaryConstraint& bc, TypeAttribute attr) {
391  auto overloadedType = convertOverloadedConstraint(bc.getBaseOperator(), attr);
392  if (contains(constraintType, &bc) && constraintType.at(&bc) == overloadedType) {
393  return;
394  }
395  changed = true;
396  constraintType[&bc] = overloadedType;
397  };
398 
399  visitDepthFirst(program, [&](const BinaryConstraint& binaryConstraint) {
400  if (isOverloaded(binaryConstraint.getBaseOperator())) {
401  // Get arguments
402  auto* leftArg = binaryConstraint.getLHS();
403  auto* rightArg = binaryConstraint.getRHS();
404 
405  // Both args must be of the same type
406  if (isFloat(leftArg) && isFloat(rightArg)) {
407  setConstraintType(binaryConstraint, TypeAttribute::Float);
408  } else if (isUnsigned(leftArg) && isUnsigned(rightArg)) {
409  setConstraintType(binaryConstraint, TypeAttribute::Unsigned);
410  } else if (isSymbol(leftArg) && isSymbol(rightArg)) {
411  setConstraintType(binaryConstraint, TypeAttribute::Symbol);
412  } else {
413  setConstraintType(binaryConstraint, TypeAttribute::Signed);
414  }
415  } else {
416  if (contains(constraintType, &binaryConstraint)) {
417  assert(constraintType.at(&binaryConstraint) == binaryConstraint.getBaseOperator() &&
418  "unexpected constraint type");
419  return;
420  }
421  changed = true;
422  constraintType[&binaryConstraint] = binaryConstraint.getBaseOperator();
423  }
424  });
425 
426  return changed;
427 }
428 
429 bool TypeAnalysis::isFloat(const Argument* argument) const {
430  return isOfKind(getTypes(argument), TypeAttribute::Float);
431 }
432 
433 bool TypeAnalysis::isUnsigned(const Argument* argument) const {
434  return isOfKind(getTypes(argument), TypeAttribute::Unsigned);
435 }
436 
437 bool TypeAnalysis::isSymbol(const Argument* argument) const {
438  return isOfKind(getTypes(argument), TypeAttribute::Symbol);
439 }
440 
441 void TypeAnalysis::run(const TranslationUnit& translationUnit) {
442  // Check if debugging information is being generated
443  std::ostream* debugStream = nullptr;
444  if (Global::config().has("debug-report") || Global::config().has("show", "type-analysis")) {
445  debugStream = &analysisLogs;
446  }
447 
448  // Analyse user-defined functor types
449  const Program& program = translationUnit.getProgram();
451  program, [&](const FunctorDeclaration& fdecl) { udfDeclaration[fdecl.getName()] = &fdecl; });
452 
453  // Rest of the analysis done until fixpoint reached
454  bool changed = true;
455  while (changed) {
456  changed = false;
457  argumentTypes.clear();
458 
459  // Analyse general argument types, clause by clause.
460  for (const Clause* clause : program.getClauses()) {
461  auto clauseArgumentTypes = analyseTypes(translationUnit, *clause, debugStream);
462  argumentTypes.insert(clauseArgumentTypes.begin(), clauseArgumentTypes.end());
463 
464  if (debugStream != nullptr) {
465  // Store an annotated clause for printing purposes
466  annotatedClauses.emplace_back(createAnnotatedClause(clause, clauseArgumentTypes));
467  }
468  }
469 
470  // Analyse intrinsic-functor types
471  changed |= analyseIntrinsicFunctors(translationUnit);
472 
473  // Deduce numeric-constant polymorphism
474  changed |= analyseNumericConstants(translationUnit);
475 
476  // Deduce aggregator polymorphism
477  changed |= analyseAggregators(translationUnit);
478 
479  // Deduce binary-constraint polymorphism
480  changed |= analyseBinaryConstraints(translationUnit);
481  }
482 }
483 
484 } // namespace souffle::ast::analysis
souffle::ast::analysis::isOfKind
bool isOfKind(const Type &type, TypeAttribute kind)
Check if the type is of a kind corresponding to the TypeAttribute.
Definition: TypeSystem.cpp:189
souffle::ast::UserDefinedFunctor::getName
const std::string & getName() const
return the name
Definition: UserDefinedFunctor.h:54
souffle::interpreter::comparator
typename index_utils::get_full_index< Arity >::type::comparator comparator
Definition: Util.h:216
souffle::ast::analysis::TypeAnalysis::analyseBinaryConstraints
bool analyseBinaryConstraints(const TranslationUnit &translationUnit)
Definition: Type.cpp:392
souffle::ast::analysis::TypeAnalysis::analyseIntrinsicFunctors
bool analyseIntrinsicFunctors(const TranslationUnit &translationUnit)
Definition: Type.cpp:288
souffle::TypeAttribute::Record
@ Record
souffle::ast::analysis::TypeAnalysis::analysisLogs
std::stringstream analysisLogs
Definition: Type.h:95
TranslationUnit.h
TypeAttribute
Type attribute class.
souffle::ast::FunctorDeclaration
User-defined functor declaration.
Definition: FunctorDeclaration.h:49
AggregateOp.h
souffle::ast::analysis::TypeAnalysis::getPolymorphicOperator
AggregateOp getPolymorphicOperator(const Aggregator *agg) const
Definition: Type.cpp:278
souffle::ast::NumericConstant::getFixedType
const std::optional< Type > & getFixedType() const
Definition: NumericConstant.h:73
souffle::ast::analysis::TypeAnalysis::getPolymorphicNumericConstantType
NumericConstant::Type getPolymorphicNumericConstantType(const NumericConstant *nc) const
– Polymorphism-related methods –
Definition: Type.cpp:268
souffle::convertOverloadedAggregator
AggregateOp convertOverloadedAggregator(const AggregateOp op, const TypeAttribute type)
Convert aggregator to a give type.
Definition: AggregateOp.h:133
souffle::ast::analysis::TypeAnalysis::analyseTypes
static std::map< const Argument *, TypeSet > analyseTypes(const TranslationUnit &tu, const Clause &clause, std::ostream *logs=nullptr)
Analyse the given clause and computes for each contained argument a set of potential types.
Definition: Type.cpp:131
souffle::AggregateOp
AggregateOp
Types of aggregation functions.
Definition: AggregateOp.h:34
souffle::ast::analysis::TypeAnalysis::functorInfo
std::map< const IntrinsicFunctor *, const IntrinsicFunctorInfo * > functorInfo
Definition: Type.h:102
souffle::contains
bool contains(const C &container, const typename C::value_type &element)
A utility to check generically whether a given element is contained in a given container.
Definition: ContainerUtil.h:75
souffle::TypeAttribute::Symbol
@ Symbol
souffle::ast::FunctorDeclaration::getName
const std::string & getName() const
Return name.
Definition: FunctorDeclaration.h:59
souffle::Own
std::unique_ptr< A > Own
Definition: ContainerUtil.h:42
types
std::vector< Own< ast::Type > > types
Definition: ComponentInstantiation.cpp:64
souffle::ast::analysis::TypeAnalysis::getTypes
TypeSet const & getTypes(const Argument *argument) const
Get the computed types for the given argument.
Definition: Type.h:56
souffle::map
auto map(const std::vector< A > &xs, F &&f)
Applies a function to each element of a vector and returns the results.
Definition: ContainerUtil.h:158
MiscUtil.h
souffle::ast::analysis::TypeAnalysis::run
void run(const TranslationUnit &translationUnit) override
run analysis for a Ast translation unit
Definition: Type.cpp:447
souffle::ast::analysis::TypeAnalysis::getValidIntrinsicFunctorOverloads
IntrinsicFunctors getValidIntrinsicFunctorOverloads(const IntrinsicFunctor &inf) const
– Functor-related methods –
Definition: Type.cpp:216
Constraint.h
souffle::ast::Clause
Intermediate representation of a horn clause.
Definition: Clause.h:51
souffle::ast::Program::getClauses
std::vector< Clause * > getClauses() const
Return clauses.
Definition: Program.h:65
souffle::ast::analysis::Type
An abstract base class for types to be covered within a type environment.
Definition: TypeSystem.h:51
souffle::ast::UserDefinedFunctor
User-Defined functor class.
Definition: UserDefinedFunctor.h:46
souffle::isOverloaded
bool isOverloaded(const BinaryConstraintOp constraintOp)
Utility function, informing whether constraint is overloaded.
Definition: BinaryConstraintOps.h:231
souffle::ast::analysis::Variable
A variable to be utilized within constraints to be handled by the constraint solver.
Definition: ConstraintSystem.h:41
Relation.h
IntrinsicFunctor.h
souffle::ast::analysis::TypeAnalysis::argumentTypes
std::map< const Argument *, TypeSet > argumentTypes
Definition: Type.h:93
souffle::ast::analysis::TypeAnalysis::hasValidTypeInfo
bool hasValidTypeInfo(const Argument *argument) const
Definition: Type.cpp:255
souffle::ast::analysis::TypeSet
A collection to represent sets of types.
Definition: TypeSystem.h:249
Utils.h
NodeMapper.h
souffle::IntrinsicFunctorInfo
Definition: FunctorOps.h:120
souffle::ast::analysis::TypeAnalysis::numericConstantType
std::map< const NumericConstant *, NumericConstant::Type > numericConstantType
Definition: Type.h:104
souffle::TypeAttribute::Signed
@ Signed
souffle::ast::NumericConstant::Type::Int
@ Int
souffle::IntrinsicFunctors
std::vector< std::reference_wrapper< const IntrinsicFunctorInfo > > IntrinsicFunctors
Definition: FunctorOps.h:129
souffle::ast::Argument
An abstract class for arguments.
Definition: Argument.h:33
souffle::ast::analysis::TypeAnalysis::getFunctorReturnType
TypeAttribute getFunctorReturnType(const Functor *functor) const
Definition: Type.cpp:145
ConstraintSystem.h
Global.h
UserDefinedFunctor.h
souffle::ast::Program
The program class consists of relations, clauses and types.
Definition: Program.h:52
TypeCast.h
souffle::ast::analysis::TypeAnalysis::print
void print(std::ostream &os) const override
print the analysis result in HTML format
Definition: Type.cpp:136
souffle::ast::analysis::TypeAnalysis::analyseAggregators
bool analyseAggregators(const TranslationUnit &translationUnit)
Definition: Type.cpp:355
souffle::clone
auto clone(const std::vector< A * > &xs)
Definition: ContainerUtil.h:172
souffle::TypeAttribute::Unsigned
@ Unsigned
souffle::ast::analysis::TypeAnalysis::isFloat
bool isFloat(const Argument *argument) const
Definition: Type.cpp:435
i
size_t i
Definition: json11.h:663
souffle::filter
std::vector< A > filter(std::vector< A > xs, F &&f)
Filter a vector to include certain elements.
Definition: FunctionalUtil.h:155
ContainerUtil.h
souffle::ast::analysis::getTypeAttribute
TypeAttribute getTypeAttribute(const Type &type)
Definition: TypeSystem.cpp:353
StringUtil.h
souffle::ast::IntrinsicFunctor
Intrinsic Functor class for functors are in-built.
Definition: IntrinsicFunctor.h:47
Atom.h
souffle::any_of
bool any_of(const Container &c, UnaryPredicate p)
A generic test checking whether any elements within a container satisfy a certain predicate.
Definition: FunctionalUtil.h:124
TypeConstraints.h
souffle::ast::TranslationUnit
Translation unit class for the translation pipeline.
Definition: TranslationUnit.h:51
souffle::ast::BinaryConstraint::getBaseOperator
BinaryConstraintOp getBaseOperator() const
Return binary operator.
Definition: BinaryConstraint.h:69
souffle::convertOverloadedConstraint
BinaryConstraintOp convertOverloadedConstraint(const BinaryConstraintOp constraintOp, const TypeAttribute toType)
Convert Constraint to work with requested type.
Definition: BinaryConstraintOps.h:248
souffle::ast::analysis::TypeAnalysis::createAnnotatedClause
static Own< Clause > createAnnotatedClause(const Clause *clause, const std::map< const Argument *, TypeSet > argumentTypes)
Definition: Type.cpp:68
souffle::ast::analysis::TypeAnalysis::analyseNumericConstants
bool analyseNumericConstants(const TranslationUnit &translationUnit)
Definition: Type.cpp:313
Negation.h
BranchInit.h
souffle::BinaryConstraintOp
BinaryConstraintOp
Binary Constraint Operators.
Definition: BinaryConstraintOps.h:41
souffle::ast::Functor
Abstract functor class.
Definition: Functor.h:36
souffle::ast::analysis::TypeAnalysis::getFunctorArgType
TypeAttribute getFunctorArgType(const Functor *functor, const size_t idx) const
Definition: Type.cpp:155
souffle::FunctorOp
FunctorOp
Definition: FunctorOps.h:35
souffle::ast::analysis::TypeAnalysis::annotatedClauses
VecOwn< Clause > annotatedClauses
Definition: Type.h:94
souffle::ast::analysis::TypeAnalysis::getTypeAttributes
std::set< TypeAttribute > getTypeAttributes(const Argument *arg) const
Definition: Type.cpp:189
souffle::ast::BinaryConstraint
Binary constraint class.
Definition: BinaryConstraint.h:53
souffle::ast::analysis::TypeAnalysis::aggregatorType
std::map< const Aggregator *, AggregateOp > aggregatorType
Definition: Type.h:105
Aggregator.h
souffle::Global::config
static MainConfig & config()
Definition: Global.h:141
souffle::functorBuiltIn
IntrinsicFunctors functorBuiltIn(FunctorOp op)
Definition: FunctorOps.cpp:224
souffle::ast::Aggregator
Defines the aggregator class.
Definition: Aggregator.h:53
souffle::ast::analysis::TypeAnalysis::constraintType
std::map< const BinaryConstraint *, BinaryConstraintOp > constraintType
Definition: Type.h:106
b
l j a showGridBackground &&c b raw series this eventEmitter b
Definition: htmlJsChartistMin.h:15
souffle::ast::Aggregator::getBaseOperator
AggregateOp getBaseOperator() const
Return the (base type) operator of the aggregator.
Definition: Aggregator.h:61
souffle::ast::analysis::TypeAnalysis::isUnsigned
bool isUnsigned(const Argument *argument) const
Definition: Type.cpp:439
SumTypeBranches.h
souffle::ast::NumericConstant::Type::Uint
@ Uint
souffle::ast::analysis::TypeAnalysis::getNumericConstantTypes
const std::map< const NumericConstant *, NumericConstant::Type > & getNumericConstantTypes() const
Definition: Type.cpp:174
souffle::fatal
void fatal(const char *format, const Args &... args)
Definition: MiscUtil.h:198
souffle::ast::analysis::TypeAnalysis::isMultiResultFunctor
static bool isMultiResultFunctor(const Functor &functor)
Definition: Type.cpp:178
Clause.h
Type.h
souffle::ast::analysis
Definition: Aggregate.cpp:39
souffle::ast::analysis::TypeAnalysis::getFunctorArgTypes
const std::vector< TypeAttribute > & getFunctorArgTypes(const UserDefinedFunctor &udf) const
Definition: Type.cpp:166
souffle::ast::UnnamedVariable
Unnamed variable class.
Definition: UnnamedVariable.h:34
souffle::ast::analysis::TypeAnalysis::isSymbol
bool isSymbol(const Argument *argument) const
Definition: Type.cpp:443
souffle::ast::analysis::TypeAnalysis::udfDeclaration
std::map< std::string, const FunctorDeclaration * > udfDeclaration
Definition: Type.h:103
BinaryConstraint.h
souffle::ast::visitDepthFirst
void visitDepthFirst(const Node &root, Visitor< R, Ps... > &visitor, Args &... args)
A utility function visiting all nodes within the ast rooted by the given node recursively in a depth-...
Definition: Visitor.h:273
FunctorOps.h
souffle::ast::analysis::TypeAnalysis::isStatefulFunctor
bool isStatefulFunctor(const UserDefinedFunctor *udf) const
Definition: Type.cpp:170
souffle::ast::NumericConstant::Type
Type
Definition: NumericConstant.h:51
FunctionalUtil.h
souffle::ast::NumericConstant::Type::Float
@ Float
souffle::ast::NumericConstant
Numeric Constant.
Definition: NumericConstant.h:43
souffle::TypeAttribute::Float
@ Float
TypeEnvironment.h
souffle::ast::TranslationUnit::getProgram
Program & getProgram() const
Return the program.
Definition: TranslationUnit.h:84
RecordInit.h
NumericConstant.h
std::type
ElementType type
Definition: span.h:640
TypeAttribute.h
Variable.h
TypeSystem.h
souffle::isOverloadedAggregator
bool isOverloadedAggregator(const AggregateOp op)
Definition: AggregateOp.h:116