00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00035 #include "tokenconfiguration.h"
00036
00037 TokenConfiguration::TokenConfiguration(ProjectionTree * pt):
00038 parent(NULL), labels(pt->getLabels()) {
00039
00040 for (unsigned i = 0; i < labels->nrOfLabels(); i++) {
00041 active_tokens.push_back(0);
00042 passive_tokens.push_back(0);
00043 }
00044
00045
00046 active_tokens[0] = 1;
00047
00048
00049 vector < unsigned >dos_node_ids;
00050
00051 labels->getAllRecursiveDosNodeSuccessors(0, dos_node_ids);
00052 for (unsigned i = 0; i < dos_node_ids.size(); i++) {
00053 active_tokens[dos_node_ids[i]] = 1;
00054 }
00055 }
00056
00057 TokenConfiguration::TokenConfiguration(TokenConfiguration * _parent)
00058 : parent(_parent), labels(parent->getLabels()),
00059 passive_tokens(parent->getPassiveTokens()) {
00060 for (unsigned i = 0; i < labels->nrOfLabels(); i++) {
00061 active_tokens.push_back(0);
00062 }
00063 }
00064
00065 TokenConfiguration::~TokenConfiguration() {
00066 }
00067
00068 void TokenConfiguration::createRoleList(vector < Role * >&roles,
00069 vector < unsigned >&role_counts) {
00070
00071
00072
00073
00074
00075
00076
00077 for (unsigned i = 0; i < active_tokens.size(); i++) {
00078
00079 ProjectionTreeLabel *cur_label = labels->getLabelById(i);
00080
00081
00082 if (active_tokens[i] && cur_label->atEndOfPath()) {
00083
00084 ProjectionTreeNode *n = cur_label->getProjectionTreeNode();
00085
00086
00087 if (n->getRole()) {
00088 roles.push_back(n->getRole());
00089
00090 unsigned role_count = cur_label->isDosNodeLabel()?
00091 active_tokens[cur_label->getPredecessor()->getId()] :
00092 active_tokens[i];
00093 role_counts.push_back(role_count);
00094 }
00095
00096
00097
00098 vector < ProjectionTreeLabel * >*self_labels =
00099 cur_label->getSelfSuccessors();
00100 for (unsigned j = 0; j < self_labels->size(); j++) {
00101 ProjectionTreeNode *self_n =
00102 (*self_labels)[j]->getProjectionTreeNode();
00103 if (self_n->getRole()) {
00104 roles.push_back(self_n->getRole());
00105 role_counts.push_back(active_tokens[i]);
00106 }
00107 }
00108 }
00109 }
00110 }
00111
00112 TokenConfiguration *TokenConfiguration::applyTag(TAG t) {
00113
00114
00115 TokenConfiguration *new_conf = new TokenConfiguration(this);
00116
00117
00118
00119
00120
00121
00122 vector < ProjectionTreeLabel * >matches;
00123 for (unsigned i = 0; i < active_tokens.size(); i++) {
00124
00125 if (active_tokens[i] || passive_tokens[i]) {
00126
00127 ProjectionTreeLabel *l = labels->getLabelById(i);
00128 ProjectionTreeLabel *sls = l->getSameLevelSuccessor();
00129
00130 vector < ProjectionTreeLabel * >*css = l->getChildSuccessors();
00131
00132
00133 if (sls) {
00134 if ((active_tokens[i] && sls->isChildLabel()
00135 && sls->matchesTag(t)) || (sls->isDescendantLabel()
00136 && sls->matchesTag(t))) {
00137 matches.push_back(sls);
00138 }
00139 }
00140
00141 for (unsigned j = 0; j < css->size(); j++) {
00142 ProjectionTreeLabel *cs = (*css)[j];
00143
00144 if ((active_tokens[i] && cs->isChildLabel()
00145 && cs->matchesTag(t)) || (cs->isDescendantLabel()
00146 && cs->matchesTag(t))) {
00147 matches.push_back(cs);
00148 }
00149 }
00150 }
00151 }
00152
00153
00154
00155
00156 for (unsigned i = 0; i < matches.size(); i++) {
00157 ProjectionTreeLabel *cur = matches[i];
00158
00159 ProjectionTreeLabel *sls = cur->getSameLevelSuccessor();
00160
00161 vector < ProjectionTreeLabel * >*css = cur->getChildSuccessors();
00162
00163 if (sls && sls->isDosNodeLabel())
00164 matches.push_back(sls);
00165 for (unsigned j = 0; j < css->size(); j++) {
00166 ProjectionTreeLabel *cs = (*css)[j];
00167
00168 if (cs->isDosNodeLabel()) {
00169 matches.push_back(cs);
00170 }
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 for (unsigned i = 0; i < matches.size(); i++) {
00181 ProjectionTreeLabel *cur = matches[i];
00182 unsigned id = cur->getId();
00183
00184
00185 if (cur->getPredecessor() == NULL) {
00186 new_conf->setActiveTokens(id, 1);
00187
00188 } else {
00189 unsigned basing_id = 0;
00190
00191
00192
00193 bool is_not_first_descendant_axis = false;
00194 unsigned predecessor_id = cur->getPredecessor()->getId();
00195
00196
00197
00198 if (cur->getPredecessor()->getPath() == cur->getPath()) {
00199 basing_id = cur->getLeftmostSLPredecessor()->getId();
00200
00201
00202
00203 if (labels->getLabelById(basing_id)->getFSALabel()->
00204 getId() == basing_id) {
00205 is_not_first_descendant_axis =
00206 cur->getPredecessor()->descendantAxisBetw(basing_id,
00207 true);
00208 } else {
00209 basing_id =
00210 labels->getLabelById(basing_id)->getFSALabel()->getId();
00211 is_not_first_descendant_axis =
00212 cur->getPredecessor()->descendantAxisBetw(basing_id);
00213 }
00214
00215
00216 } else {
00217 ProjectionTreeLabel *fsa = cur->getFSALabel();
00218
00219
00220
00221
00222 basing_id = cur->getFSALabel() == cur ?
00223 cur->getPredecessor()->getId() : fsa->getId();
00224 is_not_first_descendant_axis = cur->getPredecessor()->
00225 descendantAxisBetw(basing_id);
00226 }
00227
00228 switch (cur->getPathStep()->getAxisType()) {
00229 case at_dos:
00230 is_not_first_descendant_axis ?
00231 new_conf->setActiveTokens(id,
00232 new_conf->
00233 getLastActiveTokenCountFor
00234 (predecessor_id)) :
00235 new_conf->setActiveTokens(id,
00236 new_conf->
00237 sumUpActiveTokenCountFor
00238 (predecessor_id));
00239 break;
00240
00241 case at_descendant:
00242 is_not_first_descendant_axis ?
00243 new_conf->setActiveTokens(id,
00244 getLastActiveTokenCountFor
00245 (predecessor_id)) :
00246 new_conf->setActiveTokens(id,
00247 sumUpActiveTokenCountFor
00248 (predecessor_id));
00249 break;
00250
00251 case at_child:
00252 new_conf->setActiveTokens(id,
00253 getLastActiveTokenCountFor
00254 (predecessor_id));
00255 break;
00256 }
00257 }
00258 }
00259
00260
00261
00262
00263 for (unsigned i = 0; i < active_tokens.size(); i++) {
00264 if (active_tokens[i]) {
00265 ProjectionTreeLabel *cur = labels->getLabelById(i);
00266 ProjectionTreeLabel *sls = cur->getSameLevelSuccessor();
00267
00268 vector < ProjectionTreeLabel * >*css = cur->getChildSuccessors();
00269
00270 bool has_desc_successors = false;
00271
00272 has_desc_successors |= sls && sls->isDosOrDescendantLabel();
00273 for (unsigned j = 0; j < css->size() && !has_desc_successors; j++) {
00274 ProjectionTreeLabel *cs = (*css)[j];
00275
00276 has_desc_successors |= cs->isDosOrDescendantLabel();
00277 }
00278
00279 if (has_desc_successors) {
00280 new_conf->addPassiveTokens(i, active_tokens[i]);
00281 }
00282 }
00283 }
00284
00285
00286
00287 if (new_conf->isEmpty()) {
00288 delete new_conf;
00289
00290 new_conf = NULL;
00291 }
00292
00293 return new_conf;
00294 }
00295
00296 TokenConfiguration *TokenConfiguration::applyText() {
00297
00298
00299 TokenConfiguration *new_conf = new TokenConfiguration(this);
00300
00301
00302
00303
00304
00305
00306 vector < ProjectionTreeLabel * >matches;
00307 for (unsigned i = 0; i < active_tokens.size(); i++) {
00308
00309 if (active_tokens[i] || passive_tokens[i]) {
00310
00311 ProjectionTreeLabel *l = labels->getLabelById(i);
00312 ProjectionTreeLabel *sls = l->getSameLevelSuccessor();
00313
00314 vector < ProjectionTreeLabel * >*css = l->getChildSuccessors();
00315
00316
00317 if (sls) {
00318 if ((active_tokens[i] && sls->isChildLabel()
00319 && sls->matchesText()) || (sls->isDescendantLabel()
00320 && sls->matchesText())) {
00321 matches.push_back(sls);
00322 }
00323 }
00324
00325 for (unsigned j = 0; j < css->size(); j++) {
00326 ProjectionTreeLabel *cs = (*css)[j];
00327
00328 if ((active_tokens[i] && cs->isChildLabel()
00329 && cs->matchesText()) || (cs->isDescendantLabel()
00330 && cs->matchesText())) {
00331 matches.push_back(cs);
00332 }
00333 }
00334 }
00335 }
00336
00337
00338
00339 for (unsigned i = 0; i < matches.size(); i++) {
00340 ProjectionTreeLabel *cur = matches[i];
00341
00342 ProjectionTreeLabel *sls = cur->getSameLevelSuccessor();
00343
00344 vector < ProjectionTreeLabel * >*css = cur->getChildSuccessors();
00345
00346 if (sls && sls->isDosNodeLabel())
00347 matches.push_back(sls);
00348 for (unsigned j = 0; j < css->size(); j++) {
00349 ProjectionTreeLabel *cs = (*css)[j];
00350
00351 if (cs->isDosNodeLabel())
00352 matches.push_back(cs);
00353 }
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 for (unsigned i = 0; i < matches.size(); i++) {
00366 ProjectionTreeLabel *cur = matches[i];
00367 unsigned id = cur->getId();
00368
00369
00370 if (cur->getPredecessor() == NULL) {
00371 new_conf->setActiveTokens(id, 1);
00372
00373 } else {
00374
00375 unsigned basing_id = 0;
00376 bool is_not_first_descendant_axis = false;
00377 unsigned predecessor_id = cur->getPredecessor()->getId();
00378
00379
00380
00381 if (cur->getPredecessor()->getPath() == cur->getPath()) {
00382 basing_id = cur->getLeftmostSLPredecessor()->getId();
00383
00384
00385
00386 if (labels->getLabelById(basing_id)->getFSALabel()->
00387 getId() == basing_id) {
00388 is_not_first_descendant_axis =
00389 cur->getPredecessor()->descendantAxisBetw(basing_id,
00390 true);
00391 } else {
00392 basing_id =
00393 labels->getLabelById(basing_id)->getFSALabel()->getId();
00394 is_not_first_descendant_axis =
00395 cur->getPredecessor()->descendantAxisBetw(basing_id);
00396 }
00397
00398
00399
00400 } else {
00401 ProjectionTreeLabel *fsa = cur->getFSALabel();
00402
00403
00404
00405
00406 basing_id = cur->getFSALabel() == cur ?
00407 cur->getPredecessor()->getId() : fsa->getId();
00408 is_not_first_descendant_axis = cur->getPredecessor()->
00409 descendantAxisBetw(basing_id);
00410 }
00411
00412 switch (cur->getPathStep()->getAxisType()) {
00413 case at_dos:
00414 is_not_first_descendant_axis ?
00415 new_conf->setActiveTokens(id,
00416 new_conf->
00417 getLastActiveTokenCountFor
00418 (predecessor_id)) :
00419 new_conf->setActiveTokens(id,
00420 new_conf->
00421 sumUpActiveTokenCountFor
00422 (predecessor_id));
00423 break;
00424
00425 case at_descendant:
00426 is_not_first_descendant_axis ?
00427 new_conf->setActiveTokens(id,
00428 getLastActiveTokenCountFor
00429 (predecessor_id)) :
00430 new_conf->setActiveTokens(id,
00431 sumUpActiveTokenCountFor
00432 (predecessor_id));
00433 break;
00434
00435 case at_child:
00436 new_conf->setActiveTokens(id,
00437 getLastActiveTokenCountFor
00438 (predecessor_id));
00439 break;
00440 }
00441 }
00442 }
00443
00444
00445
00446
00447
00448
00449 if (!new_conf->hasActiveToken()) {
00450 delete new_conf;
00451
00452 new_conf = NULL;
00453 }
00454
00455 return new_conf;
00456 }
00457
00458 void TokenConfiguration::print(OutputStream & dos, bool is_text) {
00459 dos << "[";
00460 for (unsigned i = 0; i < active_tokens.size(); i++) {
00461 if (i > 0)
00462 dos << ",";
00463 dos << active_tokens[i];
00464 }
00465 dos << "]";
00466 if (!is_text) {
00467 dos << " - prev=[";
00468 for (unsigned i = 0; i < passive_tokens.size(); i++) {
00469 if (i > 0)
00470 dos << ",";
00471 dos << passive_tokens[i];
00472 }
00473 dos << "]";
00474 }
00475 }
00476
00477 unsigned TokenConfiguration::getLastActiveTokenCountFor(unsigned token_id) {
00478
00479 if (active_tokens[token_id]) {
00480 return active_tokens[token_id];
00481 } else if (parent != NULL) {
00482 return parent->getLastActiveTokenCountFor(token_id);
00483 } else {
00484 throw RuntimeException("TokenConfiguration: Illegal Configuration",
00485 eid_runtime_tokenconfig);
00486 }
00487
00488 return 0;
00489 }
00490
00491 bool TokenConfiguration::isEmpty() {
00492 for (unsigned i = 0; i < active_tokens.size(); i++) {
00493 if (active_tokens[i] + passive_tokens[i])
00494 return false;
00495 }
00496 return true;
00497 }
00498
00499 bool TokenConfiguration::isOutput() {
00500
00501
00502
00503 for (unsigned i = 0; i < active_tokens.size(); i++) {
00504 if (active_tokens[i] && labels->getLabelById(i)->isDosNodeLabel())
00505 return true;
00506 }
00507
00508 return false;
00509 }
00510
00511 bool TokenConfiguration::hasActiveToken() {
00512 for (unsigned i = 0; i < active_tokens.size(); i++) {
00513 if (active_tokens[i])
00514 return true;
00515 }
00516 return false;
00517 }
00518
00519 unsigned TokenConfiguration::sumUpActiveTokenCountFor(unsigned token_id) {
00520 if (parent) {
00521 return parent->sumUpActiveTokenCountFor(token_id) +
00522 active_tokens[token_id];
00523 } else {
00524 return active_tokens[token_id];
00525 }
00526 }
00527
00528 bool TokenConfiguration::forceChildKeep() {
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 vector < TAG >child_tags;
00546 bool child_contains_star_or_node = false;
00547
00548 vector < TAG >descendant_tags;
00549 bool descendant_contains_star_or_node = false;
00550
00551 for (unsigned i = 0; i < active_tokens.size(); i++) {
00552 if (active_tokens[i] + passive_tokens[i]) {
00553 ProjectionTreeLabel *cur = labels->getLabelById(i);
00554 ProjectionTreeLabel *sls = cur->getSameLevelSuccessor();
00555
00556 vector < ProjectionTreeLabel * >*css = cur->getChildSuccessors();
00557
00558 if (sls) {
00559 if (active_tokens[i] && sls->isChildLabel()) {
00560 if (sls->isNodeLabel() || sls->isStarLabel()) {
00561 child_contains_star_or_node = true;
00562 } else if (!sls->matchesText()) {
00563 child_tags.push_back(sls->getTag());
00564 }
00565 } else if (sls->isDescendantLabel()) {
00566 if (sls->isNodeLabel() || sls->isStarLabel()) {
00567 descendant_contains_star_or_node = true;
00568 } else if (!sls->matchesText()) {
00569 descendant_tags.push_back(sls->getTag());
00570 }
00571 }
00572 }
00573
00574 for (unsigned j = 0; j < css->size(); j++) {
00575 ProjectionTreeLabel *cs = (*css)[j];
00576
00577 if (active_tokens[i] && cs->isChildLabel()) {
00578 if (cs->isNodeLabel() || cs->isStarLabel()) {
00579 child_contains_star_or_node = true;
00580 } else if (!cs->matchesText()) {
00581 child_tags.push_back(cs->getTag());
00582 }
00583 } else if (cs->isDescendantLabel()) {
00584 if (cs->isNodeLabel() || cs->isStarLabel()) {
00585 descendant_contains_star_or_node = true;
00586 } else if (!cs->matchesText()) {
00587 descendant_tags.push_back(cs->getTag());
00588 }
00589 }
00590 }
00591 }
00592 }
00593
00594
00595 if (child_contains_star_or_node && descendant_contains_star_or_node) {
00596 return true;
00597 }
00598 if (child_contains_star_or_node && descendant_tags.size() > 0) {
00599 return true;
00600 }
00601 if (descendant_contains_star_or_node && child_tags.size() > 0) {
00602 return true;
00603 }
00604 for (unsigned i = 0; i < child_tags.size(); i++) {
00605 for (unsigned j = 0; j < descendant_tags.size(); j++) {
00606 if (child_tags[i] == descendant_tags[j]) {
00607 return true;
00608 }
00609 }
00610 }
00611
00612 return false;
00613 }
00614
00615 bool TokenConfiguration::keepSubtree() {
00616
00617
00618
00619
00620 bool witness = false;
00621
00622 for (unsigned i = 0; i < active_tokens.size(); i++) {
00623 if (active_tokens[i] || passive_tokens[i]) {
00624 if (labels->getLabelById(i)->isDosNodeLabel()) {
00625 witness = true;
00626 } else {
00627 return false;
00628 }
00629 }
00630 }
00631
00632 return witness;
00633 }
00634
00635 bool TokenConfiguration::skipSubtree() {
00636 return isEmpty();
00637 }