1#ifndef PROBFD_QUOTIENTS_QUOTIENT_SYSTEM_H
2#define PROBFD_QUOTIENTS_QUOTIENT_SYSTEM_H
4#include "probfd/utils/language.h"
8#include "downward/algorithms/segmented_vector.h"
13#include <unordered_map>
14#include <unordered_set>
19namespace probfd::quotients {
21template <
typename State,
typename Action>
24template <
typename State,
typename Action>
27template <
typename Action>
33 operator<=>(
const QuotientAction&,
const QuotientAction&) =
default;
36template <
typename Action>
37class QuotientInformation {
38 template <
typename,
typename>
39 friend class QuotientSystem;
41 template <
typename,
typename>
42 friend struct QuotientState;
46 std::vector<StateInfo> state_infos_;
47 std::vector<Action> aops_;
48 size_t total_num_outer_acts_ = 0;
49 TerminationInfo termination_info_;
52 size_t num_members()
const;
55 auto member_ids()
const;
57 void filter_actions(
const std::ranges::input_range
auto& filter);
60template <
typename State,
typename Action>
62 template <
typename,
typename>
63 friend class QuotientSystem;
65 using QuotientInformationType = QuotientInformation<Action>;
66 using MDPType = MDP<State, Action>;
69 std::variant<State, const QuotientInformationType*> single_or_quotient;
71 explicit QuotientState(MDPType& mdp, State single);
72 explicit QuotientState(
74 const QuotientInformationType* quotient);
77 template <std::invocable<param_type<State>> F>
78 value_t member_maximum(F&& f)
const
79 requires(std::is_convertible_v<
80 std::invoke_result_t<F, param_type<State>>,
87 size_t num_members()
const;
89 void get_collapsed_actions(std::vector<QuotientAction<Action>>& aops)
const;
92template <
typename State,
typename Action>
93class quotient_id_iterator;
95template <
typename State,
typename Action>
97 const quotient_id_iterator<State, Action>& left,
98 const quotient_id_iterator<State, Action>& right);
100template <
typename State,
typename Action>
101class quotient_id_iterator
102 :
public add_postfix_inc_dec<quotient_id_iterator<State, Action>> {
103 const QuotientSystem<State, Action>* qs_ =
nullptr;
107 using add_postfix_inc_dec<quotient_id_iterator>::operator++;
109 using difference_type = std::ptrdiff_t;
110 using value_type = StateID;
112 quotient_id_iterator() =
default;
113 quotient_id_iterator(
const QuotientSystem<State, Action>* qs, StateID x);
115 quotient_id_iterator& operator++();
116 StateID operator*()
const;
118 friend bool operator==
119 <>(
const quotient_id_iterator& left,
const quotient_id_iterator& right);
122template <
typename State,
typename Action>
124 :
public MDP<QuotientState<State, Action>, QuotientAction<Action>> {
125 friend class quotient_id_iterator<State, Action>;
127 using QuotientInformationType = QuotientInformation<Action>;
128 using QState = QuotientState<State, Action>;
129 using QAction = QuotientAction<Action>;
131 using MDPType = MDP<State, Action>;
133 std::unordered_map<StateID::size_type, QuotientInformationType> quotients_;
134 segmented_vector::SegmentedVector<StateID::size_type> quotient_ids_;
139 static constexpr StateID::size_type MASK = (StateID::size_type(-1) >> 1);
140 static constexpr StateID::size_type FLAG = ~MASK;
143 using const_iterator = quotient_id_iterator<State, Action>;
144 static_assert(std::input_iterator<const_iterator>);
146 explicit QuotientSystem(MDPType& mdp);
150 QState get_state(StateID state_id)
override;
152 void generate_applicable_actions(
154 std::vector<QAction>& aops)
override;
156 void generate_action_transitions(
159 Distribution<StateID>& result)
override;
161 void generate_all_transitions(
163 std::vector<QAction>& aops,
164 std::vector<Distribution<StateID>>& successors)
override;
166 void generate_all_transitions(
168 std::vector<Transition<QAction>>& transitions)
override;
172 value_t get_action_cost(QAction qa)
override;
174 MDPType& get_parent_mdp();
176 const_iterator begin()
const;
177 const_iterator end()
const;
182 StateID translate_state_id(StateID sid)
const;
184 template <
typename Range>
185 void build_quotient(Range& states);
187 template <
typename SubMDP>
189 build_quotient(SubMDP submdp, std::ranges::range_reference_t<SubMDP> entry);
191 template <
typename SubMDP>
192 void build_new_quotient(
194 std::ranges::range_reference_t<SubMDP> entry);
197 auto partition_actions(
198 std::ranges::input_range
auto&& aops,
199 const std::ranges::input_range
auto& filter)
const;
201 QuotientInformationType* get_quotient_info(StateID state_id);
202 const QuotientInformationType* get_quotient_info(StateID state_id)
const;
205 StateID::size_type get_masked_state_id(StateID sid)
const;
207 void set_masked_state_id(StateID sid,
const StateID::size_type& qsid);
214template <
typename Action>
215struct is_cheap_to_copy<quotients::
QuotientAction<Action>> : std::true_type {};
219#define GUARD_INCLUDE_PROBFD_QUOTIENTS_QUOTIENT_SYSTEM_H
220#include "probfd/quotients/quotient_system_impl.h"
221#undef GUARD_INCLUDE_PROBFD_QUOTIENTS_QUOTIENT_SYSTEM_H
QuotientAction
Represents an action in the probabilistic bisimulation quotient.
Definition types.h:12
QuotientState
Represents a state in the probabilistic bisimulation quotient.
Definition types.h:9
The top-level namespace of probabilistic Fast Downward.
Definition command_line.h:8
double value_t
Typedef for the state value type.
Definition aliases.h:7
typename std::conditional_t< is_cheap_to_copy_v< T >, T, const T & > param_type
Alias template defining the best way to pass a parameter of a given type.
Definition type_traits.h:25