00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00027
00028
00029
00030
00031
00032
00033
00034 #include <search_graph.h>
00035
00036 using namespace vgtl;
00037 using namespace std;
00038
00039 #include "sum_deltas.h"
00040
00041 search_focus& search_graph::new_focus(const search_inspector& where)
00042 {
00043 search_inspector where_copy = where;
00044 walker focus_to_add((node_type *) where_copy.node());
00045
00046 if(find(focus.begin(), focus.end(), focus_to_add) != focus.end())
00047 throw search_graph_exception
00048 ("in search_graph :: new_focus : the inspected node is already focused");
00049 focus.push_front(focus_to_add);
00050 return focus.front();
00051 }
00052
00053 void search_graph::destroy_focus(const search_focus& where)
00054 {
00055 list<walker>::iterator i = find(focus.begin(), focus.end(), where);
00056 if(i == focus.end())
00057 throw search_graph_exception
00058 ("in search_graph :: destroy_focus (...) : the focus does not exist");
00059 focus.erase(i);
00060 }
00061
00062 search_focus& search_graph::set_focus(search_focus& focus_to_replace,
00063 const search_inspector& where)
00064 {
00065 list<walker>::iterator i =
00066 find(focus.begin(), focus.end(), focus_to_replace);
00067 if(i == focus.end())
00068 throw search_graph_exception
00069 ("in search_graph :: set_focus (...) : the focus does not exist");
00070 search_inspector where_copy = where;
00071
00072 *i = walker((node_type *) where_copy.node());
00073 return *i;
00074 }
00075
00076 search_inspector& search_graph::new_inspector(const search_inspector &
00077 inspector_to_add)
00078 {
00079 list<const_walker>::iterator i =
00080 find(inspector.begin(), inspector.end(), inspector_to_add);
00081 if(i != inspector.end())
00082 return *i;
00083 inspector.push_front(inspector_to_add);
00084 return inspector.front();
00085 }
00086
00087 void search_graph::destroy_inspector(const search_inspector &
00088 inspector_to_destroy)
00089 {
00090 list<const_walker>::iterator i =
00091 find(inspector.begin(), inspector.end(), inspector_to_destroy);
00092 if(i == inspector.end())
00093 throw search_graph_exception
00094 ("in search_graph :: destroy_inspector (...) : the inspector does not exist");
00095 inspector.erase(i);
00096 }
00097
00098 work_node search_graph::extract(const search_inspector & where)
00099 {
00100 list<const_walker>::iterator i =
00101 find(inspector.begin(), inspector.end(), where);
00102 if(i == inspector.end())
00103 throw search_graph_exception
00104 ("in search_graph :: extract (...) : the inspector does not exist");
00105 work_node *result = recursive_walk_up_if(where, sum_deltas(ptr_ground));
00106 work_node where_as_work_node(*result);
00107 where_as_work_node._snr = (*where)->parent_relation();
00108 delete result;
00109
00110 return where_as_work_node;
00111 }
00112
00113 work_node search_graph::extract(const search_focus & where)
00114 {
00115 list<walker>::iterator i =
00116 find(focus.begin(), focus.end(), where);
00117 if(i == focus.end())
00118 throw search_graph_exception
00119 ("in search_graph :: extract (...) : the focus does not exist");
00120 work_node *result = recursive_walk_up_if(where, sum_deltas(ptr_ground));
00121 work_node where_as_work_node(*result);
00122 where_as_work_node._snr = (*where)->parent_relation();
00123 delete result;
00124
00125 return where_as_work_node;
00126 }
00127
00128 search_inspector& search_graph::insert(const search_focus &where,
00129 const search_node &what)
00130 {
00131 search_focus protected_where(where);
00132 walker new_where =
00133 split(protected_where, protected_where.child_begin(), sky(),
00134 sky().parent_begin(), (search_node*) &what);
00135
00136 const_walker new_where_as_const_walker((node_type*) new_where.node());
00137
00138 inspector.push_front(new_where_as_const_walker);
00139 return inspector.front();
00140 }
00141
00142 search_inspector& search_graph::replace(search_focus& where,
00143 const search_node &what)
00144 {
00145 list<walker>::iterator i = find(focus.begin(), focus.end(), where);
00146 if(i == focus.end())
00147 throw search_graph_exception
00148 ("in search_graph :: replace (...) : the focus does not exist");
00149 *where = (search_node*) &what;
00150 inspector.push_front(const_walker((node_type*) where.node()));
00151 return inspector.front();
00152 }
00153
00154 void search_graph::_internal_remove(search_focus& where)
00155 {
00156 if((*where)->is_delta())
00157 {
00158 delta_node& where_as_delta = *(delta_node*) *where;
00159 if(!where.is_leaf())
00160 {
00161 for(walker::children_iterator c = where.child_begin();
00162 c != where.child_end(); ++c)
00163 if((*(where >> c))->is_delta())
00164 {
00165
00166 delta_node*& c_as_delta = (delta_node*) *(where >> c);
00167
00168 vector<delta_id> delta_where_plus_delta_c;
00169 for(unsigned int i = 0; i < where_as_delta.n_deltas(); ++i)
00170 {
00171 db_deltas_to_remove.push_front(where_as_delta.get_delta_id(i));
00172 delta_where_plus_delta_c.push_back(db_deltas_to_remove.front());
00173 }
00174 for(unsigned int i = 0; i < c_as_delta->n_deltas(); ++i)
00175 {
00176 db_deltas_to_remove.push_front(c_as_delta->get_delta_id(i));
00177 delta_where_plus_delta_c.push_back(db_deltas_to_remove.front());
00178 }
00179 gptr<vdbl::database>* _xdb = c_as_delta->database();
00180 delete c_as_delta;
00181 for(list<search_node*>::iterator i=search_nodes_to_deallocate.begin();
00182 i != search_nodes_to_deallocate.end(); ++i)
00183 if(c_as_delta == *i)
00184 {
00185 search_nodes_to_deallocate.erase(i);
00186 break;
00187 }
00188
00189 c_as_delta = new delta_node(get_node_id(), __dbuser,
00190 delta_where_plus_delta_c, ptr_ground,
00191 *_xdb);
00192 search_nodes_to_deallocate.push_front(c_as_delta);
00193 }
00194 }
00195 }
00196 else
00197 {
00198 full_node& where_as_full = *(full_node*) *where;
00199 if(!where.is_leaf())
00200 {
00201 for(walker::children_iterator c = where.child_begin();
00202 c != where.child_end(); ++c)
00203 if((*(where >> c))->is_delta())
00204 {
00205 delta_node *&c_as_delta = (delta_node*) *(where >> c);
00206 work_node full_where_plus_delta_c(full_node_to_work_node
00207 (where_as_full, ptr_ground));
00208 for(unsigned int i = 0; i < c_as_delta->n_deltas(); ++i)
00209 full_where_plus_delta_c += c_as_delta->get_delta_id(i);
00210 delete *(where >> c);
00211 for(list<search_node*>::iterator i=search_nodes_to_deallocate.begin();
00212 i != search_nodes_to_deallocate.end(); ++i)
00213 if(*(where >> c) == *i)
00214 {
00215 search_nodes_to_deallocate.erase(i);
00216 break;
00217 }
00218
00219 *(where >> c) = new work_node(full_where_plus_delta_c);
00220 search_nodes_to_deallocate.push_front(*(where >> c));
00221 }
00222 }
00223 }
00224
00225
00226 if((*where)->parent_relation() == snr_split)
00227 {
00228 if(where.n_parents() > 1)
00229 throw search_graph_exception
00230 ("in search_graph :: remove (...) : a split has more than one parent");
00231 else
00232 {
00233 walker::parents_iterator p = where.parent_begin();
00234 walker parent_of_where = where << p;
00235 unsigned int num_of_splits(0);
00236 walker first_split;
00237 for(walker::children_iterator c = parent_of_where.child_begin();
00238 c != parent_of_where.child_end(); ++c)
00239 {
00240 walker child_of_parent_of_where = parent_of_where >> c;
00241 if(child_of_parent_of_where != where &&
00242 (*child_of_parent_of_where)->parent_relation() == snr_split)
00243 {
00244 if(num_of_splits == 0)
00245 first_split = child_of_parent_of_where;
00246 num_of_splits++;
00247 }
00248 }
00249 if(num_of_splits == 1)
00250 (*first_split)->_snr = snr_reduction;
00251 }
00252 }
00253
00254 delete *where;
00255 for(list<search_node*>::iterator i=search_nodes_to_deallocate.begin();
00256 i != search_nodes_to_deallocate.end(); ++i)
00257 if(*where == *i)
00258 {
00259 search_nodes_to_deallocate.erase(i);
00260 break;
00261 }
00262
00263 erase(where);
00264 return;
00265 }
00266
00267 void search_graph::remove(search_focus& where)
00268 {
00269 list<walker>::iterator flw = find(focus.begin(), focus.end(), where);
00270 if(flw == focus.end())
00271 throw search_graph_exception
00272 ("in search_graph :: remove (...) : the focus does not exist");
00273 if(where.n_parents() >= 2 && (*where)->parent_relation() != snr_glue)
00274 throw search_graph_exception
00275 ("in search_graph :: remove (...) : search_node has several ancestors");
00276 _internal_remove(where);
00277 }
00278
00279 search_focus& search_graph::promote(search_focus& where)
00280 {
00281 list<walker>::iterator i = find(focus.begin(), focus.end(), where);
00282 if(i == focus.end())
00283 throw search_graph_exception
00284 ("in search_graph :: promote (...) : the focus does not exist");
00285 if(where.n_parents() >= 2)
00286 throw search_graph_exception
00287 ("in search_graph :: promote (...) : search_node has several ancestors");
00288 walker p = where << where.parent_begin();
00289
00290 if((*where)->is_delta())
00291 {
00292 delta_node *where_as_delta = (delta_node*) *where;
00293
00294 if((*p)->is_delta())
00295 {
00296 delta_node* p_as_delta = (delta_node*) *p;
00297
00298 vector<delta_id> delta_where_plus_delta_p;
00299 for(unsigned int i = 0; i < where_as_delta->n_deltas(); ++i)
00300 {
00301 db_deltas_to_remove.push_front(where_as_delta->get_delta_id(i));
00302 delta_where_plus_delta_p.push_back(db_deltas_to_remove.front());
00303 }
00304 for(unsigned int i = 0; i < p_as_delta->n_deltas(); ++i)
00305 {
00306 db_deltas_to_remove.push_front(p_as_delta->get_delta_id(i));
00307 delta_where_plus_delta_p.push_back(db_deltas_to_remove.front());
00308 }
00309 gptr<vdbl::database>* _xdb = p_as_delta->database();
00310 delete *p;
00311 for(list<search_node*>::iterator i=search_nodes_to_deallocate.begin();
00312 i != search_nodes_to_deallocate.end(); ++i)
00313 if(*p == *i)
00314 {
00315 search_nodes_to_deallocate.erase(i);
00316 break;
00317 }
00318
00319 *p = new delta_node(get_node_id(), __dbuser, delta_where_plus_delta_p,
00320 ptr_ground, *_xdb);
00321 }
00322 else
00323 {
00324 full_node *p_as_full = (full_node*) *p;
00325 work_node full_p_plus_delta_where(full_node_to_work_node
00326 (*p_as_full, ptr_ground));
00327
00328 for(unsigned int i = 0; i < where_as_delta->n_deltas(); ++i)
00329 full_p_plus_delta_where += where_as_delta->get_delta_id(i);
00330 delete *p;
00331 for(list<search_node*>::iterator i=search_nodes_to_deallocate.begin();
00332 i != search_nodes_to_deallocate.end(); ++i)
00333 if(*p == *i)
00334 {
00335 search_nodes_to_deallocate.erase(i);
00336 break;
00337 }
00338
00339 *p = new work_node(full_p_plus_delta_where);
00340 }
00341 search_nodes_to_deallocate.push_front(*p);
00342 }
00343 else
00344 {
00345 delete *p;
00346 for(list<search_node*>::iterator i=search_nodes_to_deallocate.begin();
00347 i != search_nodes_to_deallocate.end(); ++i)
00348 if(*p == *i)
00349 {
00350 search_nodes_to_deallocate.erase(i);
00351 break;
00352 }
00353
00354 *p = *where;
00355 }
00356 *i = p;
00357 delete *where;
00358 for(list<search_node*>::iterator i=search_nodes_to_deallocate.begin();
00359 i != search_nodes_to_deallocate.end(); ++i)
00360 if(*where == *i)
00361 {
00362 search_nodes_to_deallocate.erase(i);
00363 break;
00364 }
00365
00366 erase(where);
00367 return *i;
00368 }
00369
00370 void search_graph::remove_upwards(search_focus& where, bool relaxation_kills)
00371 {
00372 list<walker>::iterator flw = find(focus.begin(), focus.end(), where);
00373 if(flw == focus.end())
00374 throw search_graph_exception
00375 ("in search_graph :: remove_upwards (...) : the focus does not exist");
00376 if(where.n_parents() >= 2 && (*where)->parent_relation() != snr_glue)
00377 throw search_graph_exception
00378 ("in search_graph :: remove_upwards (...) : search_node has several ancestors");
00379
00380 list<walker> to_be_erased;
00381 to_be_erased.push_front(*flw);
00382
00383 for(flw = to_be_erased.begin(); flw != to_be_erased.end(); ++flw)
00384 {
00385 switch((**flw)->parent_relation())
00386 {
00387 case snr_root:
00388
00389 break;
00390 case snr_split:
00391
00392 break;
00393 case snr_relaxation:
00394 if(!relaxation_kills)
00395 break;
00396
00397 case snr_reduction:
00398 case snr_glue:
00399
00400 for(walker::parents_iterator p = (*flw).parent_begin();
00401 p != (*flw).parent_end(); ++p)
00402 to_be_erased.push_back((*flw) << p);
00403 break;
00404 case snr_worknode:
00405 case snr_virtual:
00406 throw search_graph_exception
00407 ("in search_graph :: remove_upwards (...) : search_node is unremovable!");
00408 break;
00409 default:
00410 throw search_graph_exception
00411 ("in search_graph :: remove_upwards (...) : search_node has unknown parent relation!");
00412 break;
00413 }
00414 _internal_remove(*flw);
00415 }
00416 }
00417