Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  aut-def.gi   Sprache: unbekannt

 
Spracherkennung für: .gi vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

#############################################################################
##
#W  aut-def.gi                         Manuel Delgado <mdelgado@fc.up.pt>
#W                                     Jose Morais    <josejoao@fc.up.pt>
##
##
##
#Y  Copyright (C)  2004,  CMUP, Universidade do Porto, Portugal
##
#############################################################################
##
##  This file contains some generic methods for automata. 
##
#############################################################################
##
##
## Example
## gap> A:=Automaton("det",4,2,[[3,3,3,4],[3,4,3,4]],[1],[4]);
## < deterministic automaton on 2 letters with 4 states >
## gap> Display(A);
##    |  1  2  3  4
## -----------------
##  a |  3  3  3  4
##  b |  3  4  3  4
## Initial state:   [ 1 ]
## Accepting state: [ 4 ]
##
## The first component of a non deterministic automaton is <"nondet">
## and that of an epsilon automaton is <"epsilon">.
##
## In the case of automata with e-transitions, the last line of the 
## transition table corresponds to the e-transitions (i.e., epsilon is 
## considered the last letter of the alphabet).

#############################################################################
##
#R  
## The transitions of a deterministic automaton are always represented by 
## a matrix that may be dense or 
## not. If it is dense, the automaton is dense deterministic.
## The holes in the list may be replaced by zeros.
##
## The nondeterministic automata may be represented the same way, with
## sets of states instead of states in the transition matrix.
##
## In order to use this representation for epsilon-automata, an extra letter 
## must be added to the alphabet.
##

############################################################################
DeclareRepresentation( "IsAutomatonRep", IsComponentObjectRep, 
        ["type","states","alphabet","transitions","initial","accepting"]);

