mirror of
https://github.com/apple/swift.git
synced 2026-02-27 18:26:24 +01:00
161 lines
3.8 KiB
C++
161 lines
3.8 KiB
C++
//===--- Relation.h - Relations and boolean matrices ------------*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2026 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// The code here is meant for debugging relations implemented as boolean
|
|
// predicates. You can construct a Boolean matrix by evaluating the predicate
|
|
// against all possible pairs of values from some range, and then check that
|
|
// this matrix satisfies various conditions.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_SEMA_RELATION_H
|
|
#define SWIFT_SEMA_RELATION_H
|
|
|
|
#include "swift/Basic/Assertions.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include <vector>
|
|
|
|
namespace swift {
|
|
|
|
namespace constraints {
|
|
|
|
struct BooleanMatrix {
|
|
std::vector<std::vector<bool>> elements;
|
|
|
|
size_t rows() const {
|
|
return elements.size();
|
|
}
|
|
|
|
size_t columns() const {
|
|
return elements[0].size();
|
|
}
|
|
|
|
explicit BooleanMatrix(std::vector<std::vector<bool>> elements)
|
|
: elements(elements) {
|
|
ASSERT(elements.size() > 0);
|
|
size_t columns = elements[0].size();
|
|
for (const auto &row : elements) {
|
|
ASSERT(columns == row.size());
|
|
}
|
|
}
|
|
|
|
void dump(llvm::raw_ostream &out) {
|
|
for (auto &row : elements) {
|
|
llvm::interleave(
|
|
row,
|
|
[&](bool elt) { out << (elt ? "1" : "0"); },
|
|
[&]() { out << " "; });
|
|
out << "\n";
|
|
}
|
|
}
|
|
|
|
BooleanMatrix multiply(const BooleanMatrix &other) const {
|
|
std::vector<std::vector<bool>> result;
|
|
|
|
ASSERT(columns() == other.rows());
|
|
|
|
for (unsigned i = 0; i < rows(); ++i) {
|
|
result.emplace_back();
|
|
for (unsigned j = 0; j < other.columns(); ++j) {
|
|
bool entry = false;
|
|
for (unsigned k = 0; k < columns(); ++k) {
|
|
entry |= elements[i][k] && other.elements[k][j];
|
|
}
|
|
result.back().push_back(entry);
|
|
}
|
|
}
|
|
|
|
return BooleanMatrix(result);
|
|
}
|
|
|
|
bool isReflexive() const {
|
|
ASSERT(rows() == columns());
|
|
|
|
for (unsigned i = 0; i < rows(); ++i) {
|
|
if (!elements[i][i])
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool isAntiReflexive() const {
|
|
ASSERT(rows() == columns());
|
|
|
|
for (unsigned i = 0; i < rows(); ++i) {
|
|
if (elements[i][i])
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool isSymmetric() const {
|
|
ASSERT(rows() == columns());
|
|
|
|
for (unsigned i = 0; i < rows(); ++i) {
|
|
for (unsigned j = 0; j < i; ++j) {
|
|
if (elements[i][j] != elements[j][i])
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool isAntiSymmetric() const {
|
|
ASSERT(rows() == columns());
|
|
|
|
for (unsigned i = 0; i < rows(); ++i) {
|
|
for (unsigned j = 0; j < i; ++j) {
|
|
if (elements[i][j] && elements[j][i])
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool isTransitive() const {
|
|
ASSERT(rows() == columns());
|
|
|
|
auto square = multiply(*this);
|
|
for (unsigned i = 0; i < square.rows(); ++i) {
|
|
for (unsigned j = 0; j < square.columns(); ++j) {
|
|
if (square.elements[i][j] && !elements[i][j])
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
template<typename Iter, typename Fn>
|
|
static BooleanMatrix forPredicate(Iter begin, Iter end, Fn pred) {
|
|
std::vector<std::vector<bool>> elements;
|
|
|
|
for (Iter row = begin; row != end; ++row) {
|
|
elements.emplace_back();
|
|
for (Iter col = begin; col != end; ++col)
|
|
elements.back().push_back(pred(*row, *col));
|
|
}
|
|
|
|
return BooleanMatrix(elements);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // SWIFT_SEMA_RELATION_H
|