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/my_stdio.h>
29 Transducer::newState()
31 int nstate
= transitions
.size();
33 while(transitions
.find(nstate
) != transitions
.end())
37 transitions
[nstate
].clear(); // force creating
42 Transducer::Transducer()
47 Transducer::~Transducer()
52 Transducer::Transducer(Transducer
const &t
)
58 Transducer::operator =(Transducer
const &t
)
69 Transducer::insertSingleTransduction(int const tag
, int const source
)
71 if(transitions
.find(source
) != transitions
.end())
73 if(transitions
[source
].count(tag
) == 1)
75 pair
<multimap
<int,int>::iterator
, multimap
<int,int>::iterator
> range
;
76 range
= transitions
[source
].equal_range(tag
);
77 return range
.first
->second
;
79 else if(transitions
[source
].count(tag
) == 0)
82 int state
= newState();
83 transitions
[source
].insert(pair
<int, int>(tag
, state
));
86 else if(transitions
[source
].count(tag
) == 2)
88 // there's a local cycle, must be ignored and treated like in '1'
89 pair
<multimap
<int,int>::iterator
, multimap
<int,int>::iterator
> range
;
90 range
= transitions
[source
].equal_range(tag
);
91 for(; range
.first
!= range
.second
; range
.first
++)
93 if(range
.first
->second
!= source
)
95 return range
.first
->second
;
112 Transducer::insertNewSingleTransduction(int const tag
, int const source
)
114 int state
= newState();
115 transitions
[source
].insert(pair
<int, int>(tag
, state
));
120 Transducer::insertTransducer(int const source
, Transducer
&t
,
121 int const epsilon_tag
)
123 map
<int, int> relacion
;
125 t
.joinFinals(epsilon_tag
);
127 for(map
<int, multimap
<int, int> >::const_iterator it
= t
.transitions
.begin(),
128 limit
= t
.transitions
.end();
131 relacion
[it
->first
] = newState();
134 for(map
<int, multimap
<int, int> >::const_iterator it
= t
.transitions
.begin();
135 it
!= t
.transitions
.end(); it
++)
137 for(multimap
<int, int>::const_iterator it2
= it
->second
.begin(),
138 limit2
= (it
->second
).end();
139 it2
!= limit2
; it2
++)
141 transitions
[relacion
[it
->first
]].insert(pair
<int, int>(it2
->first
, relacion
[it2
->second
]));
145 transitions
[source
].insert(pair
<int, int>(epsilon_tag
,
146 relacion
[t
.initial
]));
148 return relacion
[*(t
.finals
.begin())];
152 Transducer::linkStates(int const source
, int const destino
,
156 if(transitions
.find(source
) != transitions
.end() &&
157 transitions
.find(destino
) != transitions
.end())
160 pair
<multimap
<int, int>::iterator
, multimap
<int, int>::iterator
> range
;
161 range
= transitions
[source
].equal_range(etiqueta
);
162 for(;range
.first
!= range
.second
; range
.first
++)
164 if(range
.first
->first
== etiqueta
&& range
.first
->second
== destino
)
170 transitions
[source
].insert(pair
<int, int>(etiqueta
, destino
));
174 cerr
<< "Error: Trying to link nonexistent states (" << source
;
175 cerr
<< ", " << destino
<< ", " << etiqueta
<< ")" << endl
;
181 Transducer::isFinal(int const state
) const
183 return finals
.find(state
) != finals
.end();
187 Transducer::setFinal(int const state
, bool valor
)
191 finals
.insert(state
);
200 Transducer::getInitial() const
206 Transducer::closure(int const state
, int const epsilon_tag
)
208 set
<int> nonvisited
, result
;
210 nonvisited
.insert(state
);
211 result
.insert(state
);
213 while(nonvisited
.size() > 0)
215 int auxest
= *nonvisited
.begin();
216 pair
<multimap
<int, int>::iterator
, multimap
<int, int>::iterator
> rango
;
217 rango
= transitions
[auxest
].equal_range(epsilon_tag
);
218 while(rango
.first
!= rango
.second
)
220 if(result
.find(rango
.first
->second
) == result
.end())
222 result
.insert(rango
.first
->second
);
223 nonvisited
.insert(rango
.first
->second
);
227 nonvisited
.erase(auxest
);
234 Transducer::joinFinals(int const epsilon_tag
)
236 if(finals
.size() > 1)
238 int state
= newState();
240 for(set
<int>::iterator it
= finals
.begin(), limit
= finals
.end();
243 linkStates(*it
, state
, epsilon_tag
);
247 finals
.insert(state
);
249 else if(finals
.size() == 0)
251 cerr
<< "Error: empty set of final states" <<endl
;
257 Transducer::isEmptyIntersection(set
<int> const &s1
, set
<int> const &s2
)
260 if(s1
.size() < s2
.size())
262 for(set
<int>::const_iterator it
= s1
.begin(), limit
= s1
.end(); it
!= limit
; it
++)
264 if(s2
.find(*it
) != s2
.end())
272 for(set
<int>::const_iterator it
= s2
.begin(), limit
= s2
.end(); it
!= limit
; it
++)
274 if(s1
.find(*it
) != s1
.end())
285 Transducer::determinize(int const epsilon_tag
)
287 vector
<set
<int> > R(2);
288 map
<int, set
<int> > Q_prima
;
289 map
<set
<int>, int> Q_prima_inv
;
291 map
<int, multimap
<int, int> > transitions_prima
;
293 unsigned int talla_Q_prima
= 0;
294 Q_prima
[0] = closure(initial
, epsilon_tag
);
296 Q_prima_inv
[Q_prima
[0]] = 0;
299 int initial_prima
= 0;
300 set
<int> finals_prima
;
302 if(finals
.find(initial
) != finals
.end())
304 finals_prima
.insert(0);
309 while(talla_Q_prima
!= Q_prima
.size())
311 talla_Q_prima
= Q_prima
.size();
314 for(set
<int>::iterator it
= R
[t
].begin(), limit
= R
[t
].end();
317 if(!isEmptyIntersection(Q_prima
[*it
], finals
))
319 finals_prima
.insert(*it
);
322 map
<int, set
<int> > mymap
;
324 for(set
<int>::iterator it2
= Q_prima
[*it
].begin(),
325 limit2
= Q_prima
[*it
].end();
326 it2
!= limit2
; it2
++)
328 for(multimap
<int, int>::iterator it3
= transitions
[*it2
].begin(),
329 limit3
= transitions
[*it2
].end();
330 it3
!= limit3
; it3
++)
332 if(it3
->first
!= epsilon_tag
)
334 set
<int> c
= closure(it3
->second
, epsilon_tag
);
336 for(set
<int>::iterator it4
= c
.begin(), limit4
= c
.end();
337 it4
!= limit4
; it4
++)
339 mymap
[it3
->first
].insert(*it4
);
346 for(map
<int, set
<int> >::iterator it2
= mymap
.begin(), limit2
= mymap
.end();
347 it2
!= limit2
; it2
++)
349 if(Q_prima_inv
.find(it2
->second
) == Q_prima_inv
.end())
351 int etiq
= Q_prima
.size();
352 Q_prima
[etiq
] = it2
->second
;
353 Q_prima_inv
[it2
->second
] = etiq
;
354 R
[(t
+1)%2].insert(Q_prima_inv
[it2
->second
]);
355 transitions_prima
[etiq
].clear();
357 transitions_prima
[*it
].insert(pair
<int, int>(it2
->first
, Q_prima_inv
[it2
->second
]));
364 transitions
= transitions_prima
;
365 finals
= finals_prima
;
366 initial
= initial_prima
;
371 Transducer::minimize(int const epsilon_tag
)
373 reverse(epsilon_tag
);
374 determinize(epsilon_tag
);
375 reverse(epsilon_tag
);
376 determinize(epsilon_tag
);
380 Transducer::optional(int const epsilon_tag
)
382 joinFinals(epsilon_tag
);
383 int state
= newState();
384 linkStates(state
, initial
, epsilon_tag
);
388 linkStates(*finals
.begin(), state
, epsilon_tag
);
390 finals
.insert(state
);
391 linkStates(initial
, state
, epsilon_tag
);
395 Transducer::oneOrMore(int const epsilon_tag
)
397 joinFinals(epsilon_tag
);
398 int state
= newState();
399 linkStates(state
, initial
, epsilon_tag
);
403 linkStates(*finals
.begin(), state
, epsilon_tag
);
405 finals
.insert(state
);
406 linkStates(state
, initial
, epsilon_tag
);
410 Transducer::zeroOrMore(int const epsilon_tag
)
412 oneOrMore(epsilon_tag
);
413 optional(epsilon_tag
);
421 initial
= newState();
425 Transducer::isEmpty() const
427 return finals
.size() == 0 && transitions
.size() == 1;
431 Transducer::size() const
433 return transitions
.size();
437 Transducer::numberOfTransitions() const
441 for(map
<int, multimap
<int, int> >::const_iterator it
= transitions
.begin(),
442 limit
= transitions
.end();
445 counter
+= (it
->second
).size();
452 Transducer::isEmpty(int const state
) const
454 map
<int, multimap
<int, int> >::const_iterator it
;
456 it
= transitions
.find(state
);
457 if(it
!= transitions
.end())
459 if((it
->second
).size() > 0)
469 Transducer::write(FILE *output
, int const decalage
)
471 Compression::multibyte_write(initial
, output
);
472 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
+decalage
, 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
, int const decalage
)
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 tagbase
+= Compression::multibyte_read(input
) - decalage
;
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>(tagbase
, state
));
552 Transducer::copy(Transducer
const &t
)
556 transitions
= t
.transitions
;
560 Transducer::destroy()
565 Transducer::reverse(int const epsilon_tag
)
567 joinFinals(epsilon_tag
);
569 map
<int, multimap
<int, int> > temporal
;
571 for(map
<int, multimap
<int, int> >::reverse_iterator it
= transitions
.rbegin(); it
!= transitions
.rend(); it
++)
573 multimap
<int, int> aux
= it
->second
;
575 for(multimap
<int, int>::iterator it2
= aux
.begin(), limit2
= aux
.end();
576 it2
!= limit2
; it2
++)
578 if(it2
->second
>= it
->first
)
580 transitions
[it2
->second
].insert(pair
<int, int>(it2
->first
, it
->first
));
584 temporal
[it2
->second
].insert(pair
<int, int>(it2
->first
, it
->first
));
587 if(temporal
.find(it
->first
) != temporal
.end())
589 (it
->second
).insert(temporal
[it
->first
].begin(), temporal
[it
->first
].end());
590 temporal
.erase(it
->first
);
594 for(map
<int, multimap
<int, int> >::reverse_iterator it
= temporal
.rbegin(),
595 limit
= temporal
.rend();
598 for(multimap
<int, int>::iterator it2
= it
->second
.begin(),
599 limit2
= it
->second
.end();
600 it2
!= limit2
; it2
++)
602 transitions
[it
->first
].insert(pair
<int, int>(it2
->first
, it2
->second
));
607 initial
= *(finals
.begin());