######################################################################
##
#F  Automaton(Type, Size, Alphabet, TransitionTable, ListInitial, 
##  ListAccepting )
##
##  Produces an automaton
##  The Alphabet may be given as a list of symbols (e.g. "xy" or "01")
##  or as an integer, representing its size. In the latter case, the alphabet
##  is taken as "abc..." (or "a_1,a_2,a_3,..." for an alphabet of more than 
##  26 symbols.
##  The meaning of the other arguments is clear.
##
InstallGlobalFunction( Automaton, function(Type, Size, Alphabet, 
        TransitionTable, ListInitial, ListAccepting )

#        local   F,  alph,  j,  i,  TT,  y,  x,  aut,  alphabet,  states,  
#                       initial,  accepting,  transitions,  A;
        local A, alph, aut, F, i, j, x, y, TT, l;

    #some tests...
    if not IsPosInt(Size) then
        Error("The size of the automaton must be a positive integer");
    elif not (IsPosInt(Alphabet) or IsList(Alphabet)) then
        Error("The size of the alphabet must be a positive integer or a list");
    fi;

    # Construct the family of all automata.
    F:= NewFamily( "Automata" ,
                IsAutomatonObj );
    if IsPosInt(Alphabet) then
        if Alphabet < 27 then
            alph := (List([1..Alphabet], i -> jascii[68+i]));
        else
            alph := (List([1..Alphabet], i -> Concatenation("a", String(i))));
        fi;
        if Type = "epsilon" then
            alph[Length(alph)] := '@';
        fi;

        F!.alphabet := MakeImmutable(alph);
    else
        if Type = "epsilon" then
            if not Alphabet[Length(Alphabet)] = '@' then
                Error("The last letter of the alphabet must be @");
            fi;
            j:=0;
            for i in Alphabet do
                if i = '@' then
                    j := j + 1;
                fi;
            od;
            if j > 1 then
                Error("The alphabet must contain only one @");
            fi;
        fi;
        F!.alphabet := Alphabet;
        Alphabet := Length(F!.alphabet);
    fi;

    if not IsList(TransitionTable) then
        Error("The transition table must be given as a matrix");
    elif not IsList(ListInitial) then
        Error("The initial states must be provided as a list");
    elif not IsList(ListAccepting) then
        Error("The accepting states must be provided as a list");
    elif (Length(TransitionTable) <> Alphabet) then
        Error("The number of rows of the transition table must equal the size of the alphabet");
    fi;

    #The type of the automaton: deterministic or not must be given
    if Type <> "det" and Type <> "nondet" and Type <> "epsilon" then
        Error( "Please specify the type of the automaton as \"det\" or \"nondet\" or \"epsilon\"");
    fi;


    # Fill the holes in the transition table with <0> in the case of 
    # deterministic automata and with <[0]> in the case of non 
    # deterministic automata
    TT := NullMat(Alphabet,Size);
    for i in [1 .. Alphabet] do
        for j in[1 .. Size] do
            if Type = "det" then
                if IsBound(TransitionTable[i][j]) then
                    if IsInt(TransitionTable[i][j]) then
                        if TransitionTable[i][j] > Size or TransitionTable[i][j] < 0 then
                            Error(Concatenation("TransitionTable[", String(i), "][", String(j), "] must be in [0 .. ", String(Size), "]"));
                        else
                            TT[i][j] := TransitionTable[i][j];
                        fi;
                    else
                        Error(Concatenation("TransitionTable[", String(i), "][", String(j), "] must be an integer"));
                    fi;
                else
                    TT[i][j] := 0;
                fi;
            else
                if IsBound(TransitionTable[i][j]) then 
                    if IsInt(TransitionTable[i][j]) then
                        if TransitionTable[i][j] > Size or TransitionTable[i][j] < 0 then
                            Error(Concatenation("TransitionTable[", String(i), "][", String(j), "] must be in [0 .. ", String(Size), "]"));
                        else
                            if TransitionTable[i][j] = 0 then
                                TT[i][j] := [];
                            else
                                TT[i][j] := [TransitionTable[i][j]];
                            fi;
                        fi;
                    elif IsRowVector(TransitionTable[i][j]) then
                        for y in [1 .. Length(TransitionTable[i][j])] do
                            if not IsBound(TransitionTable[i][j][y]) then
                                Error(Concatenation("TransitionTable[", String(i), "][", String(j), "] must have all elements in [1 .. ", String(Size), "]"));
                            elif IsPosInt(TransitionTable[i][j][y]) then
                                x := TransitionTable[i][j][y];
                                if x > Size or x < 0 then
                                    Error(Concatenation("TransitionTable[", String(i), "][", String(j), "] must have all elements in [1 .. ", String(Size), "]"));
                                fi;
                            elif TransitionTable[i][j][y] = 0 then
                                Unbind(TransitionTable[i][j][y]);
                            else
                                Error(Concatenation("TransitionTable[", String(i), "][", String(j), "] must have all elements in [1 .. ", String(Size), "]"));
                            fi;
                        od;
                        TT[i][j] := TransitionTable[i][j];
                    elif not TransitionTable[i][j] = [] then
                        Error(Concatenation("TransitionTable[", String(i), "][", String(j), "] must be in [0 .. ", String(Size), "]"));
                    else
                        TT[i][j] := TransitionTable[i][j];
                    fi;
                else
                    TT[i][j] := [];
                fi;
            fi;
        od;
    od;

    aut := rec(type := Type,
               alphabet := Alphabet,
               states := Size,
               initial := ListInitial,
               accepting := ListAccepting,
               transitions := TT );

    A := Objectify( NewType( F, IsAutomatonObj and 
                 IsAutomatonRep and IsAttributeStoringRep ),
                 aut );

    # Return the automaton.
    return A;
end);


#############################################################################
##
#M  ViewObj( <A> ) . . . . . . . . . . . print automata
##
InstallMethod( ViewObj,
        "displays an automaton",
        true,
        [IsAutomatonObj and IsAutomatonRep], 0,
        function( A )
    if A!.type = "det" then
        Print("< deterministic automaton on ", A!.alphabet, " letters with ", A!.states, " states >");
    elif A!.type = "nondet" then
        Print("< non deterministic automaton on ", A!.alphabet, " letters with ", A!.states, " states >");
    else
        Print("< epsilon automaton on ", A!.alphabet, " letters with ", A!.states, " states >");
    fi;
end);


#############################################################################
##
#M  PrintObj( <A> ) . . . . . . . . . . . print automata
##
InstallMethod( PrintObj,
        "displays an automaton",
        true,
        [IsAutomatonObj and IsAutomatonRep], 0,
        function( A )
    Print(String(A),"\n");
end);

