2 * Copyright (C) 2005 Universitat d'Alacant / Universidad de Alicante
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 #include <lttoolbox/Transducer.H>
20 #include <lttoolbox/Compression.H>
21 #include <lttoolbox/MyStdio.H>
22 #include <lttoolbox/Utility.H>
30 Transducer::newState()
32 int nstate = transitions.size();
34 while(transitions.find(nstate) != transitions.end())
38 transitions[nstate].clear(); // force creating
43 Transducer::Transducer()
48 Transducer::~Transducer()
53 Transducer::Transducer(Transducer const &t)
59 Transducer::operator =(Transducer const &t)
70 Transducer::insertSingleTransduction(int const tag, int const source)
72 if(transitions.find(source) != transitions.end())
74 if(transitions[source].count(tag) == 1)
76 pair<multimap<int,int>::iterator, multimap<int,int>::iterator > range;
77 range = transitions[source].equal_range(tag);
78 return range.first->second;
80 else if(transitions[source].count(tag) == 0)
83 int state = newState();
84 transitions[source].insert(pair<int, int>(tag, state));
87 else if(transitions[source].count(tag) == 2)
89 // there's a local cycle, must be ignored and treated like in '1'
90 pair<multimap<int,int>::iterator, multimap<int,int>::iterator> range;
91 range = transitions[source].equal_range(tag);
92 for(; range.first != range.second; range.first++)
94 if(range.first->second != source)
96 return range.first->second;
113 Transducer::insertNewSingleTransduction(int const tag, int const source)
115 int state = newState();
116 transitions[source].insert(pair<int, int>(tag, state));
121 Transducer::insertTransducer(int const source, Transducer &t,
122 int const epsilon_tag)
124 map<int, int> relacion;
126 t.joinFinals(epsilon_tag);
128 for(map<int, multimap<int, int> >::const_iterator it = t.transitions.begin(),
129 limit = t.transitions.end();
132 relacion[it->first] = newState();
135 for(map<int, multimap<int, int> >::const_iterator it = t.transitions.begin();
136 it != t.transitions.end(); it++)
138 for(multimap<int, int>::const_iterator it2 = it->second.begin(),
139 limit2 = (it->second).end();
140 it2 != limit2; it2++)
142 transitions[relacion[it->first]].insert(pair<int, int>(it2->first, relacion[it2->second]));
146 transitions[source].insert(pair<int, int>(epsilon_tag,
147 relacion[t.initial]));
149 return relacion[*(t.finals.begin())];
153 Transducer::linkStates(int const source, int const destino,
157 if(transitions.find(source) != transitions.end() &&
158 transitions.find(destino) != transitions.end())
161 pair<multimap<int, int>::iterator, multimap<int, int>::iterator> range;
162 range = transitions[source].equal_range(etiqueta);
163 for(;range.first != range.second; range.first++)
165 if(range.first->first == etiqueta && range.first->second == destino)
171 transitions[source].insert(pair<int, int>(etiqueta, destino));
175 cerr << "Error: Trying to link nonexistent states (" << source;
176 cerr << ", " << destino << ", " << etiqueta << ")" << endl;
182 Transducer::isFinal(int const state) const
184 return finals.find(state) != finals.end();
188 Transducer::setFinal(int const state, bool valor)
192 finals.insert(state);
201 Transducer::getInitial() const
207 Transducer::closure(int const state, int const epsilon_tag)
209 set<int> nonvisited, result;
211 nonvisited.insert(state);
212 result.insert(state);
214 while(nonvisited.size() > 0)
216 int auxest = *nonvisited.begin();
217 pair<multimap<int, int>::iterator, multimap<int, int>::iterator> rango;
218 rango = transitions[auxest].equal_range(epsilon_tag);
219 while(rango.first != rango.second)
221 if(result.find(rango.first->second) == result.end())
223 result.insert(rango.first->second);
224 nonvisited.insert(rango.first->second);
228 nonvisited.erase(auxest);
235 Transducer::joinFinals(int const epsilon_tag)
237 if(finals.size() > 1)
239 int state = newState();
241 for(set<int>::iterator it = finals.begin(), limit = finals.end();
244 linkStates(*it, state, epsilon_tag);
248 finals.insert(state);
250 else if(finals.size() == 0)
252 cerr << "Error: empty set of final states" <<endl;
258 Transducer::isEmptyIntersection(set<int> const &s1, set<int> const &s2)
261 if(s1.size() < s2.size())
263 for(set<int>::iterator it = s1.begin(), limit = s1.end(); it != limit; it++)
265 if(s2.find(*it) != s2.end())
273 for(set<int>::iterator it = s2.begin(), limit = s2.end(); it != limit; it++)
275 if(s1.find(*it) != s1.end())
286 Transducer::determinize(int const epsilon_tag)
288 vector<set<int> > R(2);
289 map<int, set<int> > Q_prima;
290 map<set<int>, int> Q_prima_inv;
292 map<int, multimap<int, int> > transitions_prima;
294 unsigned int talla_Q_prima = 0;
295 Q_prima[0] = closure(initial, epsilon_tag);
297 Q_prima_inv[Q_prima[0]] = 0;
300 int initial_prima = 0;
301 set<int> finals_prima;
303 if(finals.find(initial) != finals.end())
305 finals_prima.insert(0);
310 while(talla_Q_prima != Q_prima.size())
312 talla_Q_prima = Q_prima.size();
315 for(set<int>::iterator it = R[t].begin(), limit = R[t].end();
318 if(!isEmptyIntersection(Q_prima[*it], finals))
320 finals_prima.insert(*it);
323 map<int, set<int> > mymap;
325 for(set<int>::iterator it2 = Q_prima[*it].begin(),
326 limit2 = Q_prima[*it].end();
327 it2 != limit2; it2++)
329 for(multimap<int, int>::iterator it3 = transitions[*it2].begin(),
330 limit3 = transitions[*it2].end();
331 it3 != limit3; it3++)
333 if(it3->first != epsilon_tag)
335 set<int> c = closure(it3->second, epsilon_tag);
337 for(set<int>::iterator it4 = c.begin(), limit4 = c.end();
338 it4 != limit4; it4++)
340 mymap[it3->first].insert(*it4);
347 for(map<int, set<int> >::iterator it2 = mymap.begin(), limit2 = mymap.end();
348 it2 != limit2; it2++)
350 if(Q_prima_inv.find(it2->second) == Q_prima_inv.end())
352 int etiq = Q_prima.size();
353 Q_prima[etiq] = it2->second;
354 Q_prima_inv[it2->second] = etiq;
355 R[(t+1)%2].insert(Q_prima_inv[it2->second]);
356 transitions_prima[etiq].clear();
358 transitions_prima[*it].insert(pair<int, int>(it2->first, Q_prima_inv[it2->second]));
365 transitions = transitions_prima;
366 finals = finals_prima;
367 initial = initial_prima;
372 Transducer::minimize(int const epsilon_tag)
374 reverse(epsilon_tag);
375 determinize(epsilon_tag);
376 reverse(epsilon_tag);
377 determinize(epsilon_tag);
381 Transducer::optional(int const epsilon_tag)
383 joinFinals(epsilon_tag);
384 int state = newState();
385 linkStates(state, initial, epsilon_tag);
389 linkStates(*finals.begin(), state, epsilon_tag);
391 finals.insert(state);
392 linkStates(initial, state, epsilon_tag);
396 Transducer::oneOrMore(int const epsilon_tag)
398 joinFinals(epsilon_tag);
399 int state = newState();
400 linkStates(state, initial, epsilon_tag);
404 linkStates(*finals.begin(), state, epsilon_tag);
406 finals.insert(state);
407 linkStates(state, initial, epsilon_tag);
411 Transducer::zeroOrMore(int const epsilon_tag)
413 oneOrMore(epsilon_tag);
414 optional(epsilon_tag);
422 initial = newState();
426 Transducer::isEmpty() const
428 return finals.size() == 0 && transitions.size() == 1;
432 Transducer::size() const
434 return transitions.size();
438 Transducer::numberOfTransitions() const
442 for(map<int, multimap<int, int> >::const_iterator it = transitions.begin(),
443 limit = transitions.end();
446 counter += (it->second).size();
453 Transducer::isEmpty(int const state) const
455 map<int, multimap<int, int> >::const_iterator it;
457 it = transitions.find(state);
458 if(it != transitions.end())
460 if((it->second).size() > 0)
470 Transducer::write(FILE *output)
472 Compression::multibyte_write(initial, output);
473 Compression::multibyte_write(finals.size(), output);
475 for(set<int>::iterator it = finals.begin(), limit = finals.end();
478 Compression::multibyte_write(*it - base, output);
482 base = transitions.size();
483 Compression::multibyte_write(base, output);
484 for(map<int, multimap<int, int> >::iterator it = transitions.begin(),
485 limit = transitions.end();
488 Compression::multibyte_write(it->second.size(), output);
490 for(multimap<int, int>::iterator it2 = it->second.begin(),
491 limit2 = it->second.end();
492 it2 != limit2; it2++)
494 Compression::multibyte_write(it2->first-tagbase, output);
495 tagbase = it2->first;
497 if(it2->second >= it->first)
499 Compression::multibyte_write(it2->second-it->first, output);
503 Compression::multibyte_write(it2->second+base-it->first, output);
510 Transducer::read(FILE *input)
514 new_t.initial = Compression::multibyte_read(input);
515 int finals_size = Compression::multibyte_read(input);
518 while(finals_size > 0)
522 base += Compression::multibyte_read(input);
523 new_t.finals.insert(base);
526 base = Compression::multibyte_read(input);
527 int number_of_states = base;
528 int current_state = 0;
529 while(number_of_states > 0)
531 int number_of_local_transitions = Compression::multibyte_read(input);
533 while(number_of_local_transitions > 0)
535 number_of_local_transitions--;
536 int tag = Compression::multibyte_read(input);
537 int state = (current_state + Compression::multibyte_read(input)) % base;
538 if(new_t.transitions.find(state) == new_t.transitions.end())
540 new_t.transitions[state].clear(); // force create
542 new_t.transitions[current_state].insert(pair<int, int>(tag+tagbase, state));
553 Transducer::copy(Transducer const &t)
557 transitions = t.transitions;
561 Transducer::destroy()
566 Transducer::reverse(int const epsilon_tag)
568 joinFinals(epsilon_tag);
570 map<int, multimap<int, int> > temporal;
572 for(map<int, multimap<int, int> >::reverse_iterator it = transitions.rbegin(); it != transitions.rend(); it++)
574 multimap<int, int> aux = it->second;
576 for(multimap<int, int>::iterator it2 = aux.begin(), limit2 = aux.end();
577 it2 != limit2; it2++)
579 if(it2->second >= it->first)
581 transitions[it2->second].insert(pair<int, int>(it2->first, it->first));
585 temporal[it2->second].insert(pair<int, int>(it2->first, it->first));
588 if(temporal.find(it->first) != temporal.end())
590 (it->second).insert(temporal[it->first].begin(), temporal[it->first].end());
591 temporal.erase(it->first);
595 for(map<int, multimap<int, int> >::reverse_iterator it = temporal.rbegin(),
596 limit = temporal.rend();
599 for(multimap<int, int>::iterator it2 = it->second.begin(),
600 limit2 = it->second.end();
601 it2 != limit2; it2++)
603 transitions[it->first].insert(pair<int, int>(it2->first, it2->second));
608 initial = *(finals.begin());