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 "projectiontreenode.h"
00036
00037 ProjectionTreeNode::ProjectionTreeNode(ProjectionTreeNode * _parent, int _var,
00038 PathExpression * _path, bool _dep,
00039 Role * _role,
00040 bool _direct_output):parent(_parent),
00041 var(_var),
00042 path(_path),
00043 dep(_dep),
00044 role(_role),
00045 direct_output(_direct_output) {
00046 }
00047
00048 ProjectionTreeNode::~ProjectionTreeNode() {
00049 for (unsigned i = 0; i < children.size(); i++) {
00050 delete children[i];
00051 }
00052 }
00053
00054 bool ProjectionTreeNode::insertNode(int parent_var, int introduced_var,
00055 PathExpression * path, bool dep,
00056 Role * role, bool direct_output) {
00057
00058 if (parent_var == var) {
00059 ProjectionTreeNode *child =
00060 new ProjectionTreeNode(this, introduced_var, path, dep, role,
00061 direct_output);
00062
00063 children.push_back(child);
00064
00065 return true;
00066 } else {
00067 bool created = false;
00068
00069 for (unsigned i = 0; i < children.size() && !created; i++) {
00070 created =
00071 children[i]->insertNode(parent_var, introduced_var, path, dep,
00072 role, direct_output);
00073 }
00074
00075 return created;
00076 }
00077 }
00078
00079 void ProjectionTreeNode::print(OutputStream & dos) {
00080 print(dos, 0);
00081 dos << resetIndents();
00082 }
00083
00084 PathExpression *ProjectionTreeNode::getRootPath() {
00085 vector < PathExpression * >paths;
00086 getPathsFromRoot(paths);
00087
00088 PathExpression *r = new PathExpression();
00089
00090 for (unsigned i = 0; i < paths.size(); i++) {
00091 PathExpression *cur = paths[i];
00092
00093 if (cur && !cur->isEmptyPath()) {
00094 for (unsigned i = 0; i < cur->getPathSize(); i++) {
00095 r->addPathStep(cur->getPathStepAt(i)->clone());
00096 }
00097 }
00098 }
00099
00100 return r;
00101 }
00102
00103 void ProjectionTreeNode::getPathsFromRoot(vector < PathExpression * >&paths) {
00104 if (parent) {
00105 parent->getPathsFromRoot(paths);
00106 }
00107 paths.push_back(path);
00108 }
00109
00110 void ProjectionTreeNode::removeUnneededNodes(PassiveProjectionTree * ppt) {
00111 for (unsigned i = 0; i < children.size(); i++) {
00112 if (children[i]->getPath()) {
00113 if (children[i]->getPath()->hasInnerTextNodeTest() &&
00114 !children[i]->getPath()->getPathStepAfterTextNodeTest()->
00115 isDosNodeStep()) {
00116 children[i]->removeSubtreeInclSelf(ppt);
00117 i--;
00118 } else if (children[i]->getPath()->hasTerminatingTextNodeTest()) {
00119 children[i]->removeSubtreeExclSelf(ppt);
00120 } else {
00121 children[i]->removeUnneededNodes(ppt);
00122 }
00123 } else {
00124 children[i]->removeUnneededNodes(ppt);
00125 }
00126 }
00127 }
00128
00129 void ProjectionTreeNode::removeRedundantRoles(PassiveProjectionTree * ppt) {
00130 if (children.size() > 0 && !direct_output) {
00131 setRedundantRoleSelf();
00132 } else if (dep && isDosDepNode() && parent) {
00133 vector < ProjectionTreeNode * >*siblings = parent->getChildren();
00134
00135
00136
00137 bool perform_check = false;
00138
00139 for (unsigned i = 0; i < siblings->size(); i++) {
00140 if (!(*siblings)[i]->isDepNode()) {
00141 perform_check = true;
00142 break;
00143 }
00144 }
00145
00146
00147
00148
00149
00150 if (perform_check && parent->getVar() >= TAGID_ROOT) {
00151 for (unsigned i = 0; i < siblings->size(); i++) {
00152 if ((*siblings)[i] != this && !(*siblings)[i]->isDepNode()
00153 && ((*siblings)[i]->getPath()
00154 && (*siblings)[i]->getPath()->
00155 isSemanticallyContainedIn(path))
00156 || !(*siblings)[i]->getPath()) {
00157 if (!(*siblings)[i]->getPath()) {
00158 if (path->getPathSize() == 1
00159 && path->getTailPathStep()->isDosNodeStep()) {
00160 (*siblings)[i]->removeSubtreeInclSelf(ppt);
00161 siblings = parent->getChildren();
00162 i--;
00163 }
00164 } else {
00165 (*siblings)[i]->removeSubtreeInclSelf(ppt);
00166 siblings = parent->getChildren();
00167 i--;
00168 }
00169 }
00170 }
00171 }
00172 }
00173
00174 for (unsigned i = 0; i < children.size(); i++) {
00175 children[i]->removeRedundantRoles(ppt);
00176 }
00177 }
00178
00179 void ProjectionTreeNode::
00180 registerToPassiveProjectionTree(PassiveProjectionTree * ppt) {
00181 PathExpression *root_to_cur = getRootPath();
00182
00183 ppt->registerPath(root_to_cur);
00184 delete root_to_cur;
00185 }
00186
00187 void ProjectionTreeNode::print(OutputStream & dos, unsigned indents) {
00188 dos << resetIndents() << incrementIndents(indents);
00189 dos << writeIndents();
00190 if (var > -1) {
00191 dos << "($" << VarName::getInstance()->getVarname(var) << ") => ";
00192 }
00193
00194 if (path) {
00195 dos << *(path);
00196 } else {
00197 dos << "%/%";
00198 }
00199
00200 if (role) {
00201 dos << " (r" << role->getId() << ",";
00202 switch (role->getType()) {
00203 case rt_root:
00204 dos << "root";
00205 break;
00206 case rt_variable:
00207 dos << "var";
00208 break;
00209 case rt_condition:
00210 dos << "cond";
00211 break;
00212 case rt_output:
00213 dos << "out";
00214 break;
00215 }
00216 dos << ",$" << VarName::getInstance()->getVarname(role->getBasingVar())
00217 << ",$" << VarName::getInstance()->getVarname(role->
00218 getBasingFSA()) <<
00219 ")";
00220 } else {
00221 dos << " <= redundant role/node";
00222 }
00223
00224 if (direct_output) {
00225 dos << " *";
00226 }
00227 dos << NEWLINE;
00228
00229 for (unsigned i = 0; i < children.size(); i++) {
00230 children[i]->print(dos, indents + 1);
00231 }
00232 }
00233
00234 void ProjectionTreeNode::removeSubtreeInclSelf(PassiveProjectionTree * ppt) {
00235 removeSubtreeExclSelf(ppt);
00236
00237 if (parent) {
00238 vector < ProjectionTreeNode * >*siblings = parent->getChildren();
00239 for (unsigned i = 0; i < siblings->size(); i++) {
00240 if ((*siblings)[i] == this) {
00241 if (!(*siblings)[i]->getRole() ||
00242 RoleList::getInstance()->removeRole((*siblings)[i]->
00243 getRole())) {
00244 (*siblings)[i]->registerToPassiveProjectionTree(ppt);
00245 delete(*siblings)[i];
00246 siblings->erase(siblings->begin() + i);
00247 }
00248 }
00249 }
00250 } else {
00251 if (!role || RoleList::getInstance()->removeRole(role)) {
00252 this->registerToPassiveProjectionTree(ppt);
00253 delete this;
00254 }
00255 }
00256 }
00257
00258 void ProjectionTreeNode::removeSubtreeExclSelf(PassiveProjectionTree * ppt) {
00259 for (unsigned i = 0; i < children.size(); i++) {
00260 if (!children[i]->getRole()
00261 || RoleList::getInstance()->removeRole(children[i]->getRole())) {
00262 children[i]->removeSubtreeExclSelf(ppt);
00263 if (children.size() > 0) {
00264 children[i]->registerToPassiveProjectionTree(ppt);
00265 delete children[i];
00266
00267 children.erase(children.begin() + i);
00268 i--;
00269 }
00270 }
00271 }
00272 }
00273
00274 void ProjectionTreeNode::setRedundantRoleSelf() {
00275 if (!role || RoleList::getInstance()->removeRole(role)) {
00276 role = NULL;
00277 }
00278 }