6 #include <unordered_map>
7 #include <boost/unordered_map.hpp>
8 #include <boost/range/adaptor/reversed.hpp>
10 #include "common_types.hh"
12 #include "constraint.hh"
26 Eigen::Matrix <Bounds, Eigen::Dynamic, Eigen::Dynamic>
value;
35 explicit Zone(
const Eigen::Matrix <Bounds, Eigen::Dynamic, Eigen::Dynamic> &
value) :
36 Zone(Eigen::Matrix<Bounds, Eigen::Dynamic, Eigen::Dynamic>(
value)) {}
42 Zone(Eigen::Matrix <Bounds, Eigen::Dynamic, Eigen::Dynamic>
value, Bounds m) :
51 explicit Zone(
const std::vector<double> &valuation, Bounds
M) :
M(
std::move(
M)) {
52 value.resize(valuation.size() + 1, valuation.size() + 1);
53 value.fill(Bounds(std::numeric_limits<double>::max(),
false));
54 for (std::size_t i = 0; i < valuation.size(); ++i) {
55 this->
tighten(i, -1, Bounds{valuation.at(i),
true});
56 this->
tighten(-1, i, Bounds{-valuation.at(i),
true});
66 [[nodiscard]]
inline std::size_t
getNumOfVar() const noexcept {
67 return value.cols() - 1;
73 if (zeroZone.
value.cols() == size) {
76 zeroZone.
value.resize(size, size);
77 zeroZone.
value.fill(Bounds(0,
true));
86 if (
static_cast<std::size_t
>(topZone.
value.cols()) == size) {
89 topZone.
value.resize(size, size);
90 topZone.
value.fill(Bounds(std::numeric_limits<double>::max(),
false));
95 void tighten(ClockVariables x, ClockVariables y, Bounds c) {
105 switch (constraint.odr) {
106 case learnta::Constraint::Order::ge:
108 this->
tighten(-1, constraint.x, Bounds{-constraint.c, true});
110 case learnta::Constraint::Order::gt:
112 this->
tighten(-1, constraint.x, Bounds{-constraint.c, false});
114 case learnta::Constraint::Order::le:
116 this->
tighten(constraint.x, -1, Bounds{constraint.c, true});
118 case learnta::Constraint::Order::lt:
120 this->
tighten(constraint.x, -1, Bounds{constraint.c, false});
126 void tighten(
const std::vector<Constraint> &constraints) {
127 for (
const auto &constraint: constraints) {
132 void applyResets(
const std::vector<std::pair<ClockVariables, std::variant<double, ClockVariables>>> &resets) {
134 for (
const auto &[resetVariable, updatedVariable]: resets) {
135 if (updatedVariable.index() == 1 && resetVariable != std::get<ClockVariables>(updatedVariable)) {
137 this->
value(resetVariable + 1, std::get<ClockVariables>(updatedVariable) + 1) = Bounds{0.0,
true};
138 this->
value(std::get<ClockVariables>(updatedVariable) + 1, resetVariable + 1) = Bounds{0.0,
true};
143 for (
const auto &[resetVariable, updatedVariable]: resets) {
144 if (updatedVariable.index() == 0) {
146 this->
value(0, resetVariable + 1) = Bounds(-std::get<double>(updatedVariable),
true);
147 this->
value(resetVariable + 1, 0) = Bounds(std::get<double>(updatedVariable),
true);
158 void revertResets(
const std::vector<std::pair<ClockVariables, std::variant<double, ClockVariables>>> &resets) {
159 std::vector<ClockVariables> resetVariables;
160 resetVariables.reserve(resets.size());
161 std::unordered_map<ClockVariables, ClockVariables> reverseAssignments;
162 for (
const auto &[resetVariable, updatedVariable]: resets) {
163 resetVariables.push_back(resetVariable);
164 if (updatedVariable.index() == 1 && resetVariable != std::get<ClockVariables>(updatedVariable)) {
165 reverseAssignments[std::get<ClockVariables>(updatedVariable)] = resetVariable;
168 for (
const auto &resetVariable: boost::adaptors::reverse(resetVariables)) {
170 auto it = reverseAssignments.find(resetVariable);
171 if (it != reverseAssignments.end()) {
172 this->
value(it->first + 1, it->second + 1) = Bounds{0.0,
true};
173 this->
value(it->second + 1, it->first + 1) = Bounds{0.0,
true};
183 assert(this->value.cols() == another.
value.cols());
184 assert(this->value.rows() == another.
value.rows());
185 auto result =
Zone{this->value.array().min(another.
value.array())};
196 assert(this->value.cols() == another.
value.cols());
197 assert(this->value.rows() == another.
value.rows());
198 this->value = this->value.cwiseMin(another.
value);
213 result.
value.block(N, N, O, O) = another.
value.block(1, 1, O, O);
214 result.
value.block(0, N + 1, 1, O - 1) = another.
value.block(0, 1, 1, O - 1);
215 result.
value.block(N + 1, 0, O - 1, 1) = another.
value.block(1, 0, O - 1, 1);
217 result.
value.block(0, 0, N + 1, N + 1) = this->
value;
226 [[nodiscard]] std::vector<double>
sample() {
229 std::vector<double> valuation;
232 for (std::size_t i = 0; i < N; i++) {
233 Bounds lowerBound = this->
value(0, i + 1);
234 Bounds upperBound = this->
value(i + 1, 0);
235 if (
isPoint(upperBound, lowerBound)) {
236 valuation[i] = upperBound.first;
238 double lower = std::max(0.0, -lowerBound.first);
239 double upper = upperBound.first;
240 for (std::size_t j = 0; j < i; j++) {
241 Bounds tmpLowerBound = this->
value(j + 1, i + 1);
242 Bounds tmpUpperBound = this->
value(i + 1, j + 1);
243 lower = std::max(lower, -tmpLowerBound.first + valuation[j]);
244 upper = std::min(upper, tmpUpperBound.first + valuation[j]);
246 assert(lower <= upper);
247 if (lowerBound.second) {
248 valuation[i] = lower;
249 }
else if (upper - lower > 0.5) {
250 valuation[i] = lower + 0.5;
252 valuation[i] = (lower + upper) * 0.5;
262 for (
int i = 0; i <
value.rows(); i++) {
274 value(0, x) = Bounds(-0.0,
true);
275 value(x, 0) = Bounds(0.0,
true);
286 value.col(x).fill(Bounds(std::numeric_limits<double>::max(),
false));
287 value.row(x).fill(Bounds(std::numeric_limits<double>::max(),
false));
296 static constexpr Bounds infinity = Bounds(std::numeric_limits<double>::max(),
false);
297 value.col(0).fill(Bounds(infinity));
308 value.row(0).fill(Bounds(0,
true));
315 for (
int k = 0; k <
value.cols(); k++) {
334 return (
value +
value.transpose()).minCoeff() >= Bounds(0.0,
true);
340 explicit operator bool() {
348 static constexpr Bounds infinity = Bounds(std::numeric_limits<double>::max(),
false);
350 if (*it > Bounds{
M.first,
true}) {
351 *it = Bounds(infinity);
352 }
else if (*it < Bounds{-
M.first,
false}) {
353 *it = Bounds(-
M.first,
false);
365 static constexpr Bounds infinity = Bounds(std::numeric_limits<double>::max(),
false);
366 for (std::size_t i = 0; i < this->maxConstraints.size(); ++i) {
367 if (
value(i + 1, 0).
first > this->maxConstraints.at(i)) {
368 value(i + 1, 0) = infinity;
370 if (-
value(0, i + 1).
first > this->maxConstraints.at(i)) {
371 value(0, i + 1) = Bounds{-this->maxConstraints.at(i),
false};
373 for (std::size_t j = 0; j < this->maxConstraints.size(); ++j) {
374 if (
value(i + 1, j + 1).
first > this->maxConstraints.at(i)) {
375 value(i + 1, j + 1) = infinity;
376 }
else if (-
value(0, i + 1).
first > this->maxConstraints.at(i)) {
377 value(i + 1, j + 1) = infinity;
378 }
else if (-
value(0, j + 1).
first > this->maxConstraints.at(j)) {
379 value(i + 1, j + 1) = infinity;
389 value(0, 0) = Bounds(-std::numeric_limits<double>::infinity(),
false);
398 return this->value.cwiseMax(zone.
value) == this->
value;
433 for (
int i = 0; i < zone.
value.cols(); ++i) {
434 for (
int j = 0; j < zone.
value.rows(); ++j) {
444 static inline std::ostream &operator<<(std::ostream &os,
const learnta::Zone &zone) {
445 return learnta::print(os, zone);
449 std::size_t seed = zone.
value.array().size();
450 const auto asVector = zone.
value.array();
457 for (
auto it = asVector.data(); it != asVector.data() + asVector.size(); it++) {
459 value.asD = it->first;
460 seed ^= it->second + value.asI + 0x9e3779b9 + (seed << 6) + (seed >> 2);
Definition: experiment_runner.hh:23
T first(const std::pair< T, U > &pair)
Return the first element of a pair.
Definition: common_types.hh:69
static std::ostream & print(std::ostream &os, const learnta::Zone &zone)
Print the zone.
Definition: zone.hh:432
static bool isPoint(const Bounds &upperBound, const Bounds &lowerBound)
Check if the upper and lower bounds define a point.
Definition: bounds.hh:17
Definition: external_transition_maker.hh:149
A constraint in a guard of transitions.
Definition: constraint.hh:32
Implementation of a zone with DBM.
Definition: zone.hh:24
std::vector< double > maxConstraints
the threshold of each clock variable
Definition: zone.hh:30
Zone(const Eigen::Matrix< Bounds, Eigen::Dynamic, Eigen::Dynamic > &value)
Construct a zone from a matrix representing the zone.
Definition: zone.hh:35
void makeUnsat()
make the zone unsatisfiable
Definition: zone.hh:388
void unconstrain(ClockVariables x)
Unconstrain the constraint on this clock.
Definition: zone.hh:283
std::vector< double > sample()
Return a clock valuation in this zone.
Definition: zone.hh:226
std::size_t getNumOfVar() const noexcept
Definition: zone.hh:66
static Zone zero(int size)
Make the zone of size size such that all the values are zero.
Definition: zone.hh:71
Zone(const std::vector< double > &valuation, Bounds M)
Construct a zone containing only the given valuation.
Definition: zone.hh:51
Zone(Eigen::Matrix< Bounds, Eigen::Dynamic, Eigen::Dynamic > value, Bounds m)
Construct a zone from a matrix representing the zone and the bound.
Definition: zone.hh:42
void elapse()
Assign the strongest post-condition of the delay.
Definition: zone.hh:295
Zone operator&&(const Zone &another) const
Returns the intersection of two zones.
Definition: zone.hh:182
bool strictEqual(Zone z) const
Check the equivalence of two zones.
Definition: zone.hh:425
bool includes(const Zone &zone) const
Return if this zone includes the given zone.
Definition: zone.hh:397
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
void extrapolate()
Extrapolate the zone using the diagonal extrapolation based on maximum constants.
Definition: zone.hh:364
bool isSatisfiableNoCanonize() const
check if the zone is satisfiable
Definition: zone.hh:333
bool operator==(const Zone &z) const
Check the equivalence of two zones.
Definition: zone.hh:406
Eigen::Matrix< Bounds, Eigen::Dynamic, Eigen::Dynamic > value
The matrix representing the DBM.
Definition: zone.hh:26
void reset(ClockVariables x)
Assign a constant value to the clock variable x.
Definition: zone.hh:271
static Zone top(std::size_t size)
Make the zone of size size with no constraints.
Definition: zone.hh:84
Zone operator&=(const Zone &another)
Assign the intersection of two zones.
Definition: zone.hh:195
void revertResets(const std::vector< std::pair< ClockVariables, std::variant< double, ClockVariables >>> &resets)
Make it the weakest precondition of the reset.
Definition: zone.hh:158
void tighten(const Constraint &constraint)
Add a guard of a timed automaton.
Definition: zone.hh:104
void abstractize()
truncate the constraints compared with a constant greater than or equal to M
Definition: zone.hh:347
void tighten(const std::vector< Constraint > &constraints)
Add a set of guards of a timed automaton.
Definition: zone.hh:126
void reverseElapse()
Assign the weakest pre-condition of the delay.
Definition: zone.hh:307
Zone(Eigen::Matrix< Bounds, Eigen::Dynamic, Eigen::Dynamic > &&value)
Construct a zone from a matrix representing the zone.
Definition: zone.hh:39
bool equalIgnoreZero(Zone z) const
Check the equivalence of two zones.
Definition: zone.hh:415
bool isSatisfiable()
check if the zone is satisfiable
Definition: zone.hh:323
Zone operator^(const Zone &another) const
Returns the juxtaposition of two zones.
Definition: zone.hh:207
void tighten(ClockVariables x, ClockVariables y, Bounds c)
add the constraint
Definition: zone.hh:95