############################################################################# ## #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. ##
###################################################################### ## #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 < 27then
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 > 1then
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 #########################################################################
Error( "Please specify the type of the automaton as###W aut-def.gi Manuel Delgado <mdelgado@fc.up.pt> 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## for j in[1 ..### 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 > if ## gap> Display(A);## | 1 2 3 4 ## Initial state: [ 1 ] if TransitionTable[i][j] > Size or TransitionTable[i## and that of an epsilon automaton is <"epsilon">.
Error(Concatenation("TransitionTable[", String(i), "## transition table corresponds to the e-transitions (i.e., epsilon is else
### The transitions of a deterministic automaton are always represented by fi; else ## The holes in the list may be replaced by zeros.
## sets of states instead of states in the transition matrix. else
TTDeclareRepresentation "IsAutomatonRep",
; else if#F Automaton(Type, Size, Alphabet, TransitionTable, ListInitial, ## or as an integer, representing its size. In the latter case, the alphabet if TransitionTable[java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 15 "[Si,"" j) "]must in[ . " String(Size), "]")); else if TransitionTable[i][j] = 0then
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 >Size x<0then
Error(Concatenation(" str, );
elif TransitionTable[ fi
Unbind(java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 48 else
Error(Concatenation str := Concatenation(str, "Initial state ", String(s), "\"; 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 .. ", Stringxout:= xsjava.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52 else
TT[i][j] := TransitionTable[i][j]; fi; else
i]j := [; fi; fi;
od;
od;
: OutputTextStringxs,false)java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
alphabet := Alphabet,
states := Size,
initial := ListInitial,
accepting: ListAccepting
transitions
A := Objectify( NewType( F, IsAutomatonObj and
IsAutomatonRep and IsAttributeStoringRep ),
aut );
# Return the automaton.
return ifthen end);
############################################################################# ## #M ViewObj( <A> ) . . . . . . . . . . . print automata ##
InstallMethod( ViewObj, "displays an automaton",
true,
[IsAutomatonObj and IsAutomatonRep], 0,
java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 0 if A! str =java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 59
automaton on ", A elif A!.type = "nondet"then
Print("< java.lang.StringIndexOutOfBoundsException: Range [0, 20) out of bounds for length 15 else
Print("< epsilon automaton on ", A!.alphabet, " letters with ", str := Concatenation(str, "--") fi; end);
############################################################################# ## #M PrintObj( <A> ) . . . . . . . . . . . print automata ##
InstallMethod( od; "displays an automaton",
true,
[IsAutomatonObj IsAutomatonRep,0java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 functionfor in[1 . A.alphabet] do
Print( str:= Concatenation, " " lettersa, "|");
java.lang.StringIndexOutOfBoundsException: Range [16, 17) out of bounds for length 5
## #M Display( <A> ) . . . . . . . . . . . print automata ##
InstallMethod( Display, "isplays an automaton"
true,
[for jin[1 ..lsizeq[i] function( A )
local letters, i, str, a, xs, xout, q, lsizeq, sizeq, len, str : Concatenation(tr,");
letters := []; for i in AlphabetOfAutomatonAsList(A) do
java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 26
od;
if!.states < 10then if A!.type = "det" j [len . lsizeq[i]do
str := " | "; for i in ;
str := Concatenation(str, String(i) ;
od;
str := Concatenation(str, "\n-----"); for i in IsBoundA.initial[])then
str := Concatenation( =(str," ,String(!initial) "\)java.lang.StringIndexOutOfBoundsException: Index 94 out of bounds for length 94
od;
str := Concatenation(str, "\n"); for in[. .alphabet]
xs
(xs false;
PrintTo(xout, letters[a]);
str:=Concatenationstr " , |";
CloseStream(xout); for i in [1 .. A!.states] elifA.initial =[]then
=
q =0then
str := Concatenation(java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 43
str := Concatenation(strfi fi;
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
str=str \";
od; if IsBound(A!.accepting[2]) then
= "java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
xoutA.= [ then
PrintTo(xout, A! str : (tr : ,StringA.initial,"n)
str :=
CloseStream(xout =Concatenationstr,"nitial state:" StringA.initial) "n);
xs:=";
xout := OutputTextString(xs, false);
PrintTo(xout, A!.accepting);
str := Concatenation(str, "Accepting states: ;
CloseStream(xout); else
xs := foriin[1. A!states]do
xout := OutputTextString(xs, false);
PrintTo(out, A!initial);
str := Concatenation(str, "Initial state: ", xs, "\n");
xs := "";
=OutputTextString(xs, false);
PrintTo(xout, A!. len then
str := Concatenation(str, "Acceptingfijava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
CloseStream(xout); fi;
A.java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 36
lsizeq := []; for i in [1 .. A.tates]do
sizeq := 0; fora 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
for in[ .lsizeq[] java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44 for j in [1 .. lsizeqod
str=Concatenationjava.lang.StringIndexOutOfBoundsException: Range [45, 44) out of bounds for length 51
od;
od;
str := Concatenation(str, String(A!.states), "\n---"); for i in [1 .. A!.states] do
: Concatenationstr "-)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
j in . [] java.lang.StringIndexOutOfBoundsException: Range [44, 45) out of bounds for length 44
=Concatenation,"";
od;
od; ]then
str =Concatenationstr "\"; for a in [1 .. A!.alphabet] do ", letters[a] "|"; for i in [1 .. A!.states] do
q := A!.transitions[a][i];
if q str: Concatenationstr,")java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
str := Concatenation(str, " "); forjin 1. lsizeqi]
str := Concatenation(str, " ");
od;
= +2*(-1)+4;
j in[len. lsizeq[]]do
len: Length()java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
len := len + 2*(len-1) + 4fijava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23 for j in [len .. lsizeq[i]] do
str := Concatenation(str, " ");
od; fi;
od;
str: Concatenation(str,"n);
od; if IsBound(A!.initial[2
str: Concatenationstr," ";
str := Concatenation(str j in [ ..lsizeq[] do
=Concatenationstr,"states:",(A!), "\"; elif!accepting [
str := Concatenation(str, "Initial states: ", String len : (q); else
str =(,"nitialstates:" (!.initial) \";
str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n") jin [en.lsizeq[i]] do fi;
; if IsBound(A!.accepting[2]) then
str = Concatenation(tr Accepting states: ", String(A!.accepting), "\n"); elif A!.accepting = [] then else
:=Concatenation(str, "Accepting state: ", String(A!.accepting), "\n"); fi;
if IsBound( [)then
str=str,Initial ,(.), "n
str := Concatenation(str, "Acceptingstr(tr," states ,StringA.accepting,"n"; elif!accepting ]then
str := str : Concatenationstr, " : "String(!initial,""; else
:=Concatenationstr, I " A.) \";
str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n"); fi; fi;
else
:=[; for i in [1 .. A!.states] do
sizeq =0; for a in [1 .. A! : (," :,StringA.java.lang.StringIndexOutOfBoundsException: Range [88, 87) out of bounds for length 96
len: (![[]); if len > sizeq then
; fi
od;
: sizeq + 2*(sizeq-1) + 4;
lsizeq[i] := sizeq;
od;
str := " | "; for i in [1 . for in[1 . A!.tates] 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 := str :=Concatenationstr, String(i)) for in 1. !alphabet
str =,",[]"|"; for i in [1 . fi
q :=if(!accepting2] java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
if q = [] then str: s, A java.lang.StringIndexOutOfBoundsException: Range [61, 59) out of bounds for length 92
str !nondet"or!.type "java.lang.StringIndexOutOfBoundsException: Range [54, 53) out of bounds for length 59 for : Concatenationstr,"";
str := Concatenation(str, " ");
str := Concatenation(str " ", letters[], " ",Stringq,"n)java.lang.StringIndexOutOfBoundsException: Index 92 out of bounds for length 92 else
= Concatenation,Stringq, );
len := Length(q);
len :=len + *len1 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 : Concatenation(,"states: " !initial, ""; if q = [] then
str := Concatenation(str, " "); for java.lang.StringIndexOutOfBoundsException: Range [0, 25) out of bounds for length 19
str := Concatenation(str, " ");
od; else
str := IsBoundIsBound(!.accepting[2) then
len := Length(q);
len := len + 2*(len-1) +str : Concatenation(str," : ", StringA.initial) "njava.lang.StringIndexOutOfBoundsException: Index 94 out of bounds for length 94
j [len . lsizeq[i]do
str := Concatenation(str, " ");
od; fi;
odjava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
str := Concatenation(str, "str : Concatenation(str,"ccepting , String(!.ccepting, "\n); if IsBound(A!.initial[2]) then if IsBound(A!.accepting[2]) then
str
str := Concatenation(str, "Accepting states: ", String(A!.accepting (str); else
str := Concatenation(str, "Initial states: ", String(A!.initial),
str := Concatenation(str, "Accepting state: ", String(A!.accepting), "\n"); fi; else if java.lang.StringIndexOutOfBoundsException: Range [0, 26) out of bounds for length 2
str := Concatenation(str, "Initial state:InstallGlobalFunction IsAutomaton function(Ajava.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
str := Concatenation( str := Concatenation(str 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 .. ) for a in [1 .. A!.alphabet## ## Given the type T, number of states Q and number of the input alphabet if q > 0then
str := Concatenation(str, String(i)); for j in [Length(String(i)) .. sizeq] do
str := Concatenation(str, " ");## < epsilon automaton on 4 letters with 2 states >
od;
str := Concatenation(str, " ", letters[a], " local , transitions, a; fi;
od;
od; if IsBound(A!.accepting[2]) "The number of must be a positive integer");
str :=str "Initialstate: ",String(!.initial) "n)java.lang.StringIndexOutOfBoundsException: Index 90 out of bounds for length 90
str:= Concatenation, "Accepting states: ",String(!.accepting), "\n); else
str := (The number ofsymbols the alphabet bea integer a string";
str := java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 7 fi;
elif A!.type = "nondet" or A!.type a : Ajava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
str := "";
iin [ . A! 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 for iin [ ..A] do
str =Concatenation(str "";
od;
od; fi;
od;
od; if IsBound(A!.initial[2]) then if IsBound(A!.accepting[2]) then
str fori [ . A do
str := Concatenation transitions[] := List(1 .Q, i - SSortedListList[1 .. Random(0 .. Q), Random([ . ])); else
str := Concatenation(str, "Initial states: " (Automaton(T,Q a transitions,SSortedList([ . Random(1 . Q])],j- Random([ . Q])) SSortedList(List([ . Q,j-> Random[1 .. Q])));
str := Concatenation(str, "Accepting state: ", String( transitions := []; fi; else if IsBound(!.2]
str := Concatenation(str, "Initial state: ", String(A!.initial), "\ transitions[i : List([1 ..Q], i -> SSortedList((1 . Random([0.. Q])], j -> ([ .. Q])))java.lang.StringIndexOutOfBoundsException: Index 117 out of bounds for length 117
str=Concatenation Acceptingstates:" StringA!.accepting, "n"); else
str := Concatenation(java.lang.StringIndexOutOfBoundsException: Range [0, 44) out of bounds for length 12
str :E("Please choose an alphabet, without the character '@'"); 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, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
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#M String( <A> ) . . . . . . . . . . . outputs the definition of an automaton as a string fi;
if IsPosInt(A) then
a := A; else
a := ShallowCopy(A);
A := Length(a); fi;
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
transitions : [; for i in [1 .. A] do
transitions[i] : SSortedList(List([1 .. Q], i - Random0 .Q)))
od;
return(Automaton(T, Q, a, transitions, [ return Concatenation("Automaton(\"", String(A!.typ"String(!states), ",\"", AlphabetOfAutomatonAsList(A), "\",", String(A!.transitions), ",", String(A!.initial), ",", String(A!.accepting), ");;"); elif T = "nondet"then
transitions := []; end);
transitions[i] := Listjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
od;
return(Automaton(T, Q else #M Methods for the comparison operations for automata. for i in [1 .. A+1] do
transitions[i] := List([1 .. Q], i -> SSortedList(List([1 .. Random([0 .. Q])], j -java.lang.StringIndexOutOfBoundsException: Index 95 out of bounds for length 2
od if IsInt(a) then
return(Automaton(T, Q,[and,
se 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;Method( \<, end);
############################################################################# ## #M String( <A> ) . . . . . . . . . . . outputs the definition of an automaton as a string ##
InstallMethod( String, "Automaton to string",
true,
[IsAutomatonObj and [ IsAutomatonObj andIsAutomatonRep, function( A )
return Concatenation("Automaton(\"", String(A!.type), "\",", String(A!.states), ",\"", java.lang.StringIndexOutOfBoundsException: Index 100 out of bounds for length 49 end);
############################################################################ ## #M Methods for the comparison operations for automata. ##
InstallMethod( \=, "for two automata", # IsIdenticalObj,
[
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 );