}
XBT_DEBUG("Replaced stack by %s", get_record_trace().to_string().c_str());
+ // TODO: See if we can simply take a prefix of what
+ // currently exists instead of performing a recomputation.
+ // There seems to be a subtlety here that at the moment
+ // I can't figure out
if (reduction_mode_ == ReductionMode::sdpor) {
- if (stack_.empty()) {
- execution_seq_ = sdpor::Execution();
- } else {
- execution_seq_ = execution_seq_.get_prefix_up_to(stack_.size() - 1);
+ execution_seq_ = sdpor::Execution();
+ for (const auto& state : stack_) {
+ execution_seq_.push_transition(state->get_transition_out().get());
}
- XBT_DEBUG("Additionally replaced corresponding SDPOR execution stack");
}
+ XBT_DEBUG("Additionally replaced corresponding SDPOR execution stack");
}
void DFSExplorer::log_state() // override
Execution E_prime_v = get_prefix_up_to(e);
std::vector<sdpor::Execution::EventHandle> v;
+ // Note `e + 1` here: `notdep(e, E)` is defined as the
+ // set of events that *occur-after* but don't *happen-after* `e`
for (auto e_prime = e + 1; e_prime <= next_E_p; ++e_prime) {
// Any event `e*` which occurs after `e` but which does not
// happen after `e` is a member of `v`. In addition to marking
size_t size() const { return this->contents_.size(); }
bool empty() const { return this->contents_.empty(); }
+ auto begin() const { return this->contents_.begin(); }
+ auto end() const { return this->contents_.end(); }
std::optional<aid_t> get_first_ssdpor_initial_from(EventHandle e, std::unordered_set<aid_t> disqualified) const;
std::unordered_set<aid_t> get_ssdpor_initials_from(EventHandle e, std::unordered_set<aid_t> disqualified) const;
Execution execution;
REQUIRE(execution.empty());
REQUIRE(execution.size() == 0);
+ REQUIRE_FALSE(execution.get_latest_event_handle().has_value());
}
TEST_CASE("simgrid::mc::odpor::Execution: Testing Happens-Before")
}
}
-TEST_CASE("simgrid::mc::odpor::Execution: Testing Racing Events Initials")
+TEST_CASE("simgrid::mc::odpor::Execution: Testing Racing Events and Initials")
{
SECTION("Example 1")
{
// All events are dependent with event 3, but event 0 "happens-before" event 2
REQUIRE(execution.get_racing_events_of(3) == std::unordered_set<Execution::EventHandle>{1, 2});
+
+ SECTION("Check initials with respect to event 1")
+ {
+ // First, note that v := notdep(1, execution).p == {e2}.{e3} == {e2, e3}
+ // Since e2 -->_E e3, actor 3 is not an initial for E' := pre(1, execution)
+ // with respect to `v`. e2, however, has nothing happening before it in dom_E(v),
+ // so it is an initial of E' wrt. `v`
+ const auto initial_wrt_event1 = execution.get_first_ssdpor_initial_from(1, std::unordered_set<aid_t>{});
+ REQUIRE(initial_wrt_event1.has_value());
+ REQUIRE(initial_wrt_event1.value() == static_cast<aid_t>(1));
+ }
+
+ SECTION("Check initials with respect to event 2")
+ {
+ // First, note that v := notdep(1, execution).p == {}.{e3} == {e3}
+ // e3 has nothing happening before it in dom_E(v), so it is an initial
+ // of E' wrt. `v`
+ const auto initial_wrt_event2 = execution.get_first_ssdpor_initial_from(2, std::unordered_set<aid_t>{});
+ REQUIRE(initial_wrt_event2.has_value());
+ REQUIRE(initial_wrt_event2.value() == static_cast<aid_t>(3));
+ }
}
}
\ No newline at end of file