-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathaction_manager.cpp
426 lines (357 loc) · 13.5 KB
/
action_manager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
#include "action_manager.h"
#include "type_manager.h"
#include "term_manager.h"
#include "predicate_manager.h"
#include "formula.h"
#include "parser_utils.h"
#include "plan_bindings.h"
#include "plan.h"
#include "fc_planner.h"
///#define MYPOP_ACTION_MANAGER_COMMENTS
namespace MyPOP {
/*************************
* The Action class
*************************/
Action* Action::dummy_action = new Action("", Formula::TRUE, NULL, NULL);
Action::Action(const std::string& predicate, const Formula& precondition, const std::vector<const Variable*>* variables, const std::vector<const Atom*>* effects)
: predicate_(predicate), precondition_(&precondition), variables_(variables), effects_(effects)
{
if (effects != NULL)
{
for (std::vector<const Atom*>::const_iterator ci = effects->begin(); ci != effects->end(); ++ci)
{
const Atom* effect = *ci;
std::vector<unsigned int>* effect_mappings = new std::vector<unsigned int>();
for (std::vector<const Term*>::const_iterator ci = effect->getTerms().begin(); ci != effect->getTerms().end(); ++ci)
{
const Term* effect_term = *ci;
unsigned int action_variable_index = std::distance(variables->begin(), std::find(variables->begin(), variables->end(), effect_term));
effect_mappings->push_back(action_variable_index);
}
effect_terms_to_action_variable_mappings_.push_back(effect_mappings);
}
}
}
Action::~Action()
{
if (precondition_ != &Formula::TRUE &&
precondition_ != &Formula::FALSE)
{
delete precondition_;
}
for (std::vector<const Atom*>::const_iterator ci = effects_->begin(); ci != effects_->end(); ci++)
{
delete *ci;
}
for (std::vector<std::vector<unsigned int>* >::const_iterator ci = effect_terms_to_action_variable_mappings_.begin(); ci != effect_terms_to_action_variable_mappings_.end(); ++ci)
{
delete *ci;
}
delete effects_;
delete variables_;
}
void Action::getAchievingEffects(const Atom& atom, std::vector<const Atom*>& achieving_effects) const
{
for (std::vector<const Atom*>::const_iterator ci = effects_->begin(); ci != effects_->end(); ci++)
{
const Atom* effect = *ci;
if (effect->getPredicate().getName() != atom.getPredicate().getName())
//if (&effect->getPredicate() != &atom.getPredicate())
continue;
// Make sure the sign is correct.
if (effect->isNegative() != atom.isNegative())
continue;
// Check if the terms have the same type.
if (effect->getArity() != atom.getArity())
continue;
bool types_differ = false;
for (unsigned int i = 0; i < effect->getArity(); i++)
{
const Type* effect_type = (effect->getTerms()[i])->getType();
const Type* atom_type = (atom.getTerms()[i])->getType();
if (((effect_type == NULL || atom_type == NULL) && effect_type != atom_type) ||
(!effect_type->isSubtypeOf(*atom_type) && !atom_type->isSubtypeOf(*effect_type) && !atom_type->isEqual(*effect_type)))
{
types_differ = true;
break;
}
}
if (types_differ)
continue;
achieving_effects.push_back(effect);
// Break here if there is only a single effect which can satisfy the action.
}
}
unsigned int Action::getActionVariable(unsigned int effect_index, unsigned int effect_term_index) const
{
return (*effect_terms_to_action_variable_mappings_[effect_index])[effect_term_index];
}
unsigned int Action::getActionVariable(const Term& term) const
{
for (unsigned int action_variable_index = 0; action_variable_index < variables_->size(); ++action_variable_index)
{
if ((*variables_)[action_variable_index] == &term)
{
return action_variable_index;
}
}
return std::numeric_limits<unsigned int>::max();
}
void Action::print(std::ostream& os, const Bindings& bindings, StepID step_id) const
{
os << "(" << predicate_ << " ";
for (std::vector<const Variable*>::const_iterator ci = variables_->begin(); ci != variables_->end(); ci++)
{
const VariableDomain& vd = bindings.getVariableDomain(step_id, **ci);
if (vd.getDomain().size() > 1)
{
os << "{";
}
for (std::vector<const Object*>::const_iterator ci2 = vd.getDomain().begin(); ci2 != vd.getDomain().end(); ci2++)
{
os << **ci2;
if (ci2 + 1 != vd.getDomain().end())
{
os << ", ";
}
}
if (vd.getDomain().size() > 1)
{
os << "}";
}
// os << "[ADDR=" << *ci << "]";
// os << "%" << &(vd.getDomain()) << "%";
if (ci + 1 != variables_->end())
{
os << " ";
}
}
os << ")";
}
std::ostream& operator<<(std::ostream& os, const Action& action)
{
os << "(" << action.predicate_ << " ";
for (std::vector<const Variable*>::const_iterator ci = action.variables_->begin(); ci != action.variables_->end(); ++ci)
{
os << **ci << "(" << *ci << ")";
if (ci + 1 != action.variables_->end())
{
os << " ";
}
}
os << ") effects " << std::endl;
for (std::vector<const Atom*>::const_iterator ci = action.effects_->begin(); ci != action.effects_->end(); ++ci)
{
const Atom* effect = *ci;
(*ci)->print(std::cout);
for (std::vector<const Term*>::const_iterator ci = effect->getTerms().begin(); ci != effect->getTerms().end(); ++ci)
{
os << *ci << ",";
}
os << std::endl;
}
return os;
}
/*************************
* The ActionManager class
*************************/
ActionManager::ActionManager(const TypeManager& type_manager, TermManager& term_manager, const PredicateManager& predicate_manager)
: type_manager_(&type_manager), term_manager_(&term_manager), predicate_manager_(&predicate_manager)
{
}
ActionManager::~ActionManager()
{
#ifdef MYPOP_ACTION_MANAGER_COMMENTS
std::cout << "[Destructor] ActionManager" << std::endl;
#endif
}
void ActionManager::processActions(const VAL::operator_list& operators)
{
for (VAL::operator_list::const_iterator ci = operators.begin(); ci != operators.end(); ci++)
{
const VAL::operator_* op = *ci;
const VAL::operator_symbol* name = op->name;
const VAL::var_symbol_list* parameters = op->parameters;
const VAL::goal* precondition = op->precondition;
const VAL::effect_lists* effects = op->effects;
// Get the predicate.
const std::string& predicate = name->getName();
// Initialize the variables.
std::vector<const Variable*>* action_variables = new std::vector<const Variable*>();
for (VAL::var_symbol_list::const_iterator i = parameters->begin(); i != parameters->end(); i++)
{
VAL::var_symbol* parameter = *i;
// Get the type of the parameter.
const Type* type = type_manager_->getType(parameter->type->getName());
Variable* var = new Variable(*type, parameter->getName());
term_manager_->addTerm(*parameter, *var);
// const Term* term = term_manager_->getTerm(*parameter);
// assert (term != NULL && term->isVariable());
// const Variable* var = term->asVariable();
//variables[var_counter++] = var;
action_variables->push_back(var);
}
// Parse the goals. The goal is a superclass of all possible goals.
// Possible goals:
// * disj_goal [not supported]
// * imply_goal [not supported]
// * neg_goal
// * timed_goal [not supported]
// * simple_goal
// * con_goal [not supported]
// * constraint_goal [not supported]
// * preference [not supported]
// * qfied_goal [not supported]
// * conj_goal
const Formula* action_precondition = Utility::convertGoal(*term_manager_, *predicate_manager_, precondition, false);
// Parse the effects. All possible effects are:
// * pc_list<simple_effect*> add_effects;
// * pc_list<simple_effect*> del_effects;
// * pc_list<forall_effect*> forall_effects; [not supported]
// * pc_list<cond_effect*> cond_effects; [not supported]
// * pc_list<cond_effect*> cond_assign_effects; [not supported]
// * pc_list<assignment*> assign_effects; [not supported]
// * pc_list<timed_effect*> timed_effects; [not supported]
std::vector<const Atom*>* action_effects = new std::vector<const Atom*>();
Utility::convertEffects(*term_manager_, *predicate_manager_, *effects, *action_effects);
Action* action = new Action(predicate, *action_precondition, action_variables, action_effects);
///Action* action = new Action(predicate, NULL, action_variables, NULL);
addManagableObject(action);
// Map the operator to the constructed action object for preprocessing purposes.
action_indexing_[op] = action;
}
}
void ActionManager::getAchievingActions(std::vector<std::pair<const Action*, const Atom*> >& actions, const Atom& atom) const
{
#ifdef MYPOP_ACTION_MANAGER_COMMENTS
std::cout << "Find all the actions which can achieve ";
atom.print(std::cout);
std::cout << std::endl;
#endif
// Create a list of all action which have the same predicate.
for (unsigned int i = 0; i < highest_id_; i++)
{
const Action* action = objects_[i];
std::vector<const Atom*> achieving_effects;
action->getAchievingEffects(atom, achieving_effects);
for (std::vector<const Atom*>::const_iterator ci = achieving_effects.begin(); ci != achieving_effects.end(); ci++)
{
actions.push_back(std::make_pair(action, *ci));
}
}
}
const Action& ActionManager::getAction(const VAL::operator_& val_operator) const
{
std::map<const VAL::operator_*, const Action*>::const_iterator ci = action_indexing_.find(&val_operator);
assert(ci != action_indexing_.end());
return *(*ci).second;
}
void ActionManager::ground(Bindings& bindings, std::vector<const Step*>& grounded_actions, const Action& action) const
{
// std::cout << "ground " << action << std::endl;
// In succession, assing one of the objects in each of its variable domains.
const std::vector<const Variable*>& action_variables = action.getVariables();
unsigned int variable_counter[action_variables.size()];
unsigned int max_variable_counter[action_variables.size()];
// std::cout << " " << action_variables.size() << " variables!" << std::endl;
// Initialise the maximum domain size of each action variable.
for (unsigned int i = 0; i < action_variables.size(); i++)
{
std::vector<const Object*> values;
term_manager_->getTypeManager().getObjectsOfType(values, *action_variables[i]->getType());
variable_counter[i] = 0;
max_variable_counter[i] = values.size();
// std::cout << " Size of variable domain " << *action_variables[i] << " is: " << values.size() << std::endl;
}
while (true)
{
// std::cout << " process: ";
// for (unsigned int i = 0; i < action_variables.size(); i++)
// {
// std::cout << variable_counter[i] << ", ";
// }
// std::cout << std::endl;
// Create a new action binding.
StepID action_id = bindings.createVariableDomains(action);
// Assign the domains.
for (unsigned int i = 0; i < action_variables.size(); i++)
{
VariableDomain& variable_domain = bindings.getNonConstVariableDomain(action_id, *action_variables[i]);
variable_domain.makeEqualTo(*variable_domain.getDomain()[variable_counter[i]]);
// std::cout << variable_domain << " [" << *variable_domain.getDomain()[variable_counter[i]] << "]" << std::endl;
}
// Store the grounded action.
grounded_actions.push_back(new Step(action_id, action));
// Iterate through all possible combinations of variable assignments, akin binary iterating.
unsigned int variable_to_update = 0;
while (variable_to_update < action_variables.size())
{
if (variable_counter[variable_to_update] + 1 != max_variable_counter[variable_to_update])
{
variable_counter[variable_to_update]++;
break;
}
variable_counter[variable_to_update] = 0;
variable_to_update++;
}
// If the variable_to_update equals action_variables we have exhausted all combinations, break.
if (variable_to_update == action_variables.size())
{
break;
}
}
}
void ActionManager::ground(std::vector<const GroundedAction*>& grounded_actions, const Action& action) const
{
// In succession, assing one of the objects in each of its variable domains.
const std::vector<const Variable*>& action_variables = action.getVariables();
unsigned int variable_counter[action_variables.size()];
unsigned int max_variable_counter[action_variables.size()];
// std::cout << " " << action_variables.size() << " variables!" << std::endl;
std::vector<const Object*>** parameter_values = new std::vector<const Object*>*[action_variables.size()];
// Initialise the maximum domain size of each action variable.
for (unsigned int i = 0; i < action_variables.size(); i++)
{
std::vector<const Object*>* values = new std::vector<const Object*>();
term_manager_->getTypeManager().getObjectsOfType(*values, *action_variables[i]->getType());
variable_counter[i] = 0;
max_variable_counter[i] = values->size();
parameter_values[i] = values;
// std::cout << " Size of variable domain " << *action_variables[i] << " is: " << values.size() << std::endl;
}
while (true)
{
const Object** parameters = new const Object*[action_variables.size()];
// Assign the domains.
for (unsigned int i = 0; i < action_variables.size(); i++)
{
parameters[i] = (*parameter_values[i])[variable_counter[i]];
}
const GroundedAction& grounded_action = GroundedAction::getGroundedAction(action, parameters);
grounded_actions.push_back(&grounded_action);
// Iterate through all possible combinations of variable assignments, akin binary iterating.
unsigned int variable_to_update = 0;
while (variable_to_update < action_variables.size())
{
if (variable_counter[variable_to_update] + 1 != max_variable_counter[variable_to_update])
{
variable_counter[variable_to_update]++;
break;
}
variable_counter[variable_to_update] = 0;
variable_to_update++;
}
// If the variable_to_update equals action_variables we have exhausted all combinations, break.
if (variable_to_update == action_variables.size())
{
break;
}
}
// Cleanup.
for (unsigned int i = 0; i < action_variables.size(); i++)
{
delete parameter_values[i];
}
delete[] parameter_values;
}
};