]> ruin.nu Git - popboot.git/blob - planner.cpp
parallell
[popboot.git] / planner.cpp
1 #include "planner.h"
2 #include "node.h"
3 #include <iostream>
4 using namespace std;
5 using namespace __gnu_cxx;
6
7 extern "C" void* executeNode(void* arg);
8
9 struct ExecutionStuff {
10         sem_t* nodes;
11         sem_t* list;
12         Node* node;
13         queue<Node*>* execQueue;
14 };
15
16 Planner::Planner(std::vector<Action> actions, Literals init, Literals goal){
17         _init = init;
18         _goal = goal;
19         _start = new StartNode(_init);
20         _finish = new EndNode(_goal);
21         addNode(_start);
22
23         for(vector<Action>::iterator action = actions.begin(); action != actions.end(); ++action){
24                 Action* act = new Action(*action);
25                 _actions.push_back(act);
26                 const Literals& effects = act->effects(0);
27                 for (Literals::const_iterator effect = effects.begin(); effect != effects.end(); ++effect){
28                         //cerr << "Adding effect: '" << *effect << "', action: " << action->name() << endl;
29                         _actionEffects[*effect] = act;
30                 }
31         }
32         //cerr << "Number of actions: " << _actions.size() << endl;
33         makePlan(_finish);
34 }
35
36 Planner::~Planner(){
37         //cerr << "Deleting " << _addedNodes.size() << " nodes" << endl;
38         for (vector<Node*>::iterator node = _addedNodes.begin(); node != _addedNodes.end(); ++node){
39                 //cerr << "Deleting node " << (*node)->action()->name() << endl;
40                 delete *node;
41         }
42         for (vector<Action*>::iterator action = _actions.begin(); action != _actions.end(); ++action){
43                 //cerr << "Deleting action " << (*action)->name() << endl;
44                 delete *action;
45         }
46 }
47
48
49 void Planner::makePlan(Node* node){
50         addNode(node);
51
52         //cerr << "Fetching preconditions for action: " << node->action()->name() << ".. ";
53         const Preconditions& preconds = node->action()->preconditions();
54         //cerr << "done" << endl;
55
56
57         if (preconds.size() == 0){
58                 //cerr << "Found no preconds" << endl;
59                 _start->addChild(node);
60         }else{
61                 for (Preconditions::const_iterator precond = preconds.begin(); precond != preconds.end(); ++precond){
62                         //cerr << "Looking for: '" << precond->first << "'" <<  endl;
63                         hash_map<string,Node*>::iterator addedNode = _addedEffects.find(precond->first);
64                         if(addedNode != _addedEffects.end()){
65                                 //cerr << "Using already added node" << endl;
66                                 addedNode->second->addChild(node);
67                         }else {
68                                 hash_map<string, Action*>::iterator action = _actionEffects.find(precond->first);
69                                 if (action != _actionEffects.end()){
70                                         //cerr << "Adding new node" << endl;
71                                         Node* newnode = new Node(action->second);
72                                         newnode->addChild(node);
73                                         makePlan(newnode);
74                                 }else if (precond->second){
75                                         //cerr << "Action with effect: " << precond->first << " not found!" << endl;
76                                         //cerr << "This is a hard precondition, so this action and the children can't be executed." << endl;
77                                         return;
78                                 }else{
79                                         //cerr << "Action with effect: " << precond->first << " not found!" << endl;
80                                         //cerr << "This is a soft precondition, so we will continue" << endl;
81                                         node->satisfyCondition(precond->first);
82                                         _start->addChild(node);
83                                 }
84                         }
85                 }
86         }
87 }
88
89 void Planner::addNode(Node* node){
90         //cerr << "Adding node for action: " << node->action()->name() << endl;
91         const Literals& effects = node->action()->effects(0);
92         //cerr << "Number of effects: " << effects.size() << endl;
93         _addedNodes.push_back(node);
94
95         for (Literals::const_iterator effect = effects.begin(); effect != effects.end(); ++effect){
96                 //cerr << "Adding node for effect: " << *effect << endl;
97                 _addedEffects[*effect] = node;
98         }
99 }
100
101
102 void Planner::execute(){
103         _executedNodes.push(_start);
104         sem_init(&_nodes, 0, 1);
105         sem_init(&_list, 0, 1);
106
107         int executions = 1;
108         while (executions > 0){
109                 cerr << "Waiting for a node to finish execution" << endl;
110                 int retval;
111                 sem_getvalue(&_nodes, &retval);
112                 cerr << "Semaphore before wait: " << retval << endl;
113                 sem_wait(&_nodes);
114                 sem_getvalue(&_nodes, &retval);
115                 cerr << "Semaphore after wait: " << retval << endl;
116                 --executions;
117
118                 cerr << "Getting node: ";
119                 sem_wait(&_list);
120                 cerr << "Number of nodes in queue: " << _executedNodes.size() << endl;
121                 Node* node = _executedNodes.front();
122                 _executedNodes.pop();
123                 sem_post(&_list);
124                 cerr << (int) node << endl;
125                 cerr << node->action()->name() << ", and children..  ";
126                 vector<Node*> children = node->children();
127                 cerr << " done"  << endl;
128                 if (node == _finish)
129                         return;
130                 cerr << "Iterating over the children, number: " << children.size() << endl;
131                 for(vector<Node*>::iterator child = children.begin(); child != children.end(); ++child){
132                         if ((*child)->satisfyConditions(node->effects())){
133                                 ++executions;
134                                 cerr << "Creating new thread" << endl;
135                                 pthread_attr_t tattr;
136                                 pthread_t tid;
137                                 pthread_attr_init(&tattr);
138                                 pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);
139                                 ExecutionStuff* es = new ExecutionStuff;
140                                 es->nodes = &_nodes;
141                                 es->list = &_list;
142                                 es->node = *child;
143                                 es->execQueue = &_executedNodes;
144                                 pthread_create(&tid, &tattr, executeNode, es);
145                                 //executeNode(es);
146                         }
147                 }
148
149         }
150         cerr << "Number of nodes: " << _addedNodes.size() << endl;
151         back_insert_iterator<Literals> ii(_init);
152         _init.clear();
153         for (vector<Node*>::iterator node = _addedNodes.begin(); node != _addedNodes.end(); ++node){
154                 cerr << "Deleting node " << (*node)->action()->name() << endl;
155                 if ((*node)->executed()){
156                         executions++;
157                         const Literals& effects = (*node)->effects();
158                         copy(effects.begin(),effects.end(),ii);
159                         cerr << "Finding action" << endl;
160                         vector<Action*>::iterator action = find(_actions.begin(), _actions.end(), (*node)->action());
161                         if (action != _actions.end()){
162                                 cerr << "Removing executed action: " << (*action)->name() << endl;
163                                 delete *action;
164                                 _actions.erase(action);
165                         }
166                 }
167                 delete *node;
168         }
169         _addedNodes.clear();
170         _addedEffects.clear();
171         _actionEffects.clear();
172         copy(_init.begin(), _init.end(), ostream_iterator<string>(cerr, " "));
173         cerr << endl;
174         cerr << "Number of actions left: " << _actions.size() << endl;
175         //TODO: Fill _actionEffects with the remaining effects, create start end end nodes and create a new plan.
176         if (executions <= 1){
177                 cerr << "Non of the remaining actions could be executed, quiting." << endl;
178                 return;
179         }
180         if (_actions.size() == 0){
181                 cerr << "No remaining actions, quiting." << endl;
182                 return;
183         }
184         for (vector<Action*>::iterator action = _actions.begin(); action != _actions.end(); ++action){
185                 const Literals& effects = (*action)->effects(0);
186                 for (Literals::const_iterator effect = effects.begin(); effect != effects.end(); ++effect){
187                         cerr << "Adding effect: '" << *effect << "', action: " << (*action)->name() << endl;
188                         _actionEffects[*effect] = *action;
189                 }
190         }
191         _start = new StartNode(_init);
192         _finish = new EndNode(_goal);
193         addNode(_start);
194         makePlan(_finish);
195         if (_addedNodes.size() <= 2){
196                 cerr << "No actions to execute, quiting." << endl;
197                 return;
198         }
199         execute();
200         
201 }
202 void* executeNode(void* arg){
203         cerr << "Running new thred." << endl;
204         ExecutionStuff* es = (ExecutionStuff*)arg;
205
206         if (es == 0)
207                 pthread_exit((void*)1);
208
209         es->node->execute();
210
211         sem_wait(es->list);
212         cerr << "Adding pointer with value: " << (int)es->node << endl;
213         es->execQueue->push(es->node);
214         sem_post(es->list);
215
216         cerr << "Increasing semaphore" << endl;
217         sem_post(es->nodes);
218
219         pthread_exit((void*)0);
220 }