1 #include "word-tag.hpp"
2 #include "fast-sprintf.hpp"
3
4 extern "C" {
5 #ifdef DEBUG
6 #include "prepare/build-disjuncts.h" // prt_exp_mem()
7 #endif
8 #include "error.h"
9 #include "tokenize/tok-structures.h"
10 #include "utilities.h"
11 }
12
13 #define D_IC 8
insert_connectors(Exp * exp,int & dfs_position,bool & leading_right,bool & leading_left,std::vector<int> & eps_right,std::vector<int> & eps_left,char * var,bool root,double parent_cost,Exp * parent_exp,const X_node * word_xnode)14 void WordTag::insert_connectors(Exp* exp, int& dfs_position,
15 bool& leading_right, bool& leading_left,
16 std::vector<int>& eps_right,
17 std::vector<int>& eps_left,
18 char* var, bool root, double parent_cost,
19 Exp* parent_exp, const X_node *word_xnode)
20 {
21 double cost = parent_cost + exp->cost;
22
23 #ifdef DEBUG
24 if (0 && verbosity_level(+D_IC)) // Extreme debug
25 //if (_word == 2)
26 {
27 const char*type =
28 ((const char *[]) {"OR_type", "AND_type", "CONNECTOR_type"}) [exp->type-1];
29 printf("Expression type %s for Word%d, var %s:\n", type, _word, var);
30 //printf("parent_exp: %s\n", lg_exp_stringify(parent_exp));
31 printf("exp(%s) e=%.2f pc=%.2f %s\n",
32 word_xnode->string,exp->cost, parent_cost, lg_exp_stringify(exp));
33 if (exp->cost > 0 || root) prt_exp_mem(exp, 0);
34 }
35 #endif
36
37 if (exp->type == CONNECTOR_type) {
38 dfs_position++;
39
40 switch (exp->dir) {
41 case '+':
42 _position.push_back(_right_connectors.size());
43 _dir.push_back('+');
44 _right_connectors.push_back(
45 PositionConnector(parent_exp, exp, '+', _word, dfs_position,
46 cost, parent_cost, leading_right, false,
47 eps_right, eps_left, word_xnode, _opts));
48 leading_right = false;
49 break;
50 case '-':
51 _position.push_back(_left_connectors.size());
52 _dir.push_back('-');
53 _left_connectors.push_back(
54 PositionConnector(parent_exp, exp, '-', _word, dfs_position,
55 cost, parent_cost, false, leading_left,
56 eps_right, eps_left, word_xnode, _opts));
57 leading_left = false;
58 break;
59 default:
60 throw std::string("Unknown connector direction: ") + exp->dir;
61 }
62 } else if (exp->type == AND_type) {
63 if (exp->operand_first == NULL) {
64 /* zeroary and */
65 if (cost != 0)
66 {
67 lgdebug(+D_IC, "EmptyConnector var=%s(%d) cost %.2f pcost %.2f\n",
68 var, _variables->string(var), cost, parent_cost);
69 _empty_connectors.push_back(EmptyConnector(_variables->string(var),cost));
70 }
71 } else
72 if (exp->operand_first->operand_next == NULL) {
73 /* unary and - skip */
74 insert_connectors(exp->operand_first, dfs_position, leading_right,
75 leading_left, eps_right, eps_left, var, root, cost, parent_exp, word_xnode);
76 } else {
77 int i;
78 Exp* opd;
79
80 char new_var[MAX_VARIABLE_NAME];
81 char* last_new_var = new_var;
82 char* last_var = var;
83 while ((*last_new_var = *last_var)) {
84 last_new_var++;
85 last_var++;
86 }
87
88 for (i = 0, opd = exp->operand_first; opd != NULL; opd = opd->operand_next, i++) {
89 char* s = last_new_var;
90 *s++ = 'c';
91 fast_sprintf(s, i);
92
93 double and_cost = (i == 0) ? cost : 0;
94 insert_connectors(opd, dfs_position, leading_right, leading_left,
95 eps_right, eps_left, new_var, false, and_cost, parent_exp, word_xnode);
96
97 if (leading_right) {
98 eps_right.push_back(_variables->epsilon(new_var, '+'));
99 }
100 if (leading_left) {
101 eps_left.push_back(_variables->epsilon(new_var, '-'));
102 }
103 }
104 }
105 } else if (exp->type == OR_type) {
106 if (exp->operand_first != NULL && exp->operand_first->operand_next == NULL) {
107 /* unary or - skip */
108 insert_connectors(exp->operand_first, dfs_position, leading_right, leading_left,
109 eps_right, eps_left, var, root, cost, exp->operand_first, word_xnode);
110 } else {
111 int i;
112 Exp* opd;
113 bool ll_true = false;
114 bool lr_true = false;
115
116 char new_var[MAX_VARIABLE_NAME];
117 char* last_new_var = new_var;
118 char* last_var = var;
119 while ((*last_new_var = *last_var)) {
120 last_new_var++;
121 last_var++;
122 }
123
124 #ifdef DEBUG
125 if (0 && verbosity_level(+D_IC)) { // Extreme debug
126 printf("Word%d, var %s OR_type:\n", _word, var);
127 printf("exp mem: "); prt_exp_mem(exp, 0);
128 }
129 #endif
130
131 for (i = 0, opd = exp->operand_first; opd != NULL; opd = opd->operand_next, i++) {
132 bool lr = leading_right, ll = leading_left;
133 std::vector<int> er = eps_right, el = eps_left;
134
135 char* s = last_new_var;
136 *s++ = 'd';
137 fast_sprintf(s, i);
138
139 assert(word_xnode != NULL, "NULL X_node for var %s", new_var);
140 if (root)
141 {
142 lgdebug(+D_IC, "Word%d: var: %s; exp%d=%p; X_node: %s\n",
143 _word, new_var, i, opd, word_xnode->word->subword);
144 }
145
146 insert_connectors(opd, dfs_position, lr, ll, er, el, new_var, false, cost, opd, word_xnode);
147
148 /* For the toplevel X_node-joined OR_type, get the next X_node. */
149 if (root && (word_xnode->next != NULL))
150 word_xnode = word_xnode->next;
151
152 if (lr)
153 lr_true = true;
154 if (ll)
155 ll_true = true;
156 }
157 leading_right = lr_true;
158 leading_left = ll_true;
159 }
160 }
161 }
162 #undef D_IC
163
find_matches(int w,Connector * search_cntr,char dir,std::vector<PositionConnector * > & matches)164 void WordTag::find_matches(int w, Connector* search_cntr, char dir, std::vector<PositionConnector*>& matches)
165 {
166 // cout << "Look connection on: ." << _word << ". ." << w << ". " << connector_string(search_cntr) << dir << endl;
167
168 std::vector<PositionConnector>* connectors;
169 switch(dir) {
170 case '+':
171 connectors = &_left_connectors;
172 break;
173 case '-':
174 connectors = &_right_connectors;
175 break;
176 default:
177 throw std::string("Unknown connector direction: ") + dir;
178 }
179
180 std::vector<PositionConnector>::iterator i;
181 for (i = connectors->begin(); i != connectors->end(); i++) {
182 if (WordTag::match(w, *search_cntr, dir, (*i).word, ((*i).connector))) {
183 matches.push_back(&(*i));
184 }
185 }
186 }
187
add_matches_with_word(WordTag & tag)188 void WordTag::add_matches_with_word(WordTag& tag)
189 {
190 std::vector<PositionConnector>::iterator i;
191 for (i = _right_connectors.begin(); i != _right_connectors.end(); i++) {
192 std::vector<PositionConnector*> connector_matches;
193 tag.find_matches(_word, &(*i).connector, '+', connector_matches);
194 std::vector<PositionConnector*>::iterator j;
195 for (j = connector_matches.begin(); j != connector_matches.end(); j++) {
196 i->matches.push_back(*j);
197 set_match_possible((*j)->word, (*j)->position);
198 (*j)->matches.push_back(&(*i));
199 tag.set_match_possible(_word, (*i).position);
200 }
201 }
202 }
203