AI 24/25 Project Software
Documentation for the AI 24/25 course programming project software
Loading...
Searching...
No Matches
quotient_system.h
1#ifndef PROBFD_QUOTIENTS_QUOTIENT_SYSTEM_H
2#define PROBFD_QUOTIENTS_QUOTIENT_SYSTEM_H
3
4#include "probfd/utils/language.h"
5
6#include "probfd/mdp.h"
7
8#include "downward/algorithms/segmented_vector.h"
9
10#include <compare>
11#include <ranges>
12#include <type_traits>
13#include <unordered_map>
14#include <unordered_set>
15#include <utility>
16#include <variant>
17#include <vector>
18
19namespace probfd::quotients {
20
21template <typename State, typename Action>
22class QuotientSystem;
23
24template <typename State, typename Action>
25struct QuotientState;
26
27template <typename Action>
28struct QuotientAction {
29 StateID state_id;
30 Action action;
31
32 friend auto
33 operator<=>(const QuotientAction&, const QuotientAction&) = default;
34};
35
36template <typename Action>
37class QuotientInformation {
38 template <typename, typename>
39 friend class QuotientSystem;
40
41 template <typename, typename>
42 friend struct QuotientState;
43
44 struct StateInfo;
45
46 std::vector<StateInfo> state_infos_;
47 std::vector<Action> aops_; // First outer, then inner actions
48 size_t total_num_outer_acts_ = 0;
49 TerminationInfo termination_info_;
50
51 [[nodiscard]]
52 size_t num_members() const;
53
54 auto member_ids();
55 auto member_ids() const;
56
57 void filter_actions(const std::ranges::input_range auto& filter);
58};
59
60template <typename State, typename Action>
61struct QuotientState {
62 template <typename, typename>
63 friend class QuotientSystem;
64
65 using QuotientInformationType = QuotientInformation<Action>;
66 using MDPType = MDP<State, Action>;
67
68 MDPType& mdp;
69 std::variant<State, const QuotientInformationType*> single_or_quotient;
70
71 explicit QuotientState(MDPType& mdp, State single);
72 explicit QuotientState(
73 MDPType& mdp,
74 const QuotientInformationType* quotient);
75
76public:
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>>,
81 value_t>);
82
83 void
84 for_each_member_state(std::invocable<param_type<State>> auto&& f) const;
85
86 [[nodiscard]]
87 size_t num_members() const;
88
89 void get_collapsed_actions(std::vector<QuotientAction<Action>>& aops) const;
90};
91
92template <typename State, typename Action>
93class quotient_id_iterator;
94
95template <typename State, typename Action>
96bool operator==(
97 const quotient_id_iterator<State, Action>& left,
98 const quotient_id_iterator<State, Action>& right);
99
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;
104 StateID i_;
105
106public:
107 using add_postfix_inc_dec<quotient_id_iterator>::operator++;
108
109 using difference_type = std::ptrdiff_t;
110 using value_type = StateID;
111
112 quotient_id_iterator() = default;
113 quotient_id_iterator(const QuotientSystem<State, Action>* qs, StateID x);
114
115 quotient_id_iterator& operator++();
116 StateID operator*() const;
117
118 friend bool operator==
119 <>(const quotient_id_iterator& left, const quotient_id_iterator& right);
120};
121
122template <typename State, typename Action>
123class QuotientSystem
124 : public MDP<QuotientState<State, Action>, QuotientAction<Action>> {
125 friend class quotient_id_iterator<State, Action>;
126
127 using QuotientInformationType = QuotientInformation<Action>;
128 using QState = QuotientState<State, Action>;
129 using QAction = QuotientAction<Action>;
130
131 using MDPType = MDP<State, Action>;
132
133 std::unordered_map<StateID::size_type, QuotientInformationType> quotients_;
134 segmented_vector::SegmentedVector<StateID::size_type> quotient_ids_;
135 MDPType& mdp_;
136
137 // MASK: bitmask used to obtain the quotient state id, if it exists
138 // FLAG: whether a quotient state id exists
139 static constexpr StateID::size_type MASK = (StateID::size_type(-1) >> 1);
140 static constexpr StateID::size_type FLAG = ~MASK;
141
142public:
143 using const_iterator = quotient_id_iterator<State, Action>;
144 static_assert(std::input_iterator<const_iterator>);
145
146 explicit QuotientSystem(MDPType& mdp);
147
148 StateID get_state_id(param_type<QState> state) override;
149
150 QState get_state(StateID state_id) override;
151
152 void generate_applicable_actions(
153 param_type<QState> state,
154 std::vector<QAction>& aops) override;
155
156 void generate_action_transitions(
158 QAction a,
159 Distribution<StateID>& result) override;
160
161 void generate_all_transitions(
162 param_type<QState> state,
163 std::vector<QAction>& aops,
164 std::vector<Distribution<StateID>>& successors) override;
165
166 void generate_all_transitions(
167 param_type<QState> state,
168 std::vector<Transition<QAction>>& transitions) override;
169
170 TerminationInfo get_termination_info(param_type<QState> s) override;
171
172 value_t get_action_cost(QAction qa) override;
173
174 MDPType& get_parent_mdp();
175
176 const_iterator begin() const;
177 const_iterator end() const;
178
179 QState translate_state(param_type<State> s) const;
180
181 [[nodiscard]]
182 StateID translate_state_id(StateID sid) const;
183
184 template <typename Range>
185 void build_quotient(Range& states);
186
187 template <typename SubMDP>
188 void
189 build_quotient(SubMDP submdp, std::ranges::range_reference_t<SubMDP> entry);
190
191 template <typename SubMDP>
192 void build_new_quotient(
193 SubMDP submdp,
194 std::ranges::range_reference_t<SubMDP> entry);
195
196private:
197 auto partition_actions(
198 std::ranges::input_range auto&& aops,
199 const std::ranges::input_range auto& filter) const;
200
201 QuotientInformationType* get_quotient_info(StateID state_id);
202 const QuotientInformationType* get_quotient_info(StateID state_id) const;
203
204 [[nodiscard]]
205 StateID::size_type get_masked_state_id(StateID sid) const;
206
207 void set_masked_state_id(StateID sid, const StateID::size_type& qsid);
208};
209
210} // namespace probfd::quotients
211
212namespace probfd {
213
214template <typename Action>
215struct is_cheap_to_copy<quotients::QuotientAction<Action>> : std::true_type {};
216
217} // namespace probfd
218
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
222
223#endif // 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