26 #include <boost/variant.hpp>
31 #include <unordered_set>
34 #include "intermediate_zone.hh"
35 #include "intersection.hh"
36 #include "kmp_skip_value.hh"
37 #include "sunday_skip_value.hh"
39 #include "word_container.hh"
68 std::vector<boost::variant<double, ClockVariables>> resetTime;
72 const std::vector<boost::variant<double, ClockVariables>> &resetTime,
74 : s(std::move(s)), resetTime(std::move(resetTime)), z(std::move(z)) {}
77 : s(std::move(s)), z(std::move(interval)) {
78 static const std::vector<boost::variant<double, ClockVariables>>
79 zeroResetTime(numOfVar, ClockVariables(1));
81 resetTime = zeroResetTime;
86 using Variables = char;
88 std::vector<double> resetTime;
89 std::pair<double, bool> upperConstraint;
90 std::pair<double, bool> lowerConstraint;
92 const std::pair<double, bool> &upperConstraint,
93 const std::pair<double, bool> &lowerConstraint)
94 : s(std::move(s)), resetTime(std::move(resetTime)),
95 upperConstraint(std::move(upperConstraint)),
96 lowerConstraint(std::move(lowerConstraint)) {}
101 const Bounds &lowerConstraint) {
102 return upperConstraint + lowerConstraint >= Bounds{0.0,
true};
109 std::pair<double, bool> &lowerConstraint,
111 const double comparedValue) {
113 case Constraint::Order::gt:
114 if (lowerConstraint.first < comparedValue) {
115 lowerConstraint.first = comparedValue;
116 lowerConstraint.second = 0;
117 }
else if (lowerConstraint.first == comparedValue) {
118 lowerConstraint.second = 0;
121 case Constraint::Order::ge:
122 if (lowerConstraint.first < comparedValue) {
123 lowerConstraint.first = comparedValue;
124 lowerConstraint.second = 1;
127 case Constraint::Order::lt:
128 if (upperConstraint.first > comparedValue) {
129 upperConstraint.first = comparedValue;
130 upperConstraint.second = 0;
131 }
else if (upperConstraint.first == comparedValue) {
132 upperConstraint.second = 0;
135 case Constraint::Order::le:
136 if (upperConstraint.first > comparedValue) {
137 upperConstraint.first = comparedValue;
138 upperConstraint.second = 1;
150 template <
class InputContainer,
class OutputContainer>
156 const int m = delta.
getM();
157 std::unordered_set<Alphabet> endChars;
158 delta.getEndChars(endChars);
166 [](std::shared_ptr<TAState> s) {
167 return s->next.find(0) == s->next.end();
173 std::vector<std::pair<std::pair<double, bool>, std::pair<double, bool>>>
175 std::vector<IntervalInternalState> CStates;
176 std::vector<IntervalInternalState> LastStates;
177 const Bounds zeroBounds = {0,
true};
184 for (
char c = 0; c < CHAR_MAX; c++) {
185 for (
const auto &edge: initState->next[c]) {
186 if (edge.target.lock()->isMatch) {
189 for (
const auto &constraint: edge.guard) {
192 if (zone.isSatisfiableCanonized()) {
193 init[c].push_back(std::move(zone));
204 while (word.
fetch(i + m - 1)) {
205 bool tooLarge =
false;
208 if (m == 1 && init[word[i].first].size() > 0) {
211 ans.
reserve(ans.
size() + init[word[i].first].size());
213 for (
auto zone: init[word[i].first]) {
215 zone.value.col(0).fill({word[i].second,
false});
216 if (zone.isSatisfiableCanonized()) {
222 for (
auto zone: init[word[i].first]) {
224 zone.value.col(0).fill({word[i].second,
false});
225 zone.value.row(0).fill({-word[i-1].second,
true});
226 if (zone.isSatisfiableCanonized()) {
234 if (m > 1 && word.
fetch(i + m - 1)) {
235 while (endChars.find(word[i + m - 1].first) == endChars.end()) {
236 if (!word.
fetch(i + m)) {
241 i += delta[word[i + m].first];
242 word.setFront(i - 1);
243 if (!word.fetch(i + m - 1)) {
256 std::vector<double> zeroResetTime(A.
clockSize(), 0);
261 {word[i].second,
false},
262 ((i <= 0) ? zeroBounds : Bounds{-word[i - 1].second,
true})};
272 while (!CStates.empty() && word.
fetch(j)) {
273 const Alphabet c = word[j].first;
274 const double t = word[j].second;
277 for (
const auto &config : CStates) {
279 auto it = s->
next.find(c);
280 if (it == s->
next.end()) {
283 for (
const auto &edge : it->second) {
284 auto target = edge.target;
285 if (!target || !target->isMatch) {
288 Bounds upperBeginConstraint = config.upperConstraint;
289 Bounds lowerBeginConstraint = config.lowerConstraint;
290 Bounds upperEndConstraint = {word[j].second,
true};
291 Bounds lowerEndConstraint =
292 ((j > 0) ? Bounds{-word[j - 1].second,
false} : zeroBounds);
295 Bounds upperDeltaConstraint =
296 upperEndConstraint + lowerBeginConstraint;
298 Bounds lowerDeltaConstraint =
299 std::min(lowerEndConstraint + upperBeginConstraint, zeroBounds);
301 auto tmpResetTime = config.resetTime;
303 for (
const auto &delta : edge.guard) {
304 if (tmpResetTime[delta.x]) {
306 case Constraint::Order::lt:
307 case Constraint::Order::le:
309 std::min(upperEndConstraint,
310 Bounds{delta.c + tmpResetTime[delta.x],
311 {delta.odr == Constraint::Order::le}});
313 upperDeltaConstraint =
314 std::min(upperDeltaConstraint,
315 upperEndConstraint + lowerBeginConstraint);
317 upperBeginConstraint =
318 std::min(upperBeginConstraint,
319 lowerDeltaConstraint + upperEndConstraint);
321 case Constraint::Order::gt:
322 case Constraint::Order::ge:
324 std::min(lowerEndConstraint,
325 Bounds{-delta.c - tmpResetTime[delta.x],
326 {delta.odr == Constraint::Order::ge}});
328 lowerDeltaConstraint =
329 std::min(lowerDeltaConstraint,
330 upperBeginConstraint + lowerEndConstraint);
332 lowerBeginConstraint =
333 std::min(lowerBeginConstraint,
334 lowerEndConstraint + upperDeltaConstraint);
339 case Constraint::Order::lt:
340 case Constraint::Order::le:
341 upperDeltaConstraint = std::min(
342 upperDeltaConstraint,
343 Bounds{delta.c, {delta.odr == Constraint::Order::le}});
346 std::min(upperEndConstraint,
347 upperDeltaConstraint + upperBeginConstraint);
349 lowerBeginConstraint =
350 std::min(lowerBeginConstraint,
351 lowerEndConstraint + upperDeltaConstraint);
353 case Constraint::Order::gt:
354 case Constraint::Order::ge:
355 lowerDeltaConstraint = std::min(
356 lowerDeltaConstraint,
357 Bounds{-delta.c, {delta.odr == Constraint::Order::ge}});
359 upperBeginConstraint =
360 std::min(upperBeginConstraint,
361 lowerDeltaConstraint + upperEndConstraint);
364 std::min(lowerEndConstraint,
365 lowerBeginConstraint + lowerDeltaConstraint);
372 lowerBeginConstraint) ||
375 lowerDeltaConstraint)) {
379 Zone ansZone = Zone::zero(3);
380 ansZone.value(0, 1) = std::move(lowerBeginConstraint);
381 ansZone.value(1, 0) = std::move(upperBeginConstraint);
382 ansZone.value(0, 2) = std::move(lowerEndConstraint);
383 ansZone.value(2, 0) = std::move(upperEndConstraint);
384 ansZone.value(1, 2) = std::move(lowerDeltaConstraint);
385 ansZone.value(2, 1) = std::move(upperDeltaConstraint);
392 LastStates = std::move(CStates);
393 for (
const auto &config : LastStates) {
395 auto it = s->
next.find(c);
396 if (it == s->
next.end()) {
399 for (
auto &edge : it->second) {
400 const auto target = edge.target;
405 Bounds upperBeginConstraint = config.upperConstraint;
406 Bounds lowerBeginConstraint = config.lowerConstraint;
407 bool transitable =
true;
409 for (
const auto &delta : edge.guard) {
410 if (config.resetTime[delta.x]) {
411 if (!delta.satisfy(t - config.resetTime[delta.x])) {
417 case Constraint::Order::lt:
418 case Constraint::Order::le:
419 lowerBeginConstraint =
420 std::min(lowerBeginConstraint,
422 {delta.odr == Constraint::Order::le}});
424 case Constraint::Order::gt:
425 case Constraint::Order::ge:
426 upperBeginConstraint =
427 std::min(upperBeginConstraint,
429 {delta.odr == Constraint::Order::ge}});
436 lowerBeginConstraint)) {
440 auto tmpResetTime = config.resetTime;
441 for (
auto i : edge.resetVars) {
445 CStates.emplace_back(edge.target, std::move(tmpResetTime),
446 std::move(upperBeginConstraint),
447 std::move(lowerBeginConstraint));
452 if (!word.
fetch(j)) {
453 LastStates = std::move(CStates);
458 greatestN = std::max(beta[istate.s], greatestN);
476 std::array<std::vector<IntermediateZone>, CHAR_MAX> init;
477 std::vector<InternalState> CStates;
478 std::vector<InternalState> LastStates;
485 for (
char c = 0; c < CHAR_MAX; c++) {
486 for (
const auto &edge: initState->next[c]) {
487 if (edge.target.lock()->isMatch) {
490 for (
const auto &constraint: edge.guard) {
493 if (zone.isSatisfiableCanonized()) {
494 init[c].push_back(std::move(zone));
505 while (word.
fetch(i + m - 1)) {
506 bool tooLarge =
false;
509 if (m == 1 && init[word[i].first].size() > 0) {
512 ans.
reserve(ans.
size() + init[word[i].first].size());
514 for (
auto zone: init[word[i].first]) {
516 zone.value.col(0).fill({word[i].second,
false});
517 if (zone.isSatisfiableCanonized()) {
523 for (
auto zone: init[word[i].first]) {
525 zone.value.col(0).fill({word[i].second,
false});
526 zone.value.row(0).fill({-word[i-1].second,
true});
527 if (zone.isSatisfiableCanonized()) {
535 if (m > 1 && word.
fetch(i + m - 1)) {
536 while (endChars.find(word[i + m - 1].first) == endChars.end()) {
537 if (!word.
fetch(i + m)) {
542 i += delta[word[i + m].first];
543 word.setFront(i - 1);
544 if (!word.fetch(i + m - 1)) {
560 ((i <= 0) ? Bounds{0,
true} : Bounds{word[i - 1].second,
true}),
561 {word[i].second,
false}}};
570 while (!CStates.empty() && word.
fetch(j)) {
574 std::vector<InternalState> CurrEpsilonConf;
575 CurrEpsilonConf.reserve(CStates.size());
576 for (
auto &istate : CStates) {
577 auto it = istate.s->next.find(0);
578 if (it != istate.s->next.end()) {
579 CurrEpsilonConf.push_back(istate);
582 while (!CurrEpsilonConf.empty()) {
583 std::vector<InternalState> PrevEpsilonConf =
584 std::move(CurrEpsilonConf);
585 CurrEpsilonConf.clear();
586 for (
const auto &econfig : PrevEpsilonConf) {
587 auto it = econfig.s->next.find(0);
588 if (it == econfig.s->next.end()) {
591 for (
const auto &edge : it->second) {
592 auto target = edge.target;
597 ClockVariables newClock = 0;
598 tmpZ.
alloc({word[j].second,
true},
599 ((j > 0) ? Bounds{-word[j - 1].second,
false}
601 tmpZ.
tighten(edge.guard, econfig.resetTime);
602 if (tmpZ.isSatisfiableCanonized()) {
603 auto tmpResetTime = econfig.resetTime;
604 for (ClockVariables x : edge.resetVars) {
605 tmpResetTime[x] = newClock;
607 tmpZ.update(tmpResetTime);
608 CurrEpsilonConf.emplace_back(target, tmpResetTime, tmpZ);
612 CStates.insert(CStates.end(), CurrEpsilonConf.begin(),
613 CurrEpsilonConf.end());
616 const Alphabet c = word[j].first;
617 const double t = word[j].second;
620 for (
const auto &config : CStates) {
622 auto it = s->
next.find(c);
623 if (it == s->
next.end()) {
626 for (
const auto &edge : it->second) {
627 auto target = edge.target;
628 if (!target || !target->isMatch) {
632 tmpZ.
alloc({word[j].second,
true},
633 ((j > 0) ? Bounds{-word[j - 1].second,
false}
635 tmpZ.
tighten(edge.guard, config.resetTime);
636 if (tmpZ.isSatisfiableCanonized()) {
645 LastStates = std::move(CStates);
646 for (
const auto &config : LastStates) {
648 auto it = s->
next.find(c);
649 if (it == s->
next.end()) {
652 for (
const auto &edge : it->second) {
653 auto target = edge.target;
658 tmpZ.
tighten(edge.guard, config.resetTime, t);
659 if (tmpZ.isSatisfiableCanonized()) {
660 auto tmpResetTime = config.resetTime;
661 for (ClockVariables x : edge.resetVars) {
664 tmpZ.update(tmpResetTime);
665 CStates.emplace_back(target, std::move(tmpResetTime),
672 if (!word.
fetch(j)) {
673 LastStates = std::move(CStates);
678 greatestN = std::max(beta[istate.s], greatestN);
701 template <
class InputContainer,
class OutputContainer>
708 std::unordered_map<const TAState *, std::shared_ptr<TAState>> ptrConv;
709 for (std::shared_ptr<TAState> s : A.
states) {
710 ptrConv[s.get()] = std::make_shared<TAState>(*s);
711 Ap.
states.push_back(ptrConv.at(s.get()));
717 for (std::shared_ptr<TAState> s : Ap.
states) {
718 if (s->next.find(
'$') != s->next.end()) {
720 s->next[
'$'].clear();
723 for (
auto &transitionsPair : s->next) {
724 for (
auto &transition : transitionsPair.second) {
725 transition.target = ptrConv.at(transition.target).get();
733 const int m = delta.
getM();
734 std::unordered_set<Alphabet> endChars;
735 delta.getEndChars(endChars);
743 [](std::shared_ptr<TAState> s) {
744 return s->next.find(0) == s->next.end();
749 std::vector<std::pair<std::pair<double, bool>, std::pair<double, bool>>>
751 std::vector<IntervalInternalState> CStates;
752 std::vector<IntervalInternalState> LastStates;
753 const Bounds zeroBounds = {0,
true};
760 for (
char c = 0; c < CHAR_MAX; c++) {
761 for (
const auto &edge: initState->next[c]) {
762 if (edge.target.lock()->isMatch) {
765 for (
const auto &constraint: edge.guard) {
768 if (zone.isSatisfiableCanonized()) {
769 init[c].push_back(std::move(zone));
780 while (word.
fetch(i + m - 1)) {
781 bool tooLarge =
false;
784 if (m == 1 && init[word[i].first].size() > 0) {
787 ans.
reserve(ans.
size() + init[word[i].first].size());
789 for (
auto zone: init[word[i].first]) {
791 zone.value.col(0).fill({word[i].second,
false});
792 if (zone.isSatisfiableCanonized()) {
798 for (
auto zone: init[word[i].first]) {
800 zone.value.col(0).fill({word[i].second,
false});
801 zone.value.row(0).fill({-word[i-1].second,
true});
802 if (zone.isSatisfiableCanonized()) {
810 if (m > 1 && word.
fetch(i + m - 1)) {
811 while (endChars.find(word[i + m - 1].first) == endChars.end()) {
812 if (!word.
fetch(i + m)) {
817 i += delta[word[i + m].first];
818 word.setFront(i - 1);
819 if (!word.fetch(i + m - 1)) {
832 std::vector<double> zeroResetTime(A.
clockSize(), 0);
837 {word[i].second,
false},
838 ((i <= 0) ? zeroBounds : Bounds{-word[i - 1].second,
true})};
848 while (!CStates.empty() && word.
fetch(j)) {
849 const Alphabet c = word[j].first;
850 const double t = word[j].second;
853 for (
const auto &config : CStates) {
855 auto it = s->
next.find(
'$');
856 if (it == s->
next.end()) {
859 for (
const auto &edge : it->second) {
860 auto target = edge.target;
861 if (!target || !target->isMatch) {
864 Bounds upperBeginConstraint = config.upperConstraint;
865 Bounds lowerBeginConstraint = config.lowerConstraint;
866 Bounds upperEndConstraint = {word[j].second,
true};
867 Bounds lowerEndConstraint =
868 ((j > 0) ? Bounds{-word[j - 1].second,
false} : zeroBounds);
871 Bounds upperDeltaConstraint =
872 upperEndConstraint + lowerBeginConstraint;
874 Bounds lowerDeltaConstraint =
875 std::min(lowerEndConstraint + upperBeginConstraint, zeroBounds);
877 auto tmpResetTime = config.resetTime;
879 for (
const auto &delta : edge.guard) {
880 if (tmpResetTime[delta.x]) {
882 case Constraint::Order::lt:
883 case Constraint::Order::le:
885 std::min(upperEndConstraint,
886 Bounds{delta.c + tmpResetTime[delta.x],
887 {delta.odr == Constraint::Order::le}});
889 upperDeltaConstraint =
890 std::min(upperDeltaConstraint,
891 upperEndConstraint + lowerBeginConstraint);
893 upperBeginConstraint =
894 std::min(upperBeginConstraint,
895 lowerDeltaConstraint + upperEndConstraint);
897 case Constraint::Order::gt:
898 case Constraint::Order::ge:
900 std::min(lowerEndConstraint,
901 Bounds{-delta.c - tmpResetTime[delta.x],
902 {delta.odr == Constraint::Order::ge}});
904 lowerDeltaConstraint =
905 std::min(lowerDeltaConstraint,
906 upperBeginConstraint + lowerEndConstraint);
908 lowerBeginConstraint =
909 std::min(lowerBeginConstraint,
910 lowerEndConstraint + upperDeltaConstraint);
915 case Constraint::Order::lt:
916 case Constraint::Order::le:
917 upperDeltaConstraint = std::min(
918 upperDeltaConstraint,
919 Bounds{delta.c, {delta.odr == Constraint::Order::le}});
922 std::min(upperEndConstraint,
923 upperDeltaConstraint + upperBeginConstraint);
925 lowerBeginConstraint =
926 std::min(lowerBeginConstraint,
927 lowerEndConstraint + upperDeltaConstraint);
929 case Constraint::Order::gt:
930 case Constraint::Order::ge:
931 lowerDeltaConstraint = std::min(
932 lowerDeltaConstraint,
933 Bounds{-delta.c, {delta.odr == Constraint::Order::ge}});
935 upperBeginConstraint =
936 std::min(upperBeginConstraint,
937 lowerDeltaConstraint + upperEndConstraint);
940 std::min(lowerEndConstraint,
941 lowerBeginConstraint + lowerDeltaConstraint);
948 lowerBeginConstraint) ||
951 lowerDeltaConstraint)) {
955 Zone ansZone = Zone::zero(3);
956 ansZone.value(0, 1) = std::move(lowerBeginConstraint);
957 ansZone.value(1, 0) = std::move(upperBeginConstraint);
958 ansZone.value(0, 2) = std::move(lowerEndConstraint);
959 ansZone.value(2, 0) = std::move(upperEndConstraint);
960 ansZone.value(1, 2) = std::move(lowerDeltaConstraint);
961 ansZone.value(2, 1) = std::move(upperDeltaConstraint);
968 LastStates = std::move(CStates);
969 for (
const auto &config : LastStates) {
971 auto it = s->
next.find(c);
972 if (it == s->
next.end()) {
975 for (
auto &edge : it->second) {
976 const auto target = edge.target;
981 Bounds upperBeginConstraint = config.upperConstraint;
982 Bounds lowerBeginConstraint = config.lowerConstraint;
983 bool transitable =
true;
985 for (
const auto &delta : edge.guard) {
986 if (config.resetTime[delta.x]) {
987 if (!delta.satisfy(t - config.resetTime[delta.x])) {
993 case Constraint::Order::lt:
994 case Constraint::Order::le:
995 lowerBeginConstraint =
996 std::min(lowerBeginConstraint,
998 {delta.odr == Constraint::Order::le}});
1000 case Constraint::Order::gt:
1001 case Constraint::Order::ge:
1002 upperBeginConstraint =
1003 std::min(upperBeginConstraint,
1005 {delta.odr == Constraint::Order::ge}});
1012 lowerBeginConstraint)) {
1016 auto tmpResetTime = config.resetTime;
1017 for (
auto i : edge.resetVars) {
1018 tmpResetTime[i] = t;
1021 CStates.emplace_back(edge.target, std::move(tmpResetTime),
1022 std::move(upperBeginConstraint),
1023 std::move(lowerBeginConstraint));
1028 if (!word.
fetch(j)) {
1030 for (
const auto &config : CStates) {
1032 auto it = s->
next.find(
'$');
1033 if (it == s->
next.end()) {
1036 for (
const auto &edge : it->second) {
1037 auto target = edge.target;
1038 if (!target || !target->isMatch) {
1041 Bounds upperBeginConstraint = config.upperConstraint;
1042 Bounds lowerBeginConstraint = config.lowerConstraint;
1043 Bounds upperEndConstraint = {
1044 std::numeric_limits<double>::infinity(),
true};
1045 Bounds lowerEndConstraint =
1046 ((j > 0) ? Bounds{-word[j - 1].second,
false} : zeroBounds);
1049 Bounds upperDeltaConstraint =
1050 upperEndConstraint + lowerBeginConstraint;
1052 Bounds lowerDeltaConstraint =
1053 std::min(lowerEndConstraint + upperBeginConstraint, zeroBounds);
1055 auto tmpResetTime = config.resetTime;
1057 for (
const auto &delta : edge.guard) {
1058 if (tmpResetTime[delta.x]) {
1059 switch (delta.odr) {
1060 case Constraint::Order::lt:
1061 case Constraint::Order::le:
1062 upperEndConstraint =
1063 std::min(upperEndConstraint,
1064 Bounds{delta.c + tmpResetTime[delta.x],
1065 {delta.odr == Constraint::Order::le}});
1067 upperDeltaConstraint =
1068 std::min(upperDeltaConstraint,
1069 upperEndConstraint + lowerBeginConstraint);
1071 upperBeginConstraint =
1072 std::min(upperBeginConstraint,
1073 lowerDeltaConstraint + upperEndConstraint);
1075 case Constraint::Order::gt:
1076 case Constraint::Order::ge:
1077 lowerEndConstraint =
1078 std::min(lowerEndConstraint,
1079 Bounds{-delta.c - tmpResetTime[delta.x],
1080 {delta.odr == Constraint::Order::ge}});
1082 lowerDeltaConstraint =
1083 std::min(lowerDeltaConstraint,
1084 upperBeginConstraint + lowerEndConstraint);
1086 lowerBeginConstraint =
1087 std::min(lowerBeginConstraint,
1088 lowerEndConstraint + upperDeltaConstraint);
1092 switch (delta.odr) {
1093 case Constraint::Order::lt:
1094 case Constraint::Order::le:
1095 upperDeltaConstraint = std::min(
1096 upperDeltaConstraint,
1097 Bounds{delta.c, {delta.odr == Constraint::Order::le}});
1099 upperEndConstraint =
1100 std::min(upperEndConstraint,
1101 upperDeltaConstraint + upperBeginConstraint);
1103 lowerBeginConstraint =
1104 std::min(lowerBeginConstraint,
1105 lowerEndConstraint + upperDeltaConstraint);
1107 case Constraint::Order::gt:
1108 case Constraint::Order::ge:
1109 lowerDeltaConstraint = std::min(
1110 lowerDeltaConstraint,
1111 Bounds{-delta.c, {delta.odr == Constraint::Order::ge}});
1113 upperBeginConstraint =
1114 std::min(upperBeginConstraint,
1115 lowerDeltaConstraint + upperEndConstraint);
1117 lowerEndConstraint =
1118 std::min(lowerEndConstraint,
1119 lowerBeginConstraint + lowerDeltaConstraint);
1126 lowerBeginConstraint) ||
1129 lowerDeltaConstraint)) {
1133 Zone ansZone = Zone::zero(3);
1134 ansZone.value(0, 1) = std::move(lowerBeginConstraint);
1135 ansZone.value(1, 0) = std::move(upperBeginConstraint);
1136 ansZone.value(0, 2) = std::move(lowerEndConstraint);
1137 ansZone.value(2, 0) = std::move(upperEndConstraint);
1138 ansZone.value(1, 2) = std::move(lowerDeltaConstraint);
1139 ansZone.value(2, 1) = std::move(upperDeltaConstraint);
1144 LastStates = std::move(CStates);
1149 greatestN = std::max(beta[ptrConv.at(istate.s).get()], greatestN);
1168 template <
class InputContainer,
class OutputContainer>
1176 std::unordered_map<const TAState *, std::shared_ptr<TAState>> ptrConv;
1177 for (std::shared_ptr<TAState> s : A.
states) {
1178 ptrConv[s.get()] = std::make_shared<TAState>(*s);
1179 Ap.
states.push_back(ptrConv[s.get()]);
1185 for (std::shared_ptr<TAState> s : Ap.
states) {
1186 if (s->next.find(
'$') != s->next.end()) {
1188 s->next[
'$'].clear();
1191 for (
auto &transitionsPair : s->next) {
1192 for (
auto &transition : transitionsPair.second) {
1193 transition.target = ptrConv[transition.target].get();
1201 const int m = delta.
getM();
1202 std::unordered_set<Alphabet> endChars;
1203 delta.getEndChars(endChars);
1211 [](std::shared_ptr<TAState> s) {
1212 return s->next.find(0) == s->next.end();
1217 std::vector<std::pair<std::pair<double, bool>, std::pair<double, bool>>>
1219 std::vector<IntervalInternalState> CStates;
1220 std::vector<IntervalInternalState> LastStates;
1221 const Bounds zeroBounds = {0,
true};
1228 for (
char c = 0; c < CHAR_MAX; c++) {
1229 for (
const auto &edge: initState->next[c]) {
1230 if (edge.target.lock()->isMatch) {
1233 for (
const auto &constraint: edge.guard) {
1236 if (zone.isSatisfiableCanonized()) {
1237 init[c].push_back(std::move(zone));
1248 while (word.
fetch(i + m - 1)) {
1249 bool tooLarge =
false;
1252 if (m == 1 && init[word[i].first].size() > 0) {
1255 ans.
reserve(ans.
size() + init[word[i].first].size());
1257 for (
auto zone: init[word[i].first]) {
1259 zone.value.col(0).fill({word[i].second,
false});
1260 if (zone.isSatisfiableCanonized()) {
1261 zone.toAns(ansZone);
1266 for (
auto zone: init[word[i].first]) {
1268 zone.value.col(0).fill({word[i].second,
false});
1269 zone.value.row(0).fill({-word[i-1].second,
true});
1270 if (zone.isSatisfiableCanonized()) {
1271 zone.toAns(ansZone);
1278 if (m > 1 && word.
fetch(i + m - 1)) {
1279 while (endChars.find(word[i + m - 1].first) == endChars.end()) {
1280 if (!word.
fetch(i + m)) {
1285 i += delta[word[i + m].first];
1286 word.setFront(i - 1);
1287 if (!word.fetch(i + m - 1)) {
1300 std::vector<double> zeroResetTime(A.
clockSize(), 0);
1301 if (word.
fetch(i)) {
1305 {word[i].second,
false},
1306 ((i <= 0) ? zeroBounds : Bounds{-word[i - 1].second,
true})};
1316 while (!CStates.empty() && word.
fetch(j)) {
1317 const Alphabet c = word[j].first;
1318 const double t = word[j].second;
1321 for (
const auto &config : CStates) {
1323 auto it = s->
next.find(
'$');
1324 if (it == s->
next.end()) {
1327 for (
const auto &edge : it->second) {
1328 auto target = edge.target;
1329 if (!target || !target->isMatch) {
1332 Bounds upperBeginConstraint = config.upperConstraint;
1333 Bounds lowerBeginConstraint = config.lowerConstraint;
1334 Bounds upperEndConstraint = {word[j].second,
true};
1335 Bounds lowerEndConstraint =
1336 ((j > 0) ? Bounds{-word[j - 1].second,
false} : zeroBounds);
1339 Bounds upperDeltaConstraint =
1340 upperEndConstraint + lowerBeginConstraint;
1342 Bounds lowerDeltaConstraint =
1343 std::min(lowerEndConstraint + upperBeginConstraint, zeroBounds);
1345 auto tmpResetTime = config.resetTime;
1347 for (
const auto &delta : edge.guard) {
1348 if (tmpResetTime[delta.x]) {
1349 switch (delta.odr) {
1350 case Constraint::Order::lt:
1351 case Constraint::Order::le:
1352 upperEndConstraint =
1353 std::min(upperEndConstraint,
1354 Bounds{delta.c + tmpResetTime[delta.x],
1355 {delta.odr == Constraint::Order::le}});
1357 upperDeltaConstraint =
1358 std::min(upperDeltaConstraint,
1359 upperEndConstraint + lowerBeginConstraint);
1361 upperBeginConstraint =
1362 std::min(upperBeginConstraint,
1363 lowerDeltaConstraint + upperEndConstraint);
1365 case Constraint::Order::gt:
1366 case Constraint::Order::ge:
1367 lowerEndConstraint =
1368 std::min(lowerEndConstraint,
1369 Bounds{-delta.c - tmpResetTime[delta.x],
1370 {delta.odr == Constraint::Order::ge}});
1372 lowerDeltaConstraint =
1373 std::min(lowerDeltaConstraint,
1374 upperBeginConstraint + lowerEndConstraint);
1376 lowerBeginConstraint =
1377 std::min(lowerBeginConstraint,
1378 lowerEndConstraint + upperDeltaConstraint);
1382 switch (delta.odr) {
1383 case Constraint::Order::lt:
1384 case Constraint::Order::le:
1385 upperDeltaConstraint = std::min(
1386 upperDeltaConstraint,
1387 Bounds{delta.c, {delta.odr == Constraint::Order::le}});
1389 upperEndConstraint =
1390 std::min(upperEndConstraint,
1391 upperDeltaConstraint + upperBeginConstraint);
1393 lowerBeginConstraint =
1394 std::min(lowerBeginConstraint,
1395 lowerEndConstraint + upperDeltaConstraint);
1397 case Constraint::Order::gt:
1398 case Constraint::Order::ge:
1399 lowerDeltaConstraint = std::min(
1400 lowerDeltaConstraint,
1401 Bounds{-delta.c, {delta.odr == Constraint::Order::ge}});
1403 upperBeginConstraint =
1404 std::min(upperBeginConstraint,
1405 lowerDeltaConstraint + upperEndConstraint);
1407 lowerEndConstraint =
1408 std::min(lowerEndConstraint,
1409 lowerBeginConstraint + lowerDeltaConstraint);
1416 lowerBeginConstraint) ||
1419 lowerDeltaConstraint)) {
1423 Zone ansZone = Zone::zero(3);
1424 ansZone.value(0, 1) = std::move(lowerBeginConstraint);
1425 ansZone.value(1, 0) = std::move(upperBeginConstraint);
1426 ansZone.value(0, 2) = std::move(lowerEndConstraint);
1427 ansZone.value(2, 0) = std::move(upperEndConstraint);
1428 ansZone.value(1, 2) = std::move(lowerDeltaConstraint);
1429 ansZone.value(2, 1) = std::move(upperDeltaConstraint);
1436 LastStates = std::move(CStates);
1437 for (
const auto &config : LastStates) {
1439 auto it = s->
next.find(c);
1440 if (it == s->
next.end()) {
1443 for (
auto &edge : it->second) {
1444 const auto target = edge.target;
1449 Bounds upperBeginConstraint = config.upperConstraint;
1450 Bounds lowerBeginConstraint = config.lowerConstraint;
1451 bool transitable =
true;
1453 for (
const auto &delta : edge.guard) {
1454 if (config.resetTime[delta.x]) {
1455 if (!delta.satisfy(t - config.resetTime[delta.x])) {
1456 transitable =
false;
1460 switch (delta.odr) {
1461 case Constraint::Order::lt:
1462 case Constraint::Order::le:
1463 lowerBeginConstraint =
1464 std::min(lowerBeginConstraint,
1466 {delta.odr == Constraint::Order::le}});
1468 case Constraint::Order::gt:
1469 case Constraint::Order::ge:
1470 upperBeginConstraint =
1471 std::min(upperBeginConstraint,
1473 {delta.odr == Constraint::Order::ge}});
1480 lowerBeginConstraint)) {
1484 auto tmpResetTime = config.resetTime;
1485 for (
auto i : edge.resetVars) {
1486 tmpResetTime[i] = t;
1489 if (edge.target->isMatch) {
1496 const Bounds upperEndConstraint = {t,
true};
1497 const Bounds lowerEndConstraint = {t,
true};
1500 const Bounds upperDeltaConstraint =
1501 upperEndConstraint + lowerBeginConstraint;
1503 const Bounds lowerDeltaConstraint = std::min(
1504 lowerEndConstraint + upperBeginConstraint, zeroBounds);
1507 lowerBeginConstraint) ||
1510 lowerDeltaConstraint)) {
1514 Zone ansZone = Zone::zero(3);
1515 ansZone.value(0, 1) = lowerBeginConstraint;
1516 ansZone.value(1, 0) = upperBeginConstraint;
1517 ansZone.value(0, 2) = std::move(lowerEndConstraint);
1518 ansZone.value(2, 0) = std::move(upperEndConstraint);
1519 ansZone.value(1, 2) = std::move(lowerDeltaConstraint);
1520 ansZone.value(2, 1) = std::move(upperDeltaConstraint);
1525 CStates.emplace_back(edge.target, std::move(tmpResetTime),
1526 std::move(upperBeginConstraint),
1527 std::move(lowerBeginConstraint));
1532 if (!word.
fetch(j)) {
1534 for (
const auto &config : CStates) {
1536 auto it = s->
next.find(
'$');
1537 if (it == s->
next.end()) {
1540 for (
const auto &edge : it->second) {
1541 auto target = edge.target;
1542 if (!target || !target->isMatch) {
1545 Bounds upperBeginConstraint = config.upperConstraint;
1546 Bounds lowerBeginConstraint = config.lowerConstraint;
1547 Bounds upperEndConstraint = {
1548 std::numeric_limits<double>::infinity(),
true};
1549 Bounds lowerEndConstraint =
1550 ((j > 0) ? Bounds{-word[j - 1].second,
false} : zeroBounds);
1553 Bounds upperDeltaConstraint =
1554 upperEndConstraint + lowerBeginConstraint;
1556 Bounds lowerDeltaConstraint =
1557 std::min(lowerEndConstraint + upperBeginConstraint, zeroBounds);
1559 auto tmpResetTime = config.resetTime;
1561 for (
const auto &delta : edge.guard) {
1562 if (tmpResetTime[delta.x]) {
1563 switch (delta.odr) {
1564 case Constraint::Order::lt:
1565 case Constraint::Order::le:
1566 upperEndConstraint =
1567 std::min(upperEndConstraint,
1568 Bounds{delta.c + tmpResetTime[delta.x],
1569 {delta.odr == Constraint::Order::le}});
1571 upperDeltaConstraint =
1572 std::min(upperDeltaConstraint,
1573 upperEndConstraint + lowerBeginConstraint);
1575 upperBeginConstraint =
1576 std::min(upperBeginConstraint,
1577 lowerDeltaConstraint + upperEndConstraint);
1579 case Constraint::Order::gt:
1580 case Constraint::Order::ge:
1581 lowerEndConstraint =
1582 std::min(lowerEndConstraint,
1583 Bounds{-delta.c - tmpResetTime[delta.x],
1584 {delta.odr == Constraint::Order::ge}});
1586 lowerDeltaConstraint =
1587 std::min(lowerDeltaConstraint,
1588 upperBeginConstraint + lowerEndConstraint);
1590 lowerBeginConstraint =
1591 std::min(lowerBeginConstraint,
1592 lowerEndConstraint + upperDeltaConstraint);
1596 switch (delta.odr) {
1597 case Constraint::Order::lt:
1598 case Constraint::Order::le:
1599 upperDeltaConstraint = std::min(
1600 upperDeltaConstraint,
1601 Bounds{delta.c, {delta.odr == Constraint::Order::le}});
1603 upperEndConstraint =
1604 std::min(upperEndConstraint,
1605 upperDeltaConstraint + upperBeginConstraint);
1607 lowerBeginConstraint =
1608 std::min(lowerBeginConstraint,
1609 lowerEndConstraint + upperDeltaConstraint);
1611 case Constraint::Order::gt:
1612 case Constraint::Order::ge:
1613 lowerDeltaConstraint = std::min(
1614 lowerDeltaConstraint,
1615 Bounds{-delta.c, {delta.odr == Constraint::Order::ge}});
1617 upperBeginConstraint =
1618 std::min(upperBeginConstraint,
1619 lowerDeltaConstraint + upperEndConstraint);
1621 lowerEndConstraint =
1622 std::min(lowerEndConstraint,
1623 lowerBeginConstraint + lowerDeltaConstraint);
1630 lowerBeginConstraint) ||
1633 lowerDeltaConstraint)) {
1637 Zone ansZone = Zone::zero(3);
1638 ansZone.value(0, 1) = std::move(lowerBeginConstraint);
1639 ansZone.value(1, 0) = std::move(upperBeginConstraint);
1640 ansZone.value(0, 2) = std::move(lowerEndConstraint);
1641 ansZone.value(2, 0) = std::move(upperEndConstraint);
1642 ansZone.value(1, 2) = std::move(lowerDeltaConstraint);
1643 ansZone.value(2, 1) = std::move(upperDeltaConstraint);
1648 LastStates = std::move(CStates);
1653 greatestN = std::max(beta[ptrConv[istate.s].get()], greatestN);
Container class for the output zones.
Definition: ans_vec.hh:17
void clear()
Remove all the contained zones.
Definition: ans_vec.hh:42
std::size_t size() const
Returns the number of the contained zones.
Definition: ans_vec.hh:32
void reserve(std::size_t n)
Reserve the space to contain zones.
Definition: ans_vec.hh:50
void push_back(typename Container::value_type in)
Append a zone to the container.
Definition: ans_vec.hh:38
The skip value function based on the KMP algorithm for string matching.
Definition: kmp_skip_value.hh:17
The skip value function based on Sunday's quick search.
Definition: sunday_skip_value.hh:17
int getM() const
Minimum length of the recognized language.
Definition: sunday_skip_value.hh:76
Container class for the input timed word.
Definition: word_container.hh:13
bool fetch(std::size_t n)
Fetch the timed words by n-th position.
Definition: word_container.hh:68
void setFront(std::size_t n)
Discard the elements before n-th position.
Definition: word_container.hh:61
void monaa(WordContainer< InputContainer > word, TimedAutomaton A, AnsContainer< OutputContainer > &ans)
Execute the timed FJS algorithm.
Definition: monaa.hh:151
void monaaNotNecessaryDollar(WordContainer< InputContainer > word, TimedAutomaton A, AnsContainer< OutputContainer > &ans)
Execute the timed FJS algorithm.
Definition: monaa.hh:1169
void updateConstraint(std::pair< double, bool > &upperConstraint, std::pair< double, bool > &lowerConstraint, const Constraint &delta, const double comparedValue)
update the assuming interval to satisfy the constraint
Definition: monaa.hh:108
bool isValidConstraint(const Bounds &upperConstraint, const Bounds &lowerConstraint)
Check if the given constraint is non empty.
Definition: monaa.hh:100
void monaaDollar(WordContainer< InputContainer > word, TimedAutomaton A, AnsContainer< OutputContainer > &ans)
Execute the timed FJS algorithm. This is the original timed FJS algorithm.
Definition: monaa.hh:702
std::vector< std::shared_ptr< State > > states
The states of this automaton.
Definition: common_types.hh:14
std::vector< std::shared_ptr< State > > initialStates
The initial states of this automaton.
Definition: common_types.hh:19
A constraint in a guard of transitions.
Definition: constraint.hh:16
Class for an interval.
Definition: interval.hh:15
A state of timed automata.
Definition: timed_automaton.hh:19
std::unordered_map< Alphabet, std::vector< TATransition > > next
An mapping of a character to the transitions.
Definition: timed_automaton.hh:32
A timed automaton.
Definition: timed_automaton.hh:54
size_t clockSize() const
Returns the number of clock variables used in the timed automaton.
Definition: timed_automaton.hh:95
std::vector< int > maxConstraints
The maximum constraints for each clock variables.
Definition: timed_automaton.hh:60
Implementation of a zone with DBM.
Definition: zone.hh:43