AI 24/25 Project Software
Documentation for the AI 24/25 course programming project software
Loading...
Searching...
No Matches
factored_transition_system.h
1#ifndef MERGE_AND_SHRINK_FACTORED_TRANSITION_SYSTEM_H
2#define MERGE_AND_SHRINK_FACTORED_TRANSITION_SYSTEM_H
3
4#include "downward/merge_and_shrink/types.h"
5
6#include "downward/utils/logging.h"
7
8#include <memory>
9#include <vector>
10
11namespace utils {
12class LogProxy;
13}
14
15namespace merge_and_shrink {
16class Distances;
17class FactoredTransitionSystem;
18class MergeAndShrinkRepresentation;
19class Labels;
20class TransitionSystem;
21
22class FTSConstIterator {
23 /*
24 This class allows users to easily iterate over the active indices of
25 a factored transition system.
26 */
27 const FactoredTransitionSystem& fts;
28 // current_index is the actual iterator
29 int current_index;
30
31 void next_valid_index();
32
33public:
34 FTSConstIterator(const FactoredTransitionSystem& fts, bool end);
35 void operator++();
36
37 int operator*() const { return current_index; }
38
39 bool operator==(const FTSConstIterator& rhs) const
40 {
41 return current_index == rhs.current_index;
42 }
43
44 bool operator!=(const FTSConstIterator& rhs) const
45 {
46 return current_index != rhs.current_index;
47 }
48};
49
50struct Factor {
51 std::unique_ptr<TransitionSystem> transition_system;
52 std::unique_ptr<MergeAndShrinkRepresentation> mas_representation;
53 std::unique_ptr<Distances> distances;
54
55 Factor(
56 std::unique_ptr<TransitionSystem> transition_system,
57 std::unique_ptr<MergeAndShrinkRepresentation> mas_representation,
58 std::unique_ptr<Distances> distances);
59
60 ~Factor();
61
62 Factor(Factor&&);
63 Factor& operator=(Factor&&);
64};
65
66/*
67 NOTE: A "factor" of this factored transition system is identfied by its
68 index as used in the vectors in this class. Since transformations like
69 merging also add and remove factors, not all indices are necessarily
70 associated with factors. This is what the class uses the notion of "active"
71 factors for: an index is active iff there exists a transition system, a
72 merge-and-shrink representation and an distances object in the corresponding
73 vectors.
74
75 TODO: The user of this class has to care more about the notion of active
76 factors as we would like it to be. We should change this and clean up the
77 interface that this class shows to the outside world.
78*/
79class FactoredTransitionSystem {
80 std::unique_ptr<Labels> labels;
81 // Entries with nullptr have been merged.
82 std::vector<std::unique_ptr<TransitionSystem>> transition_systems;
83 std::vector<std::unique_ptr<MergeAndShrinkRepresentation>>
84 mas_representations;
85 std::vector<std::unique_ptr<Distances>> distances;
86 const bool compute_init_distances;
87 const bool compute_goal_distances;
88 int num_active_entries;
89
90 /*
91 Assert that the factor at the given index is in a consistent state, i.e.
92 that there is a transition system, a distances object, and an MSR.
93 */
94 void assert_index_valid(int index) const;
95
96 /*
97 We maintain the invariant that for all factors, distances are always
98 computed and all transitions are grouped according to locally equivalent
99 labels.
100 */
101 bool is_component_valid(int index) const;
102
103 void assert_all_components_valid() const;
104
105public:
106 FactoredTransitionSystem(
107 std::unique_ptr<Labels> labels,
108 std::vector<std::unique_ptr<TransitionSystem>>&& transition_systems,
109 std::vector<std::unique_ptr<MergeAndShrinkRepresentation>>&&
110 mas_representations,
111 std::vector<std::unique_ptr<Distances>>&& distances,
112 bool compute_init_distances,
113 bool compute_goal_distances,
114 utils::LogProxy& log);
115 FactoredTransitionSystem(FactoredTransitionSystem&& other);
116 ~FactoredTransitionSystem();
117
118 // No copying or assignment.
119 FactoredTransitionSystem(const FactoredTransitionSystem&) = delete;
120 FactoredTransitionSystem&
121 operator=(const FactoredTransitionSystem&) = delete;
122
123 // Merge-and-shrink transformations.
124 /*
125 Apply the given label mapping to the factored transition system by
126 updating all transitions of all transition systems. Only for the factor
127 at combinable_index, the local equivalence relation over labels must be
128 recomputed; for all factors, all labels that are combined by the label
129 mapping have been locally equivalent already before.
130 */
131 void apply_label_mapping(
132 const std::vector<std::pair<int, std::vector<int>>>& label_mapping,
133 int combinable_index);
134
135 /*
136 Apply the given state equivalence relation to the transition system at
137 index if it would reduce its size. If the transition system was shrunk,
138 update the other components of the factor (distances, MSR) and return
139 true, otherwise return false.
140
141 Note that this method is also suitable to be used for a prune
142 transformation. All states not mentioned in the state equivalence
143 relation are pruned.
144 */
145 bool apply_abstraction(
146 int index,
147 const StateEquivalenceRelation& state_equivalence_relation,
148 utils::LogProxy& log);
149
150 /*
151 Merge the two factors at index1 and index2.
152 */
153 int merge(int index1, int index2, utils::LogProxy& log);
154
155 /*
156 Extract the factor at the given index, rendering the FTS invalid.
157 */
158 Factor extract_factor(int index);
159
160 void statistics(int index, utils::LogProxy& log) const;
161 void dump(int index, utils::LogProxy& log) const;
162 void dump(utils::LogProxy& log) const;
163
164 const TransitionSystem& get_transition_system(int index) const
165 {
166 return *transition_systems[index];
167 }
168
169 const Distances& get_distances(int index) const
170 {
171 return *distances[index];
172 }
173
174 /*
175 A factor is solvabe iff the distance of the initial state to some goal
176 state is not infinity. Technically, the distance is infinity either if
177 the information of Distances is infinity or if the initial state is
178 pruned.
179 */
180 bool is_factor_solvable(int index) const;
181
182 /*
183 A factor is trivial iff every concrete state is mapped to an abstract
184 goal state, which is equivalent to saying that the corresponding
185 merge-and-shrink representation is a total function and all abstract
186 states are goal states.
187
188 If h is the heuristic for the factor F, then we have:
189 F trivial => h(s) = 0 for all states s.
190
191 Note that a factor being trivial is sufficient but not necessary for
192 its heuristic to be useless. Scenarios of useless heuristics that are
193 not captured include:
194 - All non-goal states are connected to goal states on 0-cost paths.
195 - The only pruned states are unreachable (in this case, we get
196 h(s) = 0 for all reachable states, which is useless in most
197 contexts).
198 */
199 bool is_factor_trivial(int index) const;
200
201 int get_num_active_entries() const { return num_active_entries; }
202
203 // Used by LabelReduction and MergeScoringFunctionDFP
204 const Labels& get_labels() const { return *labels; }
205
206 // The following methods are used for iterating over the FTS
207 FTSConstIterator begin() const { return FTSConstIterator(*this, false); }
208
209 FTSConstIterator end() const { return FTSConstIterator(*this, true); }
210
211 int get_size() const { return transition_systems.size(); }
212
213 bool is_active(int index) const;
214};
215} // namespace merge_and_shrink
216
217#endif