TCPSPSuite
traits.hpp
1 #ifndef TRAITS_H
2 #define TRAITS_H
3 
4 #include "../datastructures/maybe.hpp" // for Maybe
5 #include "../util/util.hpp" // for get_array_size, clog2
6 
7 #include <array> // for array
8 #include <deque> // for deque
9 #include <ostream> // for basic_ostream
10 #include <set> // for set
11 #include <stdexcept> // for runtime_error
12 #include <string> // for string
13 #include <unordered_map> // for unordered_map
14 #include <utility> // for pair
15 #include <vector> // for vector, allocator
16 class Instance; // lines 15-15
17 class Transformer; // lines 16-16
18 
19 class TraitViolatedError : public std::runtime_error {
20 public:
21  explicit TraitViolatedError(const std::string & what);
22  explicit TraitViolatedError(const char * what);
23 };
24 
25 class TraitUnfulfilledError : public std::runtime_error {
26 public:
27  explicit TraitUnfulfilledError(const std::string & what);
28  explicit TraitUnfulfilledError(const char * what);
29 };
30 
31 // TODO negative implications! E.g.: "NOT NO_DRAIN" => "NOT COMMON_DURATION"
32 
33 class Traits {
34 public:
35  // TODO use std::bitset
36 
37  /*
38  * WARNING! If you modify something here, remember to:
39  * - update ALL_TRAIT_FLAGS
40  * - update the constants in traits.cpp
41  * - update *all* the traits_profile s in the transformers
42  * - update the checks in the TraitsBuilder
43  */
44 
45  static const unsigned long NO_LAGS;
46  static const unsigned long LAGS_ONLY_SUCCESSORS;
47  static const unsigned long LAGS_ONLY_GREATER_DURATION;
48  static const unsigned long LAGS_ONLY_POSITIVE;
49  static const unsigned long LAGS_DAG;
50 
51  static const unsigned long COMMON_RELEASE;
52  static const unsigned long COMMON_DEADLINE;
53  static const unsigned long COMMON_DURATION;
54 
55  static const unsigned long CONSISTENT_WINDOWS;
56 
57  static const unsigned long DUMMY_START_END;
58 
59  static const unsigned long NO_DRAIN;
60 
61  static const unsigned long NO_WINDOW_EXTENSION;
62  static const unsigned long WINDOW_EXTENSION_JOBS_UNLIMITED;
63 
64  static const unsigned long FLAT_AVAILABILITY;
65  static const unsigned long ZERO_AVAILABILITY;
66 
67  static const unsigned long FLAT_OVERSHOOT;
68 
69  // End of flags
70 
71  static const char * const FLAG_NAMES[];
72 
73  Traits(unsigned long flags, unsigned int max_resources,
74  std::set<double> allowed_overshoot_exponents,
75  std::set<double> allowed_investment_exponents);
76  Traits();
77 
78  bool fulfills(const Traits & requirements) const;
79  bool has_flag(unsigned long flag) const;
80 
81  void add_flag(unsigned long flag);
82  void remove_flag(unsigned long flag);
83 
84  // deepcopy
85  Traits clone() const;
86 
87  // String output
88  template <class _CharT, class _Traits>
89  friend std::basic_ostream<_CharT, _Traits> &
90  operator<<(std::basic_ostream<_CharT, _Traits> & stream,
91  const Traits & traits);
92 
93 private:
94  unsigned long flags;
95  unsigned int max_resources;
96 
97  std::set<double> allowed_overshoot_exponents;
98  std::set<double> allowed_investment_exponents;
99 
100  static const std::vector<std::pair<unsigned long, unsigned long>>
101  implications;
102 };
103 
104 // Helper to define profiles
105 const unsigned long ALL_TRAIT_FLAGS[] = {
106  Traits::NO_LAGS,
107  Traits::LAGS_ONLY_SUCCESSORS,
108  Traits::LAGS_ONLY_GREATER_DURATION,
109  Traits::LAGS_ONLY_POSITIVE,
110  Traits::LAGS_DAG,
111  Traits::COMMON_RELEASE,
112  Traits::COMMON_DEADLINE,
113  Traits::COMMON_DURATION,
114  Traits::DUMMY_START_END,
115  Traits::NO_DRAIN,
116  Traits::CONSISTENT_WINDOWS,
117  Traits::NO_WINDOW_EXTENSION,
118  Traits::WINDOW_EXTENSION_JOBS_UNLIMITED,
119  Traits::FLAT_AVAILABILITY,
120  Traits::ZERO_AVAILABILITY,
121  Traits::FLAT_OVERSHOOT};
122 
123 class TraitsBuilder {
124 public:
125  explicit TraitsBuilder(const Instance & instance);
126  void run();
127  Traits get_traits();
128 
129 private:
130  void check_no_lags();
131  void check_lag_durations();
132  void check_lag_dag();
133  void check_no_drain();
134  void check_deadline_release();
135  void check_consistent_windows();
136  void check_dummy_start_end();
137  void check_window_extension();
138  void check_availabilities();
139  void check_overshoot();
140 
141  unsigned long flags;
142  const Instance & instance;
143 };
144 
145 class TraitsRouter {
146 public:
147  static const unsigned short WANT_MAYBE;
148  static const unsigned short WANT_YES;
149  static const unsigned short WANT_NO;
150 
151  using trait_profile = std::array<bool, get_array_size(ALL_TRAIT_FLAGS)>;
152  using transform_profile =
153  std::array<unsigned short, get_array_size(ALL_TRAIT_FLAGS)>;
154 
155  explicit TraitsRouter(const std::set<Transformer *> & transformers);
156  Maybe<std::vector<Transformer *>> get_path(const Traits & from,
157  const Traits & to);
158 
159 private:
160  const std::set<Transformer *> & transformers;
161 
162  std::vector<std::pair<transform_profile, Transformer *>> in_edges;
163  std::unordered_map<trait_profile, std::pair<Transformer *, trait_profile>>
164  tree;
165  std::deque<trait_profile> queue;
166  trait_profile final_profile;
167  bool found;
168 
169  void build_in_edges();
170  void do_bfs(const Traits & from, const Traits & to);
171  bool match(const trait_profile & traits_p,
172  const transform_profile & trans_p) const;
173  bool fulfills(const trait_profile & profile,
174  const trait_profile & pattern) const;
175  std::vector<Transformer *> find_matching(const trait_profile & profile) const;
176  trait_profile transform_flags(const trait_profile & in_profile,
177  const transform_profile & transform) const;
178  trait_profile traits_to_profile(const Traits & traits) const;
179 };
180 
181 /*
182  * Debug output methods
183  */
184 
185 // Maps e.g. Traits::LAGS_ONLY_GREATER_DURATION to its index, i.e. 2
186 // this should be evaluated at compile time by any sane compiler
187 constexpr unsigned int
188 flag_to_index(unsigned long flag)
189 {
190  return (unsigned int)clog2(flag);
191 }
192 
193 template <class _CharT, class _Traits>
194 std::basic_ostream<_CharT, _Traits> &
195 operator<<(std::basic_ostream<_CharT, _Traits> & stream, const Traits & traits)
196 {
197  stream << "Traits[ ";
198 
199  bool first = true;
200  for (auto flag : ALL_TRAIT_FLAGS) {
201  if (traits.has_flag(flag)) {
202  if (!first) {
203  stream << " | ";
204  }
205  stream << Traits::FLAG_NAMES[flag_to_index(flag)];
206  first = false;
207  }
208  }
209 
210  stream << " / " << traits.max_resources << " / {";
211 
212  first = true;
213  for (auto exponent : traits.allowed_overshoot_exponents) {
214  if (!first) {
215  stream << ",";
216  }
217  stream << exponent;
218  first = false;
219  }
220 
221  stream << "} / {";
222 
223  first = true;
224  for (auto exponent : traits.allowed_investment_exponents) {
225  if (!first) {
226  stream << ",";
227  }
228  stream << exponent;
229  first = false;
230  }
231 
232  stream << "} ]";
233 
234  return stream;
235 }
236 
237 #endif
Instance
a TCPSP instance
Definition: instance.hpp:24