Fawkes API  Fawkes Development Version
stn_action.cpp
1 
2 /***************************************************************************
3  * stn_action.cpp - stn-generator
4  *
5  * Created: Sat May 6 20:16:21 2017
6  * Copyright 2017 Matthias Loebach
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "stn_action.h"
23 
24 namespace fawkes {
25 namespace stn {
26 
27 /** @class StnAction "stn_action.h"
28  * An action representation within an STN.
29  */
30 
31 size_t StnAction::count = 0;
32 
33 /** Constructor.
34  * @param name The name of the new action.
35  * @param preconds A Vector of Predicates that must be satisfied to execute the
36  * action.
37  * @param effects A vector of Predicates that are applied after the action is
38  * executed.
39  * @param opts The action parameters.
40  * @param duration The duration of the action.
41  * @param cond_breakups A vector of conditional breakups as strings.
42  * @param temp_breakups A vector of temporal breakups as strings.
43  */
44 StnAction::StnAction(const std::string & name,
45  const std::vector<Predicate> & preconds,
46  const std::vector<Predicate> & effects,
47  const std::string & opts,
48  size_t duration,
49  const std::vector<std::string> &cond_breakups,
50  const std::vector<std::string> &temp_breakups)
51 : name_(name),
52  preconds_(preconds),
53  effects_(effects),
54  opts_(opts),
55  duration_(duration),
56  cond_breakups_(cond_breakups),
57  temp_breakups_(temp_breakups)
58 {
59  id_ = ++count;
60 }
61 
62 /** Print relevant information about the StnAction.
63  * @param strm The stream to print the information to.
64  * @param a The action to show the information about.
65  */
66 std::ostream &
67 operator<<(std::ostream &strm, const StnAction &a)
68 {
69  strm << "id: " << a.id_ << std::endl << "action: " << a.name_ << "\npreconditions:" << std::endl;
70  for (Predicate p : a.preconds_) {
71  strm << p;
72  }
73  strm << "effects:" << std::endl;
74  for (Predicate e : a.effects_) {
75  strm << e;
76  }
77  strm << "required actions: ";
78  for (auto const &kv : a.cond_actions_) {
79  strm << kv.first << ":" << kv.second.first;
80  for (auto const &p : kv.second.second) {
81  strm << p;
82  }
83  }
84  strm << "duration: " << std::to_string(a.duration_) << std::endl;
85  if (!a.cond_breakups_.empty()) {
86  strm << "conditional breakup conditions: ";
87  }
88  for (auto const &p : a.cond_breakups_) {
89  strm << p;
90  }
91  if (!a.temp_breakups_.empty()) {
92  strm << "temporal breakup conditions: ";
93  }
94  for (auto const &p : a.temp_breakups_) {
95  strm << p;
96  }
97  strm << std::endl << std::endl;
98 
99  return strm;
100 }
101 
102 /** Compare two StnActions.
103  * @param o The other StnAction.
104  * @return True iff the two actions have the same ID.
105  */
106 bool
108 {
109  return id_ == o.id_;
110 }
111 
112 /** Compare two StnActions.
113  * @param o The other StnAction.
114  * @return True iff the two actions have different IDs.
115  */
116 bool
118 {
119  return id_ != o.id_;
120 }
121 
122 /** Get the ID of the action.
123  * @return The unique ID.
124  */
125 size_t
127 {
128  return id_;
129 }
130 
131 /** Get all IDs of this StnAction's conditional actions.
132  * @return A vector of IDs.
133  */
134 std::vector<size_t>
136 {
137  std::vector<size_t> ids;
138  for (auto const &kv : cond_actions_) {
139  ids.push_back(kv.first);
140  }
141  return ids;
142 }
143 
144 /** Check if the given predicate is a breakup.
145  * @param t The type of of breakup to check.
146  * @param p The Predicate to check.
147  * @return True iff a breakup by the given predicate is possible.
148  */
149 bool
150 StnAction::checkForBreakup(EdgeType t, const Predicate &p) const
151 {
152  const std::vector<std::string> *breakups;
153  if (t == EdgeType::CONDITIONAL) {
154  breakups = &cond_breakups_;
155  } else if (t == EdgeType::TEMPORAL) {
156  breakups = &temp_breakups_;
157  } else {
158  throw "Wrong Edge type";
159  }
160 
161  if (std::find(breakups->begin(), breakups->end(), p.name()) != breakups->end()) {
162  std::cout << "Break because of: " << p << " ";
163  switch (t) {
164  case EdgeType::CONDITIONAL: std::cout << "Conditional" << std::endl; break;
165  case EdgeType::TEMPORAL: std::cout << "Temporal" << std::endl; break;
166  }
167  return true;
168  }
169  return false;
170 }
171 
172 /** Get a string representation of the StnAction for the graph representation.
173  * @return The string describing the StnAction.
174  */
175 std::string
177 {
178  return "Action ID: " + std::to_string(id_) + "\n" + "Name: " + name_ + "\n" + "Params: " + opts_;
179 }
180 
181 /** Generate an edge label for the graph representation.
182  * @param cond_action The ID of the conditional action to represent.
183  * @return The string describing the conditional action.
184  */
185 std::string
186 StnAction::genConditionEdgeLabel(size_t cond_action) const
187 {
188  std::string edge_label;
189  std::map<size_t, std::pair<std::string, std::vector<Predicate>>>::const_iterator it =
190  cond_actions_.find(cond_action);
191  if (it == cond_actions_.end())
192  return "";
193  for (Predicate p : it->second.second) {
194  if (p.condition()) {
195  edge_label += "<FONT COLOR=\"darkgreen\">";
196  } else {
197  edge_label += "<FONT COLOR=\"red\">";
198  }
199  edge_label += p.name() + ": ";
200  for (const std::string s : p.attrs()) {
201  edge_label += s + " ";
202  }
203  edge_label += "</FONT>";
204  }
205  return edge_label;
206 }
207 
208 /** Generate a temporal edge for the graph representation.
209  * @return The string label for the temporal edge.
210  */
211 std::string
213 {
214  std::string edge_label = "<FONT COLOR=\"blue\">";
215  edge_label += std::to_string(duration_);
216  edge_label += "</FONT>";
217  return edge_label;
218 }
219 
220 /** Generate the conditional actions of this StnAction.
221  * @param candidate_actions The actions to be considered as conditional actions.
222  */
223 void
224 StnAction::genConditionalActions(const std::vector<StnAction> candidate_actions)
225 {
226  std::vector<Predicate> check_preds = preconds_;
227  // iterate backwards to resolve conditions in the correct order
228  for (int i = candidate_actions.size() - 1; i >= 0; i--) {
229  try {
230  for (Predicate candidate_pred : candidate_actions.at(i).effects_) {
231  for (auto pred_it = check_preds.begin(); pred_it != check_preds.end();) {
232  if (!checkForBreakup(EdgeType::CONDITIONAL, (*pred_it)) && (*pred_it) == candidate_pred) {
233  std::map<size_t, std::pair<std::string, std::vector<Predicate>>>::iterator it =
234  cond_actions_.find(candidate_actions.at(i).id_);
235  if (it == cond_actions_.end()) {
236  cond_actions_.insert(
237  std::map<size_t, std::pair<std::string, std::vector<Predicate>>>::value_type(
238  candidate_actions.at(i).id_,
239  std::make_pair(candidate_actions.at(i).name_,
240  std::vector<Predicate>{(*pred_it)})));
241  } else {
242  it->second.second.push_back((*pred_it));
243  }
244  // remove predicate to only take the first (backwards)
245  // occurence of a predicate into account _it
246  pred_it = check_preds.erase(pred_it);
247  } else {
248  pred_it++;
249  }
250  }
251  }
252  } catch (std::exception &e) {
253  std::cout << "ERROR in stn_action: " << e.what() << std::endl;
254  }
255  }
256 
257  // erase initial condition if others are present
258  /*std::map<size_t, std::pair<std::string, std::vector<Predicate>>>::iterator it = cond_actions_.find(0);
259  if ( cond_actions_.size() > 1 && it != cond_actions_.end() ) {
260  cond_actions_.erase(it);
261  }*/
262 }
263 
264 /** Get the effects of the StnAction.
265  * @return A vector of Predicates that are part of the effect.
266  */
267 const std::vector<Predicate> &
269 {
270  return effects_;
271 }
272 
273 /** Get the name of the StnAction.
274  * @return The name as string.
275  */
276 std::string
278 {
279  return name_;
280 }
281 
282 /** Get the duration of the StnAction.
283  * @return The duration.
284  */
285 size_t
287 {
288  return duration_;
289 }
290 
291 /** Get the action parameters.
292  * @return The parameters as string.
293  */
294 std::string
296 {
297  return opts_;
298 }
299 
300 } // namespace stn
301 } // namespace fawkes
fawkes::stn::StnAction::genTemporalEdgeLabel
std::string genTemporalEdgeLabel() const
Generate a temporal edge for the graph representation.
Definition: stn_action.cpp:212
fawkes::stn::StnAction::opts
std::string opts() const
Get the action parameters.
Definition: stn_action.cpp:295
fawkes::stn::StnAction::duration
size_t duration() const
Get the duration of the StnAction.
Definition: stn_action.cpp:286
fawkes::stn::StnAction::operator!=
bool operator!=(const StnAction &o)
Compare two StnActions.
Definition: stn_action.cpp:117
fawkes::stn::Predicate::name
std::string name() const
Get the name of the predicate.
Definition: predicate.cpp:72
fawkes::stn::Predicate::attrs
const std::vector< std::string > & attrs() const
Get the attributes of the predicate.
Definition: predicate.cpp:90
fawkes::stn::StnAction::operator==
bool operator==(const StnAction &o)
Compare two StnActions.
Definition: stn_action.cpp:107
fawkes::stn::StnAction::checkForBreakup
bool checkForBreakup(EdgeType t, const Predicate &p) const
Check if the given predicate is a breakup.
Definition: stn_action.cpp:150
fawkes::stn::StnAction::genConditionalActions
void genConditionalActions(std::vector< StnAction > candidate_actions)
Generate the conditional actions of this StnAction.
Definition: stn_action.cpp:224
fawkes::stn::StnAction::condActionIds
std::vector< size_t > condActionIds() const
Get all IDs of this StnAction's conditional actions.
Definition: stn_action.cpp:135
fawkes::stn::StnAction::genConditionEdgeLabel
std::string genConditionEdgeLabel(size_t cond_action) const
Generate an edge label for the graph representation.
Definition: stn_action.cpp:186
fawkes
Fawkes library namespace.
fawkes::stn::StnAction::genGraphNodeName
std::string genGraphNodeName() const
Get a string representation of the StnAction for the graph representation.
Definition: stn_action.cpp:176
fawkes::stn::StnAction::effects
const std::vector< Predicate > & effects() const
Get the effects of the StnAction.
Definition: stn_action.cpp:268
fawkes::stn::Predicate
A representation of a Predicate in the STN.
Definition: predicate.h:33
fawkes::stn::StnAction
An action representation within an STN.
Definition: stn_action.h:41
fawkes::stn::Predicate::condition
bool condition() const
Get the condition of the predicate.
Definition: predicate.cpp:81
fawkes::stn::StnAction::name
std::string name() const
Get the name of the StnAction.
Definition: stn_action.cpp:277
fawkes::stn::StnAction::id
size_t id() const
Get the ID of the action.
Definition: stn_action.cpp:126