- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# complete.hxx

    00001 // complete.hxx: this file is part of the Vaucanson project.
    00002 //
    00003 // Vaucanson, a generic library for finite state machines.
    00004 //
    00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The Vaucanson Group.
    00006 //
    00007 // This program is free software; you can redistribute it and/or
    00008 // modify it under the terms of the GNU General Public License
    00009 // as published by the Free Software Foundation; either version 2
    00010 // of the License, or (at your option) any later version.
    00011 //
    00012 // The complete GNU General Public Licence Notice can be found as the
    00013 // `COPYING' file in the root directory.
    00014 //
    00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
    00016 //
    00017 #ifndef VCSN_ALGORITHMS_COMPLETE_HXX
    00018 # define VCSN_ALGORITHMS_COMPLETE_HXX
    00019
    00020 # include <vaucanson/algorithms/complete.hh>
    00021
    00022 # ifndef VCSN_NDEBUG
    00023 #  include <vaucanson/algorithms/realtime.hh>
    00024 # endif // ! VCSN_NDEBUG
    00025
    00026 # include <vaucanson/automata/concept/automata_base.hh>
    00027 # include <vaucanson/misc/usual_macros.hh>
    00028
    00029 # include <list>
    00030 # include <set>
    00031
    00032 namespace vcsn {
    00033
    00034   /*--------------.
    00035   | complete_here |
    00036   `--------------*/
    00037
    00038   template <typename A, typename AI>
    00039   void
    00040   complete_here(Element<A, AI>& work)
    00041   {
    00042     // Note that this algorithm may be used on non-deterministic
    00043     // automata.
    00044     precondition(is_realtime(work));
    00045     BENCH_TASK_SCOPED("complete");
    00046     typedef Element<A, AI> automaton_t;
    00047     AUTOMATON_TYPES(automaton_t);
    00048     AUTOMATON_FREEMONOID_TYPES(automaton_t);
    00049
    00050     hstate_t sink_state = work.add_state();
    00051     bool sink_needed = false;
    00052
    00053     // If the sink states is the only state of the automaton, we want
    00054     // to keep it as an initial state.  This is meant!  The empty
    00055     // automaton is deterministic, but a complete deterministic
    00056     // automata has at least one state (it is then easier to
    00057     // complement it).
    00058     if (work.states().size() ==  1)
    00059     {
    00060       sink_needed = true;
    00061       work.set_initial(sink_state);
    00062     }
    00063
    00064     for_all_const_states(s, work)
    00065       for_all_const_letters(l, work.structure().series().monoid().alphabet())
    00066       {
    00067         bool empty = true;
    00068         for (delta_iterator t(work.value(), *s); ! t.done(); t.next())
    00069         {
    00070           monoid_elt_t w(work.series_of(*t).structure().monoid(), *l);
    00071           if (work.series_of(*t).get(w) != work.series().semiring().wzero_)
    00072           {
    00073             empty = false;
    00074             break;
    00075           }
    00076         }
    00077         if (empty)
    00078         {
    00079           sink_needed = true;
    00080           work.add_letter_transition(*s, sink_state, *l);
    00081         }
    00082       }
    00083
    00084     if (!sink_needed)
    00085       work.del_state(sink_state);
    00086   }
    00087
    00088   /*---------.
    00089   | complete |
    00090   `---------*/
    00091
    00092   template <typename A, typename AI>
    00093   Element<A, AI>
    00094   complete(const Element<A, AI>& e)
    00095   {
    00096     Element<A, AI> res(e);
    00097     complete_here(res);
    00098     return res;
    00099   }
    00100
    00101   /*------------.
    00102   | is_complete |
    00103   `------------*/
    00104
    00105   template <typename A, typename AI>
    00106   bool
    00107   is_complete(const Element<A, AI>& e)
    00108   {
    00109     precondition(is_realtime(e));
    00110     BENCH_TASK_SCOPED("is_complete");
    00111     if (e.states().size() ==  0)
    00112       return false;
    00113     typedef Element<A, AI> automaton_t;
    00114     AUTOMATON_TYPES(automaton_t);
    00115     AUTOMATON_FREEMONOID_TYPES(automaton_t);
    00116     const alphabet_t& alpha = e.structure().series().monoid().alphabet();
    00117     for_all_const_states(i, e)
    00118     {
    00119       for_all_const_letters(j, alpha)
    00120       {
    00121         bool empty = true;
    00122         for (delta_iterator t(e.value(), *i);
    00123              ! t.done() && empty;
    00124              t.next())
    00125         {
    00126           monoid_elt_t w(e.series_of(*t).structure().monoid(), *j);
    00127           if (e.series_of(*t).get(w) != e.series().semiring().wzero_)
    00128           {
    00129             empty = false;
    00130             break;
    00131           }
    00132         }
    00133
    00134         if (empty)
    00135           return false;
    00136       }
    00137     }
    00138     return true;
    00139   }
    00140
    00141 } // vcsn
    00142
    00143 #endif // ! VCSN_ALGORITHMS_COMPLETE_HXX