#include "src/mc/explo/udpor/EventSet.hpp"
#include "src/mc/explo/udpor/Configuration.hpp"
+#include "src/mc/explo/udpor/History.hpp"
#include <iterator>
return subtracting(other).empty();
}
+bool EventSet::is_valid_configuration() const
+{
+ /// @invariant: A collection of events `E` is a configuration
+ /// if and only if following while following the history of
+ /// each event `e` of `E`you remain in `E`. In other words, you
+ /// only see events from set `E`
+ ///
+ /// The proof is based on the definition of a configuration
+ /// which requires that all
+ const History history(*this);
+ return std::all_of(history.begin(), history.end(), [=](UnfoldingEvent* e) { return this->contains(e); });
+}
+
} // namespace simgrid::mc::udpor
\ No newline at end of file
bool empty() const;
bool contains(UnfoldingEvent*) const;
bool is_subset_of(const EventSet&) const;
+ bool is_valid_configuration() const;
bool operator==(const EventSet& other) const { return this->events_ == other.events_; }
bool operator!=(const EventSet& other) const { return this->events_ != other.events_; }
namespace simgrid::mc::udpor {
+History::Iterator::Iterator(const EventSet& initial_events, optional_configuration config)
+ : frontier(initial_events), configuration(config)
+{
+}
+
History::Iterator& History::Iterator::operator++()
{
if (not frontier.empty()) {
UnfoldingEvent* e = *frontier.begin();
frontier.remove(e);
- // If we've seen this event before, skip it
-
// If there is a configuration and if the
// event is in it, skip it: the event and
// all of its immediate causes do not need to
// Perform the expansion with all viable expansions
EventSet candidates = e->get_immediate_causes();
- candidates.subtract(current_history);
+ candidates.subtract(current_history);
frontier.form_union(std::move(candidates));
}
return *this;
EventSet History::get_event_diff_with(const Configuration& config) const
{
- // auto wrapped_config = std::optional<std::reference_wrapper<Configuration>>(config);
- // auto first = Iterator(events_, wrapped_config);
- // const auto last = this->end();
+ auto wrapped_config = std::optional<std::reference_wrapper<const Configuration>>{config};
+ auto first = Iterator(events_, std::move(wrapped_config));
+ const auto last = this->end();
- // for (; first != last; ++first)
- // ;
+ for (; first != last; ++first)
+ ;
- // return first.current_history;
- // TODO: Implement this
- return EventSet();
+ return first.current_history;
}
} // namespace simgrid::mc::udpor
* @brief An iterator which traverses the history of a set of events
*/
struct Iterator {
- private:
- EventSet frontier;
- EventSet current_history = EventSet();
- std::optional<std::reference_wrapper<Configuration>> configuration;
-
- friend History;
-
public:
- Iterator(const EventSet& initial_events, std::optional<std::reference_wrapper<Configuration>> config = std::nullopt)
- : frontier(initial_events), configuration(config)
- {
- }
-
Iterator& operator++();
auto operator->() { return frontier.begin().operator->(); }
auto operator*() const { return *frontier.begin(); }
bool operator==(const Iterator& other) { return this->frontier == other.frontier; }
bool operator!=(const Iterator& other) { return not(this->operator==(other)); }
- using iterator_category = std::forward_iterator_tag;
- using difference_type = int; // # of steps between
- using value_type = UnfoldingEvent*;
- using pointer = value_type*;
- using reference = value_type&;
+ using iterator_category = std::forward_iterator_tag;
+ using difference_type = int; // # of steps between
+ using value_type = UnfoldingEvent*;
+ using pointer = value_type*;
+ using reference = value_type&;
+ using optional_configuration = std::optional<std::reference_wrapper<const Configuration>>;
+
+ Iterator(const EventSet& initial_events, optional_configuration config = std::nullopt);
+
+ private:
+ EventSet frontier;
+ EventSet current_history = EventSet();
+ optional_configuration configuration;
+ friend History;
};
};
REQUIRE_FALSE(history_e3e5.contains(&e7));
}
- SECTION("Nodes with the different ancestors")
+ SECTION("Nodes with different ancestors")
{
History history_e4e7(EventSet({&e4, &e7}));
REQUIRE(history_e4e7.get_all_events() == EventSet({&e1, &e2, &e4, &e6, &e7}));
REQUIRE_FALSE(history_e2356.contains(&e7));
}
- SECTION("History of the entire graph is the entire graph")
+ SECTION("History of the entire graph yields the entire graph")
{
- History history_e2356(EventSet({&e1, &e2, &e3, &e4, &e5, &e6, &e7}));
- REQUIRE(history_e2356.get_all_events() == EventSet({&e1, &e2, &e3, &e4, &e5, &e6, &e7}));
- REQUIRE(history_e2356.contains(&e1));
- REQUIRE(history_e2356.contains(&e2));
- REQUIRE(history_e2356.contains(&e3));
- REQUIRE(history_e2356.contains(&e4));
- REQUIRE(history_e2356.contains(&e5));
- REQUIRE(history_e2356.contains(&e6));
- REQUIRE(history_e2356.contains(&e7));
+ History history(EventSet({&e1, &e2, &e3, &e4, &e5, &e6, &e7}));
+ REQUIRE(history.get_all_events() == EventSet({&e1, &e2, &e3, &e4, &e5, &e6, &e7}));
+ REQUIRE(history.contains(&e1));
+ REQUIRE(history.contains(&e2));
+ REQUIRE(history.contains(&e3));
+ REQUIRE(history.contains(&e4));
+ REQUIRE(history.contains(&e5));
+ REQUIRE(history.contains(&e6));
+ REQUIRE(history.contains(&e7));
}
}
+
+ SECTION("History with masking configuration")
+ {
+ Configuration configuration;
+ }
}