AI 24/25 Project Software
Documentation for the AI 24/25 course programming project software
Loading...
Searching...
No Matches
causal_graph.h
1#ifndef TASK_UTILS_CAUSAL_GRAPH_H
2#define TASK_UTILS_CAUSAL_GRAPH_H
3
4/*
5 TODO: Perform some memory profiling on this class.
6
7 This implementation precomputes some information (in particular the
8 "predecessor" and "successor" information) that could also be
9 computed on the fly. Is this a good time/memory tradeoff? We usually
10 expect causal graphs to be rather small, but we have some planning
11 tasks with huge numbers of variables.
12
13 In the other direction, it might also be useful to have even more
14 causal graph variants directly available, e.g. a "get_neighbors"
15 method that is the union of pre->eff, eff->pre and eff->eff arcs.
16 Before doing this, we should check that they are useful somewhere
17 and do the memory profiling.
18*/
19
20/*
21 An IntRelation represents a relation on a set {0, ..., K - 1} as an
22 adjacency list, encoded as a vector<vector<int> >. For example, the
23 relation { (0, 1), (0, 3), (1, 3), (3, 0), (3, 1), (3, 2) } over the
24 set {0, 1, 3, 4} would be represented as
25
26 [
27 [1, 3], # representing (0, 1), (0, 3)
28 [3], # representing (1, 3)
29 [], # there are no pairs of the form (2, v)
30 [0, 1, 2], # representing (3, 0), (3, 1), (3, 2)
31 [] # there are no pairs of the form (4, v)
32 ]
33
34 The number K is called the range of the relation.
35
36 The individual lists are guaranteed to be sorted and free of
37 duplicates.
38
39 TODO: IntRelations, along with the efficient way of constructing
40 them in causal_graph.cc, could be useful for other parts of the
41 planner, too. If this is the case, they should be moved to a
42 different source file.
43
44 TODO: IntRelations currently only work for relations on {0, ..., K -
45 1}^2. They could easily be generalized to relations on {0, ..., K -
46 1 } x S for arbitrary sets S. Our current code only requires that S
47 is hashable and sortable, and we have one assertion that checks that
48 S = {0, ..., K - 1}. This could easily be changed if such a
49 generalization is useful anywhere in the code.
50*/
51
52#include <vector>
53
54typedef std::vector<std::vector<int>> IntRelation;
55
56class AbstractTask;
57class TaskProxy;
58
59namespace causal_graph {
60
61class CausalGraph {
62 IntRelation pre_to_eff;
63 IntRelation eff_to_pre;
64 IntRelation eff_to_eff;
65
66 IntRelation successors;
67 IntRelation predecessors;
68
69 // TODO remove
70 void dump() const;
71
72 void dump(const TaskProxy& task_proxy) const;
73
74public:
75 // TODO remove
76 CausalGraph();
77
78 /* Use the factory function get_causal_graph to create causal graphs
79 to avoid creating more than one causal graph per AbstractTask. */
80 explicit CausalGraph(const TaskProxy& task_proxy);
81
82 ~CausalGraph();
83
84 /*
85 All below methods querying neighbors (of some sort or other) of
86 var guarantee that:
87 - the return vertex list is sorted
88 - var itself is not in the returned list
89
90 "Successors" and "predecessors" are w.r.t. the common definition
91 of causal graphs, which have pre->eff and eff->eff arcs.
92
93 Note that axioms are treated as operators in the causal graph,
94 i.e., their condition variables are treated as precondition
95 variables and the derived variable is treated as an effect
96 variable.
97
98 For effect conditions, we only add pre->eff arcs for the respective
99 conditional effect.
100 */
101
102 const std::vector<int>& get_pre_to_eff(int var) const
103 {
104 return pre_to_eff[var];
105 }
106
107 const std::vector<int>& get_eff_to_pre(int var) const
108 {
109 return eff_to_pre[var];
110 }
111
112 const std::vector<int>& get_eff_to_eff(int var) const
113 {
114 return eff_to_eff[var];
115 }
116
117 const std::vector<int>& get_successors(int var) const
118 {
119 return successors[var];
120 }
121
122 const std::vector<int>& get_predecessors(int var) const
123 {
124 return predecessors[var];
125 }
126
127 const std::vector<std::vector<int>>& get_arcs() const { return successors; }
128
129 const std::vector<std::vector<int>>& get_inverse_arcs() const
130 {
131 return predecessors;
132 }
133};
134
135/* Create or retrieve a causal graph from cache. If causal graphs are created
136 with this function, we build at most one causal graph per AbstractTask. */
137extern const CausalGraph& get_causal_graph(const AbstractTask* task);
138} // namespace causal_graph
139#endif