8 #include "juxtaposed_zone.hh"
9 #include "timed_automaton.hh"
38 this->zone =
Zone::top(accumulatedDuration.size() + 1);
39 for (std::size_t i = 0; i < accumulatedDuration.size(); ++i) {
40 for (std::size_t j = i; j < accumulatedDuration.size(); ++j) {
42 const auto concreteDifference = accumulatedDuration.at(i) -
43 ((j + 1 < accumulatedDuration.size()) ? accumulatedDuration.at(j + 1) : 0);
44 if (std::floor(concreteDifference) == concreteDifference) {
48 this->
restrictUpperBound(i, j, Bounds{std::floor(concreteDifference) + 1,
false},
true);
63 for (std::size_t i = 0; i < accumulatedDuration.size(); ++i) {
64 for (std::size_t j = i; j < accumulatedDuration.size(); ++j) {
66 const auto concreteDifference = accumulatedDuration.at(i) -
67 ((j + 1 < accumulatedDuration.size()) ? accumulatedDuration.at(j + 1) : 0);
68 result.restrictUpperBound(i, j, Bounds{concreteDifference,
true},
true);
69 result.restrictLowerBound(i, j, Bounds{-concreteDifference,
true},
true);
83 return timedCondition;
89 [[nodiscard]]
size_t size()
const {
99 for (
int i = 0; i <
zone.
value.cols(); i++) {
100 for (
int j = i + 1; j <
zone.
value.cols(); j++) {
104 if ((!
learnta::isPoint(upperBound, lowerBound)) and (!isUnitOpen(upperBound, lowerBound))) {
153 const size_t N = this->
size();
154 const size_t M = another.
size();
157 result.
value.block(0, 0, N + 1, N + 1) = this->zone.
value;
158 for (std::size_t i = N + 1; i < N + M; ++i) {
160 result.
value.block(1, i, N, 1) = this->zone.
value.block(1, 0, N, 1);
162 result.
value.block(i, 1, 1, N) = this->zone.
value.block(0, 1, 1, N);
166 result.
value.block(N + 1, N + 1, M - 1, M - 1) = another.
zone.
value.block(2, 2, M - 1, M - 1);
168 result.
value.block(N + 1, 0, M - 1, 1) = another.
zone.
value.block(2, 0, M - 1, 1);
170 result.
value.block(0, N + 1, 1, M - 1) = another.
zone.
value.block(0, 2, 1, M - 1);
172 for (std::size_t i = 1; i <= N; ++i) {
174 result.
value.block(N + 1, i, M - 1, 1).array() += another.
zone.
value.block(2, 1, M - 1, 1).array();
176 result.
value.block(i, N + 1, 1, M - 1).array() += another.
zone.
value.block(1, 2, 1, M - 1).array();
179 result.
value.block(1, 0, N, 1).array() += another.
zone.
value(1, 0);
181 result.
value.block(0, 1, 1, N).array() += another.
zone.
value(0, 1);
220 assert(0 <= i && i < this->
size());
221 assert(0 <= j && j < this->
size());
222 if (j == this->
size() - 1) {
223 return this->zone.
value(0, i + 1);
225 return this->zone.
value(j + 2, i + 1);
233 assert(0 <= i && i < this->
size());
234 assert(0 <= j && j < this->
size());
235 if (j == this->
size() - 1) {
236 return this->zone.
value(i + 1, 0);
238 return this->zone.
value(i + 1, j + 2);
248 assert(0 <= i && i < this->
size());
249 assert(0 <= j && j < this->
size());
250 if (j == this->
size() - 1) {
251 this->zone.
value(0, i + 1) = force ? lowerBound : std::min(lowerBound, this->zone.
value(0, i + 1));
253 this->zone.
value(j + 2, i + 1) = force ? lowerBound : std::min(lowerBound, this->zone.
value(j + 2, i + 1));
264 assert(0 <= i && i < this->
size());
265 assert(0 <= j && j < this->
size());
266 if (j == this->
size() - 1) {
267 this->zone.
value(i + 1, 0) = force ? upperBound : std::min(upperBound, this->zone.
value(i + 1, 0));
269 this->zone.
value(i + 1, j + 2) = force ? upperBound : std::min(upperBound, this->zone.
value(i + 1, j + 2));
299 void enumerate(std::vector<TimedCondition> &simpleConditions)
const {
301 simpleConditions = {*
this};
304 std::vector<TimedCondition> currentConditions = {*
this};
305 for (std::size_t i = 0; i < this->
size(); i++) {
306 for (std::size_t j = i; j < this->
size(); j++) {
307 std::vector<TimedCondition> nextConditions;
309 if (timedCondition.isSimple()) {
310 simpleConditions.push_back(timedCondition);
313 auto lowerBound = timedCondition.getLowerBound(i, j);
314 const auto upperBound = timedCondition.getUpperBound(i, j);
315 if (
learnta::isPoint(upperBound, lowerBound) or isUnitOpen(upperBound, lowerBound)) {
316 nextConditions.push_back(timedCondition);
318 Bounds currentUpperBound = lowerBound.second ? -lowerBound : std::make_pair(-lowerBound.first + 1,
false);
319 while (currentUpperBound <= upperBound) {
320 auto currentTimedCondition = timedCondition;
321 currentTimedCondition.restrictLowerBound(i, j, lowerBound,
false);
322 currentTimedCondition.restrictUpperBound(i, j, currentUpperBound,
false);
323 if (lowerBound.second) {
324 currentUpperBound = {-lowerBound.first + 1,
false};
325 lowerBound.second =
false;
327 currentUpperBound = std::make_pair(-lowerBound.first + 1,
true);
328 lowerBound = {lowerBound.first - 1,
true};
330 if (currentTimedCondition.isSimple()) {
331 simpleConditions.push_back(currentTimedCondition);
333 nextConditions.push_back(currentTimedCondition);
338 currentConditions = std::move(nextConditions);
339 if (currentConditions.empty()) {
357 [[nodiscard]] std::vector<TimedCondition>
enumerate()
const {
358 std::vector<TimedCondition> simpleConditions;
361 return simpleConditions;
370 for (
const auto i: variables) {
372 Bounds &upperBound = result.
value(i + 1, 0);
373 Bounds &lowerBound = result.
value(0, i + 1);
374 if (lowerBound.second) {
376 upperBound.second =
false;
377 lowerBound.second =
false;
380 lowerBound.second =
true;
381 upperBound.second =
true;
392 for (
const auto i: variables) {
394 Bounds &upperBound = this->zone.
value(i + 1, 0);
395 Bounds &lowerBound = this->zone.
value(0, i + 1);
396 if (lowerBound.second) {
398 upperBound.second =
false;
399 lowerBound.second =
false;
402 lowerBound.second =
true;
403 upperBound.second =
true;
413 for (std::size_t i = 0; i < this->zone.
getNumOfVar(); i++) {
415 Bounds &upperBound = this->zone.
value(i + 1, 0);
416 if (upperBound.second) {
417 upperBound = Bounds{std::numeric_limits<double>::max(),
false};
426 for (std::size_t i = 0; i < this->zone.
getNumOfVar(); i++) {
428 this->zone.
value(i + 1, 0) = Bounds{std::numeric_limits<double>::max(),
false};
438 for (
const auto i: variables) {
440 Bounds &upperBound = result.
value(1, (i + 2) % result.
value.cols());
441 Bounds &lowerBound = result.
value((i + 2) % result.
value.cols(), 1);
444 upperBound.second =
false;
445 lowerBound.second =
false;
448 lowerBound.second =
true;
449 upperBound.second =
true;
462 for (
const auto i: variables) {
464 Bounds &upperBound = result.
value(i + 1, 0);
465 Bounds &lowerBound = result.
value(0, i + 1);
467 upperBound.second =
false;
469 lowerBound.second =
false;
471 lowerBound.second =
true;
473 upperBound.second =
true;
486 for (
const auto i: variables) {
488 Bounds &upperBound = (i == this->
size() - 1) ? result.
value(1, 0) : result.
value(1, i + 2);
489 Bounds &lowerBound = (i == this->
size() - 1) ? result.
value(0, 1) : result.
value(i + 2, 1);
491 upperBound.second =
false;
493 lowerBound.second =
false;
495 lowerBound.second =
true;
497 upperBound.second =
true;
510 result.
zone.
value.conservativeResize(N + 1, N + 1);
526 result.
zone.
value.conservativeResize(N - 1, N - 1);
538 result.
zone.
value.conservativeResize(N - 1, N - 1);
550 return this->zone.
value.col(0).tail(this->
size()).unaryExpr([](
const Bounds &bound) {
559 const auto N = this->zone.
value.cols();
562 result.value.block(2, 2, N - 1, N - 1) = this->zone.
value.block(1, 1, N - 1, N - 1);
563 result.value.block(0, 2, 1, N - 1) = this->zone.
value.block(0, 1, 1, N - 1);
564 result.value.block(2, 0, N - 1, 1) = this->zone.
value.block(1, 0, N - 1, 1);
566 result.value.col(1) = result.value.col(2);
567 result.value.row(1) = result.value.row(2);
569 result.value(1, 2) = {0,
true};
570 result.value(2, 1) = {0,
true};
581 const size_t examinedVariableSize)
const {
582 std::vector<std::size_t> result;
583 for (std::size_t i = 1; i <= examinedVariableSize; ++i) {
584 if (this->zone.
value.col(i) != originalCondition.
zone.
value.col(i) ||
585 this->zone.value.row(i) != originalCondition.
zone.
value.row(i)) {
586 result.push_back(i - 1);
596 bool operator!=(
const TimedCondition &condition)
const {
597 return this->
size() != condition.size() || !this->zone.
strictEqual(condition.zone);
603 [[nodiscard]] std::vector<Constraint>
toGuard()
const {
605 BOOST_LOG_TRIVIAL(trace) <<
"Constraint:" << *
this;
607 std::vector<Constraint> result;
608 const auto N = this->
size();
609 result.reserve(N * 2);
610 for (std::size_t i = 0; i < this->
size(); ++i) {
613 if (lowerBound.first != std::numeric_limits<double>::max() && lowerBound != Bounds{0, true}) {
614 if (lowerBound.second) {
620 if (upperBound.first != std::numeric_limits<double>::max()) {
621 if (upperBound.second) {
630 BOOST_LOG_TRIVIAL(trace) <<
"Guard: " << result;
641 return !(this->
getUpperBound(N - 1, N - 1) == Bounds{0,
true} &&
678 [[nodiscard]]
explicit operator bool() {
682 [[nodiscard]]
TimedCondition applyResets(
const TATransition::Resets &resets)
const {
683 auto newCondition = *
this;
684 for (
const auto &[updatedVariable, assignedValue]: resets) {
686 assert(assignedValue.index() == 0);
688 newCondition.zone.unconstrain(updatedVariable);
689 if (std::get<double>(assignedValue) == std::floor(std::get<double>(assignedValue))) {
690 newCondition.restrictLowerBound(updatedVariable, newCondition.size() - 1,
691 Bounds{-std::get<double>(assignedValue), true},
true);
692 newCondition.restrictUpperBound(updatedVariable, newCondition.size() - 1,
693 Bounds{std::get<double>(assignedValue), true},
true);
695 newCondition.restrictLowerBound(updatedVariable, newCondition.size() - 1,
696 Bounds{-std::floor(std::get<double>(assignedValue)), false},
true);
697 newCondition.restrictUpperBound(updatedVariable, newCondition.size() - 1,
698 Bounds{std::ceil(std::get<double>(assignedValue)), false},
true);
714 const std::size_t targetClockSize)
const {
716 std::vector<std::pair<std::size_t, std::size_t>> renaming;
717 for (
const auto &[updatedVariable, assignedValue]: resets) {
718 if (updatedVariable >= targetClockSize) {
721 if(assignedValue.index() == 0) {
723 if (std::get<double>(assignedValue) == std::floor(std::get<double>(assignedValue))) {
724 newCondition.restrictLowerBound(updatedVariable, newCondition.size() - 1,
725 Bounds{-std::get<double>(assignedValue), true},
true);
726 newCondition.restrictUpperBound(updatedVariable, newCondition.size() - 1,
727 Bounds{std::get<double>(assignedValue), true},
true);
729 newCondition.restrictLowerBound(updatedVariable, newCondition.size() - 1,
730 Bounds{-std::floor(std::get<double>(assignedValue)), false},
true);
731 newCondition.restrictUpperBound(updatedVariable, newCondition.size() - 1,
732 Bounds{std::ceil(std::get<double>(assignedValue)), false},
true);
734 for (
const auto &[updatedVariable2, assignedValue2]: resets) {
735 if (updatedVariable2 < updatedVariable && assignedValue2.index() == 0) {
736 double difference = std::get<double>(assignedValue2) - std::get<double>(assignedValue);
738 if (difference == std::floor(difference)) {
739 newCondition.restrictLowerBound(updatedVariable2, updatedVariable - 1,
740 Bounds{-difference,
true},
true);
741 newCondition.restrictUpperBound(updatedVariable2, updatedVariable - 1,
742 Bounds{difference,
true},
true);
744 newCondition.restrictLowerBound(updatedVariable2, updatedVariable - 1,
745 Bounds{-std::floor(difference),
false},
true);
746 newCondition.restrictUpperBound(updatedVariable2, updatedVariable - 1,
747 Bounds{std::ceil(difference),
false},
true);
753 renaming.emplace_back(std::get<ClockVariables>(assignedValue), updatedVariable);
757 for (ClockVariables clock = 0; clock < targetClockSize; ++clock) {
758 auto it = std::find_if(resets.begin(), resets.end(), [&clock] (
const auto &reset) {
759 return reset.first == clock;
761 if (it == resets.end()) {
762 renaming.emplace_back(clock, clock);
765 auto juxtaposed = *
this ^ newCondition;
766 juxtaposed.addRenaming(renaming);
774 [[nodiscard]]
bool isPoint(std::size_t i)
const {
778 [[nodiscard]] std::size_t hash_value()
const {
779 return learnta::hash_value(this->zone);
782 std::ostream &print(std::ostream &os)
const {
783 for (std::size_t i = 0; i < this->
size(); ++i) {
784 for (std::size_t j = i; j < this->
size(); ++j) {
787 os << -lowerBound.first << (lowerBound.second ?
" <= " :
" < ")
788 <<
"T_{" << i <<
", " << j <<
"} "
789 << (upperBound.second ?
" <= " :
" < ") << upperBound.first;
790 if (i != this->
size() - 1 || j != this->
size() - 1) {
798 friend class NeighborConditions;
805 for (std::size_t i = 0; i < cond.
size(); ++i) {
806 for (std::size_t j = i; j < cond.
size(); ++j) {
809 os << -lowerBound.first << (lowerBound.second ?
" <= " :
" < ")
810 <<
"T_{" << i <<
", " << j <<
"} "
811 << (upperBound.second ?
" <= " :
" < ") << upperBound.first;
812 if (i != cond.
size() - 1 || j != cond.
size() - 1) {
821 return learnta::print(os, b);
825 return timedCondition.hash_value();
Definition: constraint.hh:210
A zone constructed by juxtaposing two zones with or without shared variables.
Definition: juxtaposed_zone.hh:12
A timed condition, a finite conjunction of inequalities of the form , where and .
Definition: timed_condition.hh:19
TimedCondition removeN() const
Remove .
Definition: timed_condition.hh:523
std::vector< std::size_t > getStrictlyConstrainedVariables(const TimedCondition &originalCondition, const size_t examinedVariableSize) const
Returns the set of variables strictly constrained compared with the original condition.
Definition: timed_condition.hh:580
TimedCondition extendZero() const
Rename each variable to and add such that .
Definition: timed_condition.hh:558
void restrictUpperBound(std::size_t i, std::size_t j, Bounds upperBound, bool force=false)
Restrict the upper bound of .
Definition: timed_condition.hh:263
bool hasEqualityN() const
Return if there is .
Definition: timed_condition.hh:548
bool isSimple() const
Returns if this timed condition is simple.
Definition: timed_condition.hh:98
TimedCondition operator&&(const TimedCondition &another) const
Returns the intersection of two timed conditions.
Definition: timed_condition.hh:664
void removeUpperBoundAssign()
Remove the upper bounds.
Definition: timed_condition.hh:425
static TimedCondition makeExact(const std::vector< double > &accumulatedDuration)
Construct a timed condition from concrete values of T_{i,j}. The generated timed condition only conta...
Definition: timed_condition.hh:61
TimedCondition applyResets(const TATransition::Resets &resets, const std::size_t targetClockSize) const
Return the timed condition after applying the given reset.
Definition: timed_condition.hh:713
bool hasPrefix() const
Return if this timed condition has a (continuous) prefix.
Definition: timed_condition.hh:638
TimedCondition predecessor(const std::deque< ClockVariables > &variables) const
Make a continuous predecessor by backward-elapsing variables.
Definition: timed_condition.hh:435
bool hasSuffix() const
Return if this timed condition has a (continuous) suffix.
Definition: timed_condition.hh:648
TimedCondition suffix(const std::deque< ClockVariables > &variables) const
Make a continuous suffix.
Definition: timed_condition.hh:483
Bounds getUpperBound(std::size_t i, std::size_t j) const
Returns the upper bound of .
Definition: timed_condition.hh:232
void successorAssign(const std::deque< ClockVariables > &variables)
Make a continuous successor by elapsing variables.
Definition: timed_condition.hh:391
TimedCondition successor(const std::deque< ClockVariables > &variables) const
Make a continuous successor by elapsing variables.
Definition: timed_condition.hh:367
void restrictLowerBound(std::size_t i, std::size_t j, Bounds lowerBound, bool force=false)
Restrict the lower bound of .
Definition: timed_condition.hh:247
Bounds getLowerBound(std::size_t i, std::size_t j) const
Returns the lower bound of .
Definition: timed_condition.hh:219
TimedCondition(const std::vector< double > &accumulatedDuration)
Construct a timed condition from concrete values of T_{i,j}. The generated timed condition is the sim...
Definition: timed_condition.hh:37
std::vector< Constraint > toGuard() const
Definition: timed_condition.hh:603
size_t size() const
Return the number of the variables in this timed condition.
Definition: timed_condition.hh:89
TimedCondition removeZero() const
Remove TODO: Implement it.
Definition: timed_condition.hh:535
TimedCondition prefix(const std::deque< ClockVariables > &variables) const
Make a continuous prefix.
Definition: timed_condition.hh:459
JuxtaposedZone juxtaposeRight(const TimedCondition &right, Eigen::Index commonVariableSize) const
Juxtapose two timed conditions renaming variable.
Definition: timed_condition.hh:203
std::vector< TimedCondition > enumerate() const
Make a vector of simple timed conditions in this timed condition.
Definition: timed_condition.hh:357
TimedCondition extendN() const
Add another variable such that .
Definition: timed_condition.hh:507
bool includes(const TimedCondition &condition) const
Return if this timed condition includes the given timed condition.
Definition: timed_condition.hh:657
void enumerate(std::vector< TimedCondition > &simpleConditions) const
Make a vector of simple timed conditions in this timed condition.
Definition: timed_condition.hh:299
JuxtaposedZone operator^(const TimedCondition &another) const
Juxtapose two timed conditions.
Definition: timed_condition.hh:194
Zone zone
A zone to represent the timing constraint.
Definition: timed_condition.hh:24
bool isSatisfiableNoCanonize() const
Returns if the timed condition is satisfiable.
Definition: timed_condition.hh:671
void removeEqualityUpperBoundAssign()
Remove the equality upper bound.
Definition: timed_condition.hh:411
TimedCondition convexHull(const TimedCondition &condition) const
Return the convex hull of this timed condition and the given timed condition.
Definition: timed_condition.hh:284
bool isPoint(std::size_t i) const
Check if T_{i, |T|} is a point.
Definition: timed_condition.hh:774
static TimedCondition empty()
Construct the empty timed condition, i.e. .
Definition: timed_condition.hh:79
TimedCondition operator+(const TimedCondition &another) const
Concatenate two timed conditions.
Definition: timed_condition.hh:152
void convexHullAssign(const TimedCondition &condition)
Make it to be the convex hull of this timed condition and the given timed condition.
Definition: timed_condition.hh:277
JuxtaposedZone juxtaposeLeft(const TimedCondition &left, Eigen::Index commonVariableSize) const
Juxtapose two timed conditions renaming variable.
Definition: timed_condition.hh:212
Definition: experiment_runner.hh:23
static bool isPoint(const Bounds &upperBound, const Bounds &lowerBound)
Check if the upper and lower bounds define a point.
Definition: bounds.hh:17
Implementation of a zone with DBM.
Definition: zone.hh:24
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
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
bool isSatisfiableNoCanonize() const
check if the zone is satisfiable
Definition: zone.hh:333
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
bool isSatisfiable()
check if the zone is satisfiable
Definition: zone.hh:323