#############################################################################
##
#M  Display( <A> ) . . . . . . . . . . . print automata
##
InstallMethod( Display,
        "displays an automaton",
        true,
        [IsAutomatonObj and IsAutomatonRep], 0,
        function( A )
    local   letters,  i,  str,  a,  xs,  xout,  q,  lsizeq,  sizeq,  len,  j;

    letters := [];
    for i in AlphabetOfAutomatonAsList(A) do
        Add(letters, [i]);
    od;

    if A!.states < 10 then
        if A!.type = "det" then
            str := "   |  ";
            for i in [1 .. A!.states] do
                str := Concatenation(str, String(i), "  ");
            od;
            str := Concatenation(str, "\n-----");
            for i in [1 .. A!.states] do
                str := Concatenation(str, "---");
            od;
            str := Concatenation(str, "\n");
            for a in [1 .. A!.alphabet] do
                xs := "";
                xout := OutputTextString(xs, false);
                PrintTo(xout, letters[a]);
                str := Concatenation(str, " ", xs, " |  ");
                CloseStream(xout);
                for i in [1 .. A!.states] do
                    q := A!.transitions[a][i];
                    if q = 0 then
                        str := Concatenation(str, "   ");
                    else
                        str := Concatenation(str, String(q),"  ");
                    fi;
                od;
                str := Concatenation(str, "\n");
            od;
            if IsBound(A!.accepting[2]) then
                xs := "";
                xout := OutputTextString(xs, false);
                PrintTo(xout, A!.initial);
                str := Concatenation(str, "Initial state:    ", String(xs), "\n");
                CloseStream(xout);
                xs := "";
                xout := OutputTextString(xs, false);
                PrintTo(xout, A!.accepting);
                str := Concatenation(str, "Accepting states: ", xs, "\n");
                CloseStream(xout);
            else
                xs := "";
                xout := OutputTextString(xs, false);
                PrintTo(xout, A!.initial);
                str := Concatenation(str, "Initial state:   ", xs, "\n");
                CloseStream(xout);
                xs := "";
                xout := OutputTextString(xs, false);
                PrintTo(xout, A!.accepting);
                str := Concatenation(str, "Accepting state: ", xs, "\n");
                CloseStream(xout);
            fi;

        elif A!.type = "nondet" then
            lsizeq := [];
            for i in [1 .. A!.states] do
                sizeq := 0;
                for a in [1 .. A!.alphabet] do
                    len := Length(A!.transitions[a][i]);
                    if len > sizeq then
                        sizeq := len;
                    fi;
                od;
                sizeq := sizeq + 2*(sizeq-1) + 4;
                lsizeq[i] := sizeq;
            od;

            str := "   |  ";
            for i in [1 .. A!.states-1] do
                str := Concatenation(str, String(i), "  ");
                for j in [1 .. lsizeq[i]] do
                    str := Concatenation(str, " ");
                od;
            od;
            str := Concatenation(str, String(A!.states), "\n---");
            for i in [1 .. A!.states] do
                str := Concatenation(str, "---");
                for j in [1 .. lsizeq[i]] do
                    str := Concatenation(str, "-");
                od;
            od;
            str := Concatenation(str, "\n");
            for a in [1 .. A!.alphabet] do
                str := Concatenation(str, " ", letters[a], " | ");
                for i in [1 .. A!.states] do
                    q := A!.transitions[a][i];

                    if q = [] then
                        str := Concatenation(str, "   ");
                        for j in [1 .. lsizeq[i]] do
                            str := Concatenation(str, " ");
                        od;
                    else
                        str := Concatenation(str, String(q),"  ");
                        len := Length(q);
                        len := len + 2*(len-1) + 4;
                        for j in [len .. lsizeq[i]] do
                            str := Concatenation(str, " ");
                        od;
                    fi;
                od;
                str := Concatenation(str, "\n");
            od;
            if IsBound(A!.initial[2]) then
                if IsBound(A!.accepting[2]) then
                    str := Concatenation(str, "Initial states:   ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting states: ", String(A!.accepting), "\n");
                elif A!.accepting = [] then
                    str := Concatenation(str, "Initial states:  ", String(A!.initial), "\n");
                else
                    str := Concatenation(str, "Initial states:  ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n");
                fi;
            elif A!.initial = [] then
                if IsBound(A!.accepting[2]) then
                    str := Concatenation(str, "Accepting states: ", String(A!.accepting), "\n");
                elif A!.accepting = [] then
                else
                    str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n");
                fi;
            else
                if IsBound(A!.accepting[2]) then
                    str := Concatenation(str, "Initial state:    ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting states: ", String(A!.accepting), "\n");
                elif A!.accepting = [] then
                    str := Concatenation(str, "Initial state:    ", String(A!.initial), "\n");
                else
                    str := Concatenation(str, "Initial state:   ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n");
                fi;
            fi;

        else
            lsizeq := [];
            for i in [1 .. A!.states] do
                sizeq := 0;
                for a in [1 .. A!.alphabet] do
                    len := Length(A!.transitions[a][i]);
                    if len > sizeq then
                        sizeq := len;
                    fi;
                od;
                sizeq := sizeq + 2*(sizeq-1) + 4;
                lsizeq[i] := sizeq;
            od;

            str := "   |  ";
            for i in [1 .. A!.states-1] do
                str := Concatenation(str, String(i), "  ");
                for j in [1 .. lsizeq[i]] do
                    str := Concatenation(str, " ");
                od;
            od;
            str := Concatenation(str, String(A!.states), "\n---");
            for i in [1 .. A!.states] do
                str := Concatenation(str, "---");
                for j in [1 .. lsizeq[i]] do
                    str := Concatenation(str, "-");
                od;
            od;
            str := Concatenation(str, "\n");
            for a in [1 .. A!.alphabet-1] do
                str := Concatenation(str, " ", letters[a], " | ");
                for i in [1 .. A!.states] do
                    q := A!.transitions[a][i];

                    if q = [] then
                        str := Concatenation(str, "   ");
                        for j in [1 .. lsizeq[i]] do
                            str := Concatenation(str, " ");
                        od;
                    else
                        str := Concatenation(str, String(q),"  ");
                        len := Length(q);
                        len := len + 2*(len-1) + 4;
                        for j in [len .. lsizeq[i]] do
                            str := Concatenation(str, " ");
                        od;
                    fi;
                od;
                str := Concatenation(str, "\n");
            od;
            a := A!.alphabet;
            str := Concatenation(str, " @ | ");
            for i in [1 .. A!.states] do
                q := A!.transitions[a][i];
                if q = [] then
                    str := Concatenation(str, "   ");
                    for j in [1 .. lsizeq[i]] do
                        str := Concatenation(str, " ");
                    od;
                else
                    str := Concatenation(str, String(q),"  ");
                    len := Length(q);
                    len := len + 2*(len-1) + 4;
                    for j in [len .. lsizeq[i]] do
                        str := Concatenation(str, " ");
                    od;
                fi;
            od;
            str := Concatenation(str, "\n");
            if IsBound(A!.initial[2]) then
                if IsBound(A!.accepting[2]) then
                    str := Concatenation(str, "Initial states:   ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting states: ", String(A!.accepting), "\n");
                else
                    str := Concatenation(str, "Initial states:  ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n");
                fi;
            else
                if IsBound(A!.accepting[2]) then
                    str := Concatenation(str, "Initial state:    ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting states: ", String(A!.accepting), "\n");
                else
                    str := Concatenation(str, "Initial state:   ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n");
                fi;
            fi;

        fi;
    else
        sizeq := Length(String(A!.states));
        if A!.type = "det" then
            str := "";
            for i in [1 .. A!.states] do
                for a in [1 .. A!.alphabet] do
                    q := A!.transitions[a][i];
                    if q > 0 then
                        str := Concatenation(str, String(i));
                        for j in [Length(String(i)) .. sizeq] do
                            str := Concatenation(str, " ");
                        od;
                        str := Concatenation(str, "  ", letters[a], "   ", String(q), "\n");
                    fi;
                od;
            od;
            if IsBound(A!.accepting[2]) then
                str := Concatenation(str, "Initial state:    ", String(A!.initial), "\n");
                str := Concatenation(str, "Accepting states: ", String(A!.accepting), "\n");
            else
                str := Concatenation(str, "Initial state:   ", String(A!.initial), "\n");
                str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n");
            fi;

        elif A!.type = "nondet" or A!.type = "epsilon" then
            str := "";
            for i in [1 .. A!.states] do
                for a in [1 .. A!.alphabet] do
                    q := A!.transitions[a][i];
                    if IsBound(q[1]) then
                        str := Concatenation(str, String(i));
                        for j in [Length(String(i)) .. sizeq] do
                            str := Concatenation(str, " ");
                        od;
                        str := Concatenation(str, "  ", letters[a], "   ", String(q), "\n");
                    fi;
                od;
            od;
            if IsBound(A!.initial[2]) then
                if IsBound(A!.accepting[2]) then
                    str := Concatenation(str, "Initial states:   ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting states: ", String(A!.accepting), "\n");
                else
                    str := Concatenation(str, "Initial states:  ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n");
                fi;
            else
                if IsBound(A!.accepting[2]) then
                    str := Concatenation(str, "Initial state:    ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting states: ", String(A!.accepting), "\n");
                else
                    str := Concatenation(str, "Initial state:   ", String(A!.initial), "\n");
                    str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n");
                fi;
            fi;
        fi;
    fi;
    Print(str);    
end);

