LearnTA  0.0.1
juxtaposed_zone.hh
1 
6 #pragma once
7 
8 #include "zone.hh"
9 
10 namespace learnta {
12  class JuxtaposedZone : public Zone {
13  private:
14  Eigen::Index leftSize = 0;
15  Eigen::Index rightSize = 0;
16  public:
17  JuxtaposedZone() = default;
18 
27  JuxtaposedZone(const Zone &left, const Zone &right) :
28  leftSize(static_cast<Eigen::Index>(left.getNumOfVar())),
29  rightSize(static_cast<Eigen::Index>(right.getNumOfVar())) {
30  static boost::unordered_map<std::pair<Zone, Zone>, Eigen::Matrix<Bounds, Eigen::Dynamic, Eigen::Dynamic>> memo;
31  const auto key = std::make_pair(left, right);
32  auto it = memo.find(key);
33  if (it != memo.end()) {
34  this->value = it->second;
35  } else {
36  this->value.resize(leftSize + rightSize + 1, leftSize + rightSize + 1);
37  this->value.fill(Bounds(std::numeric_limits<double>::max(), false));
38  // Copy the constraints in left
39  this->value.block(0, 0, left.value.cols(), left.value.rows()) = left.value;
40  // Copy the constraints in right
41  this->value.block(left.value.cols(), left.value.rows(), right.value.cols() - 1, right.value.rows() - 1) =
42  right.value.block(1, 1, right.value.cols() - 1, right.value.rows() - 1);
43  this->value.block(0, left.value.rows(), 1, right.value.rows() - 1) =
44  right.value.block(0, 1, 1, right.value.rows() - 1);
45  this->value.block(left.value.cols(), 0, right.value.cols() - 1, 1) =
46  right.value.block(1, 0, right.value.cols() - 1, 1);
47 
48  this->canonize();
49  memo[key] = this->value;
50  }
51  }
52 
62  JuxtaposedZone(const Zone &left, const Zone &right, Eigen::Index commonVariableSize) :
63  leftSize(static_cast<Eigen::Index>(left.getNumOfVar())),
64  rightSize(static_cast<Eigen::Index>(right.getNumOfVar())) {
65  static boost::unordered_map<std::tuple<Zone, Zone, Eigen::Index>, Eigen::Matrix<Bounds, Eigen::Dynamic, Eigen::Dynamic>> memoWithCommon;
66  const auto key = std::make_tuple(left, right, commonVariableSize);
67  auto it = memoWithCommon.find(key);
68  if (it != memoWithCommon.end()) {
69  this->value = it->second;
70  } else {
71  const auto M = leftSize;
72  const auto N = rightSize;
73  const auto L = commonVariableSize;
74  const auto resultVariableSize = M + N - L;
75  const auto commonBeginIndex = M - L + 1;
76  const auto commonBeginInRightIndex = N - L + 1;
77  const auto rightBeginIndex = M + 1;
78  this->value.resize(resultVariableSize + 1, resultVariableSize + 1);
79  this->value.fill(Bounds(std::numeric_limits<double>::max(), false));
80 
81  // Copy the constraints in left
82  this->value.block(0, 0, left.value.cols(), left.value.rows()) = left.value;
83 
84  // Take the conjunction with the constraints in the common part of right
85  if (L > 0) {
86  this->value.block(commonBeginIndex, commonBeginIndex, L, L) =
87  this->value.block(commonBeginIndex, commonBeginIndex, L, L).cwiseMin(
88  right.value.block(commonBeginInRightIndex, commonBeginInRightIndex, L, L));
89  this->value.block(0, commonBeginIndex, 1, L) = this->value.block(0, commonBeginIndex, 1, L).cwiseMin(
90  right.value.block(0, commonBeginInRightIndex, 1, L));
91  this->value.block(commonBeginIndex, 0, L, 1) = this->value.block(commonBeginIndex, 0, L, 1).cwiseMin(
92  right.value.block(commonBeginInRightIndex, 0, L, 1));
93  }
94 
95  this->canonize();
96 
97  // Copy the constraints in the right
98  this->value.block(rightBeginIndex, rightBeginIndex, N - L, N - L) = right.value.block(1, 1, N - L, N - L);
99  this->value.block(0, rightBeginIndex, 1, N - L) = right.value.block(0, 1, 1, N - L);
100  this->value.block(rightBeginIndex, 0, N - L, 1) = right.value.block(1, 0, N - L, 1);
101 
102  this->canonize();
103 
104  // Take the conjunction with the constraints between the common and the unique parts of right
105  if (L > 0) {
106  this->value.block(rightBeginIndex, commonBeginIndex, N - L, L) =
107  this->value.block(rightBeginIndex, commonBeginIndex, N - L, L).cwiseMin(
108  right.value.block(1, commonBeginInRightIndex, N - L, L));
109  this->value.block(commonBeginIndex, rightBeginIndex, L, N - L) =
110  this->value.block(commonBeginIndex, rightBeginIndex, L, N - L).cwiseMin(
111  right.value.block(commonBeginInRightIndex, 1, L, N - L));
112  }
113 
114  this->canonize();
115  memoWithCommon[key] = this->value;
116  }
117  }
118 
127  void addRenaming(const std::vector<std::pair<std::size_t, std::size_t>> &renaming) {
128  std::vector<ClockVariables> modifiedVariables;
129  modifiedVariables.reserve(renaming.size() * 2);
130  for (const auto &[leftClock, rightClock]: renaming) {
131  // Assert the pre-condition
132  assert(leftClock < static_cast<std::size_t>(leftSize));
133  assert(rightClock < static_cast<std::size_t>(rightSize));
134  // add T[first][N] == T[second][N]
135  Eigen::Index leftIndex = static_cast<Eigen::Index>(leftClock) + 1;
136  Eigen::Index rightIndex = static_cast<Eigen::Index>(rightClock) + leftSize + 1;
137  this->value(leftIndex, rightIndex) = std::min(this->value(leftIndex, rightIndex), {0, true});
138  this->value(rightIndex, leftIndex) = std::min(this->value(rightIndex, leftIndex), {0, true});
139  modifiedVariables.push_back(leftIndex);
140  modifiedVariables.push_back(rightIndex);
141  }
142  // this->canonize();
143  for (const ClockVariables modifiedVariable: modifiedVariables) {
144  this->close1(modifiedVariable);
145  }
146  }
147 
149  [[nodiscard]] auto makeRenaming() const {
150  std::vector<std::pair<std::size_t, std::size_t>> renaming;
151  for (Eigen::Index leftIndex = 1; leftIndex <= leftSize; ++leftIndex) {
152  for (Eigen::Index rightIndex = leftSize + 1; rightIndex <= rightSize + leftSize; ++rightIndex) {
153  if (this->value(leftIndex, rightIndex) == Bounds{0, true} && this->value(rightIndex, leftIndex) == Bounds{0, true}) {
154  renaming.emplace_back(leftIndex - 1, rightIndex - leftSize - 1);
155  }
156  }
157  }
158 
159  return renaming;
160  }
161 
167  [[nodiscard]] Zone getRight() const {
168  if (static_cast<Eigen::Index>(this->getNumOfVar()) != this->leftSize + this->rightSize) {
169  BOOST_LOG_TRIVIAL(error) << "JuxtaposedZone::getRight assumes that there is no common variables";
170  abort();
171  }
172  Zone right = Zone::top(this->rightSize + 1);
173 
174  right.value.block(1, 1, right.value.cols() - 1, right.value.rows() - 1) =
175  this->value.block(leftSize + 1, leftSize + 1, right.value.cols() - 1, right.value.rows() - 1);
176  right.value.block(0, 1, 1, right.value.rows() - 1) =
177  this->value.block(0, leftSize + 1, 1, right.value.rows() - 1);
178  right.value.block(1, 0, right.value.cols() - 1, 1) =
179  this->value.block(leftSize + 1, 0, right.value.cols() - 1, 1);
180 
181  right.canonize();
182  return right;
183  }
184 
185  [[nodiscard]] Eigen::Index getLeftSize() const {
186  return leftSize;
187  }
188  };
189 }
A zone constructed by juxtaposing two zones with or without shared variables.
Definition: juxtaposed_zone.hh:12
Zone getRight() const
Return the right side zone.
Definition: juxtaposed_zone.hh:167
auto makeRenaming() const
Make renaming constraints.
Definition: juxtaposed_zone.hh:149
JuxtaposedZone(const Zone &left, const Zone &right)
Juxtapose two zones without shared variables.
Definition: juxtaposed_zone.hh:27
JuxtaposedZone(const Zone &left, const Zone &right, Eigen::Index commonVariableSize)
Juxtapose two zones with shared variables.
Definition: juxtaposed_zone.hh:62
void addRenaming(const std::vector< std::pair< std::size_t, std::size_t >> &renaming)
Add renaming constraints.
Definition: juxtaposed_zone.hh:127
Definition: experiment_runner.hh:23
Implementation of a zone with DBM.
Definition: zone.hh:24
std::size_t getNumOfVar() const noexcept
Definition: zone.hh:66
void canonize()
make the zone canonical
Definition: zone.hh:314
void close1(ClockVariables x)
Close using only x.
Definition: zone.hh:261
Bounds M
The threshold for the normalization.
Definition: zone.hh:28
Eigen::Matrix< Bounds, Eigen::Dynamic, Eigen::Dynamic > value
The matrix representing the DBM.
Definition: zone.hh:26
static Zone top(std::size_t size)
Make the zone of size size with no constraints.
Definition: zone.hh:84