#############################################################################
##
#F  IsAutomaton(A)
##
##  Tests if A is an automaton
##
InstallGlobalFunction( IsAutomaton, function(A)
    return(IsAutomatonObj(A));
end);

#############################################################################
##
#F  RandomAutomaton(T, Q, A)
##
##  Given the type T, number of states Q and number of the input alphabet
##  symbols A, this function returns a pseudo random automaton with those
##  parameters. To obtain an epsilon automata with 3 non-@-letters plus @, use
##  RandomAutomaton("epsilon",2,"abc");
##  < epsilon automaton on 4 letters with 2 states >
##
##
InstallGlobalFunction(RandomAutomaton, function(T, Q, A)
    local i, transitions, a;

    if not IsPosInt(Q) then
        Error("The number of states must be a positive integer");
    fi;
    if not (IsPosInt(A) or IsList(A)) then
        Error("The number of symbols of the input alphabet must be a positive integer or a string");
    fi;

    if IsPosInt(A) then
        a := A;
    else
        a := ShallowCopy(A);
        A := Length(a);
    fi;

    if T = "det" then
        transitions := [];
        for i in [1 .. A] do
            transitions[i] := SSortedList(List([1 .. Q], i -> Random([0 .. Q])));
        od;
        return(Automaton(T, Q, a, transitions, [Random([1 .. Q])], SSortedList(List([1 .. Q], j -> Random([1 .. Q])))));
    elif T = "nondet" then
        transitions := [];
        for i in [1 .. A] do
            transitions[i] := List([1 .. Q], i -> SSortedList(List([1 .. Random([0 .. Q])], j -> Random([1 .. Q]))));
        od;
        return(Automaton(T, Q, a, transitions, SSortedList(List([1 .. Random([1 .. Q])], j -> Random([1 .. Q]))), SSortedList(List([1 .. Q], j -> Random([1 .. Q])))));
    else
        transitions := [];
        for i in [1 .. A+1] do
            transitions[i] := List([1 .. Q], i -> SSortedList(List([1 .. Random([0 .. Q])], j -> Random([1 .. Q]))));
        od;
        if IsInt(a) then
            return(Automaton(T, Q, a+1, transitions, SSortedList(List([1 .. Random([1 .. Q])], j -> Random([1 .. Q]))), SSortedList(List([1 .. Q], j -> Random([1 .. Q])))));
        else
            if jascii[Position(jascii, '@')] in a then
                Error("Please choose an alphabet, without the character '@'");
            fi;
            return(Automaton(T, Q, Concatenation(a, [jascii[Position(jascii, '@')]]), transitions, SSortedList(List([1 .. Random([1 .. Q])], j -> Random([1 .. Q]))), SSortedList(List([1 .. Q], j -> Random([1 .. Q])))));
        fi;
    fi;
end);


#############################################################################
##
#M  String( <A> ) . . . . . . . . . . . outputs the definition of an automaton as a string
##
InstallMethod( String,
        "Automaton to string",
        true,
        [IsAutomatonObj and IsAutomatonRep], 0,
        function( A )
    return Concatenation("Automaton(\"", String(A!.type), "\",", String(A!.states), ",\"", AlphabetOfAutomatonAsList(A), "\",", String(A!.transitions), ",", String(A!.initial), ",", String(A!.accepting), ");;");
end);

    
############################################################################
##
#M Methods for the comparison operations for automata. 
##
InstallMethod( \=,
        "for two automata",
        #    IsIdenticalObj,
        [ IsAutomatonObj and IsAutomatonRep, 
          IsAutomatonObj and IsAutomatonRep,  ], 
        0,
        function( x, y ) 
    return(String(x) = String(y));

end );

InstallMethod( \<,
        "for two automata",
        #    IsIdenticalObj,
        [ IsAutomatonObj and IsAutomatonRep, 
          IsAutomatonObj and IsAutomatonRep,  ], 
        0,
        function( x, y ) 
    return(String(x) < String(y)); 
end );



#E
##
    

[ Dauer der Verarbeitung: 0.44 Sekunden  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge