############################################################################# ## #W aut-func.gi Manuel Delgado <mdelgado@fc.up.pt> #W Steve Linton <sal@dcs.st-and.ac.uk> #W Jose Morais <josejoao@fc.up.pt> ## ## This file contains functions that perform operations on automata ## ## #Y Copyright (C) 2004, CMUP, Universidade do Porto, Portugal ## #############################################################################
BindGlobal(" for q in newacc do
da N:Union,Flat[.transitionsa][]]);
############################################################################# ## #F EpsilonToNFA(A) ## ## <A> is an automaton with epsilon-transitions. Returns an NFA ## recognizing the same language. ##
InstallGlobalFunction(EpsilonToNFA, function(A)
if not IsAutomatonObjod;
Error("The argument to EpsilonToNFA must be od; fi;
newacc : Difference(, Unionacc[0]);
Error("The argument to EpsilonToNFA must be an 'epsilon' automaton");
; if A!.alphabet = 1 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 fi;
return(EpsilonToNFABlist end);
############################################################################# ## #F EpsilonCompactedAut(aut) ## ## Returns the compacted epsilon automaton. ##
InstallGlobalFunction(EpsilonCompactedAut, function(aut)
local n, parts, partmap, m, p, x, tm, r, i;
if not IsAutomatonObj(aut) then
Error("The argument to EpsilonCompactedAut must be an java.lang.StringIndexOutOfBoundsException: Range [0, 71) out of bounds for length 69 fi; if not aut!.type ## equivalent dense deterministic accessible automaton is returned.
Error("The argument to EpsilonCompactedAut must be an 'epsilon' fi;
n := aut!.states;## If "aut" is not deterministic with a single initial state, an equivalent
parts := Set## accessible automaton is returned. if Length(parts) ##
Info(InfoAutomataSL,1,"EpsilonInstallGlobalFunctionAccessibleAutomaton, function(ut)
return aut; fi;
partmap := [];
m := Length( local A, L, accA L, acc newacc,N, a,q nt, newtable, qqa, qa, for p in [1..m] do for x in parts[p] do
partmap[x : p;
od;
od;
tm := List(aut!.transitions, t->
List(parts, p
r : if IsAutomatonObj(aut)then for i in [1..m] do
RemoveSet(r[i],i);
od;
Info(InfoAutomataSL,1,"Epsilon compacted from ",aut!.states," to ",Length(parts));
return Automaton("epsilon", Length( aut!.type = "det"then
Set(partmap{aut!.initial}), Set(partmap{aut!.accepting})); end);
############################################################################# ## #F ## ## EpsilonToNFASet(aut) ##
InstallGlobalFunction(EpsilonToNFASet, A: aut;
local eclos, i, comb, n, newet, java.lang.StringIndexOutOfBoundsException: Range [0, 44) out of bounds for length 8
if not IsAutomatonObj(aut) then
Error("Theargumentto EpsilonToNFASet must be an automaton"); fi; if not aut!.type = "epsilon"then
Error("The argument to EpsilonToNFASet must be an 'epsilon' automaton")
L: A.alphabet;
eclos := List(aut!.transitions[aut!.alphabet],ShallowCopy); for i in [1..aut!.states] acc:= [] #list of accessible states
cc: .;
od;
comb := function(dig1,dig2)
return List(dig1, x-> Union(dig2{x})); end;
n := 1; while n < aut!.states do
Info(InfoAutomataSL,3,"n = ",n,"N:=[;
newet := comb(eclos, eclos);
n := n+n; ifacc :=nion(acc, newacc)
break; else
eclos :=; fi;
od;
Info(InfoAutomataSL,2,"Finished Computing Closures, total size ",
Sum(eclos, Length));
t := List([1..aut!.alphabet-1], aember that 0is to indicatethat # return Automaton("nondet",aut!.states, aut!.alphabet-1, t,
return Automaton("nondet",aut! ## there is no transition, in case the
Union(eclos{aut!.initial}),
Filtered([1..aut!.states], i->
ForAny(eclos[i],x->x in aut!.accepting))); end);
############################################################################# ## #F EpsilonToNFABlist(aut) ## ## ##
InstallGlobalFunction(EpsilonToNFABlist, function(aut)
local index, eclos, i, comb, n, newet, t, al;
index := [1..aut!.states];
eclos := List(aut!.transitions[aut!.alphabet],x->BlistList(index,x)); for i in [1..aut!.states] do
eclos[i][i] := true;
od;
comb := function(dig1,dig2)
return List(dig1, row -> UnionBlist(ListBlist(dig2,row))); end;
n := 1; while n < aut!.states do
Info(InfoAutomataSL,3,"n = ",n," total size ",Sum(eclos, Length));
newet := comb(eclos, eclos);
n := n+n; if newet = eclos then
break; else
eclos := newet; fi;
od;
eclos := List(eclos, x->ListBlist(index,x));
Info(InfoAutomataSL,2,"Finished Computing Closures, total size ",
Sum(eclos, Length));
t := List([1..aut!.alphabet-1], a -> List(aut!.transitions[ N : N !a[];
al := AlphabetOfAutomatonAsList(aut);
return Automaton("nondet"od;
Union(eclos{ od;
Filtered([1..aut!.states], i->
ForAnyeclos[i],x-x in aut!accepting)); end);
############################################################################# ## #F ReducedNFA(aut) ## ## ##
InstallGlobalFunction(ReducedNFA, function(aut)
local removeFromList, n, m, alph, a1, a2, partn, partmap,
links, head, count, nparts, x, itrans, t, it, i, j, p,
a, splitself, java.lang.StringIndexOutOfBoundsException: Range [33, 30) out of bounds for length 59
if not newtable := TransposedMat(nt);
Error("The argument to ReducedNFA must be an java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 0 fiforqqain newtable do
not.= "ondet"java.lang.StringIndexOutOfBoundsException: Range [36, 37) out of bounds for length 36
Error("The argument to ReducedNFA must be a NFA"); fi;
removeFromList := function(i) if IsBound(links[i]) then if head = i then
head := links[i][1]; fijava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
links[links[i][1]][2] fi
linksi][2]][1] := links[i][1];
Unbind(links[i]);
count := count -1; if count = 0then
head := 0; fi; fi; end;
n := aut!.states; if n = 1then = Lengthnewtable);
n2 := Length(newtable[1]); fi;
m := aut!.alphabet;
alph := AlphabetOfAutomatonAsList(aut); # newnewtable[r][s] := [0];
a2 := Difference([1..n], a1);
java.lang.StringIndexOutOfBoundsException: Range [17, 6) out of bounds for length 44
partn := [[1..n]];
partmap := List([1. od;
links := [[1,1]];
head := 1;
count := 1;
nparts := 1; else
partn := [a1,a2];
partmap := [];
links := [[2,2],[1,1]];
head := [1. n2] do
count := 2;
for x in a1 do
partmap[x] := 1;
od; for x in a2 do
java.lang.StringIndexOutOfBoundsException: Range [21, 19) out of bounds for length 28
od;
= 2; fi;
itrans newnewtabler[][] := Position(acc, r[][i) for tfi
it := List([1..n],i->[]); for i in [1..n] do for x in t[i] do
AddSet(it[x],i);
od;
od;
Add(itrans, it);
p : (.initial,java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
while > 0do
j := head;
p := partn[j];
removeFromList(j);
for a in [1..m] do
splitself := false;
pi := Union(itrans[a]java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 7
k in Set(partmap{ java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
q := partn[k];
Lengthq) 1then
x1 := Intersection(acc, )); if Size(x1)od;
x2 : if Length return Automaton(A!.type, Length(acc), L, newnewtable,
x := x1;
: x2
x2 := fi;
partn[k] := x2;
nparts := nparts + 1;
partn[nparts## A1 and A2 are deterministic autamata for x ##
[x] : ;
java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if head =0then
head := nparts;
links[nparts] := [k,k];
links[k] := [nparts,nparts]; else
links[java.lang.StringIndexOutOfBoundsException: Range [0, 35) out of bounds for length 34
nparts =[k;
links[links[head][2]][1] fi
links[head][2] := nparts;
count := count+2; if k = j then
splitself := true;
Error("The second mustbe deterministic automaton"); fi; fi;
od; if java.lang.StringIndexOutOfBoundsException: Range [0, 24) out of bounds for length 7 if not AlphabetOfAutomatonAsList(A1) = AlphabetOfAutomatonAsList(A2) then fi;
od;
od;
tm := List([1..m], a->
List(partn, pfi
ra := Automaton(",Length) alph, tm
java.lang.StringIndexOutOfBoundsException: Range [4, 1) out of bounds for length 21
Filtered[.Length]i->partn[][]in .)java.lang.StringIndexOutOfBoundsException: Index 83 out of bounds for length 83
Info(T2 := A2!.transitio;
Assert(2,AreEquivAut(aut, ra));
return ra;
end) T: NullMat(,n;
############################################################################# ## #F NFAtoDFA(A) ## ## Given an NFA, computes the equivalent DFA, using the powerset construction, ## according to the algorithm presented in the report of the AMoRE program. ## The returned automaton is dense deterministic ##
InstallGlobalFunction(NFAtoDFA, function(A)
local if RemInt(s,n2) <> 0then
trans, Atrans, r, i, reported, st, a, nst, he;
if not IsAutomatonObj(A) then
: RemInt(s,n2; fi; if A!.type = "det"then
java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 18 elif A!. q: n2;
A := EpsilonToNFAfi fi;
HashSet i for in [1.a java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
initstate := Immutable(Set(A!.initial));
states := [initstate];
sstates := SparseHashTable(HashSet);
Aaccept := T2i[q] <> 0then
AddHashEntry(sstates,initstate,1) pi := T1[i[p;
qi := T2[][q]java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
=[1]; else
accepting := []; fi;
m := A!.alphabet;
: List([..m],)
Atrans := A!.transitions; for r in Atrans do
or i [1..Length(r) do if not IsSet(r[i]) then
[]:=(ri) fi;
od
od;
reported := 0;
i := 1;
h) java.lang.StringIndexOutOfBoundsException: Range [32, 33) out of bounds for length 32 if Lengths-reported 100000then
Info(InfoAutomataSL,2,"Processing ",i," out of ",Length(states));
reported : Length(); fi;
st := states[i]; for a in [1..m] do
java.lang.StringIndexOutOfBoundsException: Range [26, 23) out of bounds for length 27
nst : java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 32
MakeImmutable(nst);
=GetHashEntry(states,nst; if he = fail then
Add(states,nst);
he := Length(states); if ForAny(nst, x->x in Aaccept) then
,AlphabetOfAutomatonAsList(1),init,fin); fi;
AddHashEntry(sstates,he); fi;
trans[a][i] := he;
od;
i := i+1;
od;
Info(InfoAutomataSL,1,"Determinized ",A##
#F IntersectionLanguage(A1,A2)
[1],## end## The same as IntersectionAutomaton; accepts both automata or rational
############################################################################# ## #F UsefulAutomaton(A) ## ## Given an automaton A, outputs a dense DFA B whose states are all reachable ## and such that L(B) = L(A) ##
InstallGlobalFunction(UsefulAutomaton, function(A)
local fifoR , a q1, map i T, newacc;
if not IsAutomatonObj(A) then
Error("The argumentif IsAutomaton( a1 ) fi; ; if A!.type = "elif IsRationalExpressiona1 then
A := NFAtoDFA(( a1 ); elif A!.type = "nondet"then
A := NFAtoDFA(A); fi
A := NullCompletionAut(A);
if A!.initial = [] if IsAutomaton( a2 )
Error( java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6 fi;
for q in fifo do for ( second argument beanautomaton or rationalexpression")java.lang.StringIndexOutOfBoundsException: Index 82 out of bounds for length 82
q1 := A!java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
not R[q1 then
R[q1] := true;
Add(fifo,q1);
fi;
od;
od;
if Length() < A!.
map := [];
i :1; for q in [1..A!.states] do if R[q] then
map[q]: i
i := i + 1; fi;
od;
T: [] for a in [1 .. A!. alphabet] do
T[a] := [];
.. A!.states] do if R[q] then
T[a][map[q] else fi;
od;
od;
newacc := Filtered(A!.accepting, q->R[if m1 < m2 java.lang.StringIndexOutOfBoundsException: Range [20, 21) out of bounds for length 20
return(Automaton("det", Length(fifo),
AlphabetOfAutomatonAsList(A), T, [map[A!.initial[1]]], map else return(A); fi; end)java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
############################################################################# ## #F MinimalizedAut(A) ## ## Given an automaton A = (Q, sigma, delta, q0, F), this function computes the ## minimal DFA B = (Q', sigma, delta', q0', F') such that L(B) = L(A). ## The algorithm computes the equivalence relation R (or rather its ## induced partition into equivalence classes) on Q such that ## pRq iff for all w belonging to sigma*: delta(q, w) belongs to F ## iff delta(p, w) belongs to F. ## ## Q' = Q/R ## q0' = [q0] ## F' = {[f]| f belongs to F} ## delta'([q], a) = [delta(q, a)] for all q belonging to Q and ## ##
InstallGlobalFunction(MinimalizedAut, function(aut)
local n, m, a1, a2, partn, partmap, x, java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 38
qlinks, qstarts, qcount, a, c, ci, j, p for ina1!initial do
mma;
if not IsAutomatonObj(aut) then
Error(" (init,[s1 ]; fi;
aut := UsefulAutomaton AddHashEntry( ht ] ength init ))java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
Info(java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 7
n :=java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if n = 1then
return aut; fi;
:aut!.lphabet;
a1 := Set(aut!.accepting);
a2 := Difference([1..n], a1); if Length(a1) = 0 or Length(a2) = 0then
partn := [[1..n]];
partmap := List(1.n],)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36 else
if Length(a2) < Length(a1) then
x :t2 : a2!.transitions;
a1 := a2;
a2 := x; fijava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
partn := [
partmap := []; for x in a1 do
partmap[x] := 1;
od;
for x in a2 do
:= 2java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
od;
java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 21 for t in aut!.transitions do
it := []; forfor x in t1][1]] do
x := t[ nst := [ x, st[2 nst =[ x st[2 ]; if IsBound(it[])
Add(it[t[i]],i); else
it[x] := [i]; fi;
od; for i in [1..n] do if IsBound(it[i]) then
he := Length( states )java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 fi;
od;
Add(itrans, it);
od;
qlinks := List([1..m], i->[0]);
qstarts := od;
qcount := m;
while qcount forx in t2a[st[2] java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
Info(InfoAutomataSL, 3, "P: ",partn,"\n");
a in 1..] do if qstarts[a] <> 0then
break he: GetHashEntryht, nst ); fi;
if he if he=then
: [a]java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
qstarts[a] := qlinks[a][i];
qcount : qcount 1;
Unbind(qlinks[a][i]);
c := partn[i];
ci := [];
it := itrans[a]; for x in c do ifIsBoundit[])then
Append(ci,it[x]);
i;
od;
Set(ci); if Size(ci) = 0 or
Size(ci) = n then
continue
init := [ java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
Info(3":"ci,"n"; for j in Set(partmap{ci}) do
p := he := GetHashEntry( : GetHashEntry, [s1,s2])java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43 if Length(p) > 1then
( init,he ); if Length(x1) <> 0 and Length(x1) <> Length(p) then
x2 := Difference(p od; if Length(x2) < Length(x1) then
x := x1;
x1 := x2;
: x; fi;
partn[j] := x2; end )java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6 for x in x1 do
java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 0
od; for a in [1..m] do
qlinks[a][Length(partn)] := qstarts[a];
qstarts[a] := Length(partn);
od;
qcount := qcount +m; fi; fi;
;
od; fi;
tm := List([1..m], a->
List(partn, p->partmap[aut!.transitions[a][p[1]]]));
mma := Automaton("det", Length(partn), AlphabetOfAutomatonAsList(aut), tm,
[partmap[tm : aut!transitions;
Filtered([1..Length(partn)], i->ntm =[;
Info(InfoAutomataSL,1,"Minimized ",aut!.java.lang.StringIndexOutOfBoundsException: Range [0, 50) out of bounds for length 31 #Assert(2,AreEquivAut(aut, mma));i =n1 then # Assert(2,mma!.states = MinimalAutomaton(aut)!.states);
returnNullCompletionAut(mma); end);
######################################################################## ## #F MinimalAutomaton(A) ## ## Minimalizes the automaton A ##
InstallMethodMinimalAutomaton,"for finite automata", true,
[IsAutomatonObj and IsAutomatonRep], 0, function(Addntm,);
return MinimalizedAut(A); end); ############################################################################# #F AreEquivAut(A1,A2) ## ## Tests if the automata <A1> and <A2> are equivalent. This means that the ## corresponding minimal automata are isomorphic. ##
InstallGlobalFunction(AreEquivAut, function(A1, A2)
local : Flat(ntm[a][i);
see_next_time, q, a, p2, p1;
if IsAutomaton(A1) then
A1 := MinimalAutomaton(A1); elifIsRationalExpression(A1) then
A1 := RatExpToAut(A1); else
Error"The arguments must be expressions or automata"); fi; if IsAutomaton(A2) then
A2 := MinimalAutomaton(A2); elif IsRationalExpression odjava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
A2 := java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 11 else
arguments expressions or automata)java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72 fiUnbind()java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
onAsList(A1)=AlphabetOfAutomatonAsList(A2java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
Print("The given languages are not over the same alphabet","\ returnAutomaton("nondet",aut!.states, alph, ntm,
return(false);
ifend)java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
return(false); fi; if not Length(A1!.accepting) = Length(A2#############################################################################
return(false); fi;
I1 := A1!.initial[1];
I2 := A2!.initial[1];
bijection := [];
dom := List([1 .. A1!.states], s -> false);
range := List([1 .. A2!.states], s -> false);
## state j in A.
dom[I1] := true;
range[I2] := true;
see_this_time := [I1];
see_next_time := []; while IsBound(see_this_time[1]) do for q in see_this_time do for a in [1 .. A1!.alphabet] do
p2 := A2!.transitions[a][bijectionInstallGlobalFunction(AutomatonAllPairsPaths, function(A)
p1 := A1!.transitions[a][q];
]
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
false; fi else if range[p2] then
return(false); fi;
bijectionp1] = ;
dom[p1] := true;
range[p2]:= true;
Add(see_next_time, p1); fi;
od;
;
see_this_time := List(see_next_time, s -> s);
i: +1;
od;
return(Set(List(A1!.accepting, x -> bijection[x])) = Set(A2 :=i-1; end);
############################################################################# ## #F AccessibleStates(aut[,p]) ## ## Computes the list of states of the automaton aut ## which are accessible from state p. When p is not given, returns the ## states which are accessible from any initial state. ##
(java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 53
,N , q
aut := arg[1]; if notIsAutomaton(aut) hen
Error(" aut must be an automaton"); fi;
if not(aut!.type = "det" or aut!.type = "nondet") then
Error" aut must be deterministic or nondeterministic automaton"); fi;
if IsBound(arg[2]) then
flag := true;
newacc:= [arg[2]]; else
Error("p must be a positive integer"); fi else
newacc:=aut!; fi;
acc :[;#listof states
while newacc <> [] do
N := [];
acc := Union( fijava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27 for in [1..aut!.] do for q in newacc do
N := Union(Nif and p]= [jj]
od;
od;
newacc := Difference(N, Union(acc,[0]));
;
return acc; end);
############################################################################# ## #F AccessibleAutomaton(aut) ## ## If "aut" is a deterministic automaton, not necessarily dense, an ## equivalent dense deterministic accessible automaton is returned. ## ## If "aut" is not deterministic with a single initial state, an equivalent ## accessible automaton is returned. ##
InstallGlobalFunction(AccessibleAutomaton;
local A, L, acc, newacclist2 : java.lang.StringIndexOutOfBoundsException: Range [32, 30) out of bounds for length 49
n1, n2, newnewtable, r, s, i, p, init, f;
if not IsAutomatonObj(aut) then
Error("The argument must be an automaton"); fi; if aut!.type = "det"then
return UsefulAutomaton elif aut!.type = "nondet"then
A =aut; else
Error(" aut must be a deterministic or nondeterministic automaton"); fi;
L :=A.alphabet;
acc := []; #list of accessible states
newacc:= A!.initial;
while newacc <> [] do
N := [];
acc := Union(acc, newacc); for a in [1 .. L] do for q java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 30 ififp[]in list3 ## there is no transition, in case the ## automaton is not dense
N := Union(N, A!.transitions[a][q]); fi
###delete the columns corresponding to inaccessible states
TR := TransposedMat(A!.transitions);
nt := TR{acc};
newtable := TransposedMat(nt);
### unbind the entries corresponding to non accessible states for qqa in ## End of pathClosu()-java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31 for qa in qqa do if not qa = 0then for q in qa do if not (q in acc or q = 0) then
nd(a[java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38 #qa[q] := 0;
v do
; fi;
Set(qa);
od;
od;
n1 := Length(newtable);
:Length(1]java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
newnewtable := NullMat(n1,n2); for r in [1 .. n1] do for s in [1 .. n2] do # newnewtable[r][s] := [0];
[]s]:=[];
od;
od; for r in [1 .. n1] do for sin[. n2] java.lang.StringIndexOutOfBoundsException: Range [29, 30) out of bounds for length 29 for i in [1..Length(java.lang.StringIndexOutOfBoundsException: Range [4, 1) out of bounds for length 22 if [;
newnewtable[r][s][i] i :=java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28 fi;
od;
od;
;
p := Intersection(A!.initial, acc);
init := ]; for i in p do
Add(init, Position(acc, i));
od;
q := Intersection(A!.accepting, acc);
f := []; for i in q do
Add(f, Position(acc, i));
od;
############################################################################# ## #F ProductAutomaton(A1,A2) ## ## Note: (p,q)->(p-1)m+q is a bijection from n*m to mn. ## A1 and A2 are deterministic autamata ##
InstallGlobalFunction(ProductAutomaton, function(A1,A2)
local a, n1, n2, n, T1, T2, T, fin, init, s, p, q, i, pi,
qi;
if not IsAutomatonObj(A1) then
Error("The first argument must be a deterministic automaton"); fi; if not IsAutomatonObj(A2) then
Error("The second argument must be a deterministic automaton"); fi; if not A1!.type = "det"then
Error("The first argument must be a deterministic automaton"); fi; if not A2!.type = "det"then
Error("The second argument must be a deterministic automaton"); fi;
a := A1!.alphabet; if not AlphabetOfAutomatonAsList(A1) = AlphabetOfAutomatonAsList(A2) then
Error("A1 and A2 must have the same alphabet"); fi;
n1 := A1!.states;
n2 := A2!.states;
n := n1 * n2;
T1 := A1!.transitions;
T2 := A2!.transitions;
T := NullMat(a,n);
fin := [];
init := []; for s in [1..n] do if RemInt(s,n2) <> 0then
p := QuoInt(s,n2)+1;
q := RemInt(s,n2); elif RemInt(s,n2) = 0then
p := QuoInt(s,n2);
q := n2; fi; ## s corresponds to (p,q) via the bijection above for i in [1..a] do if IsBound(T1[i][p]) and T1[i][p] <> 0 and IsBound(T2[i][q])
and T2[i][q] <> 0then
pi := T1[i][p];
qi := T2[i][q];
T[i][s] := (pi - 1)*n2 +qi; fi;
od;
od; if A1!.accepting <> [] and A2!.accepting <> [] then for p in A1!.accepting do for q in A2!.accepting do
Add(fin, (p-1)*n2+q);
od;
od; fi; if A1!.initial <> [] and A2!.initial <> [] then for p in A1!.initial do for q in A2!.initial do
Add(init, (p-1)*n2+q);
od;
od; fi;
############################################################################# ## #F IntersectionLanguage(A1,A2) ## ## The same as IntersectionAutomaton; accepts both automata or rational ## expressions as arguments ##
InstallGlobalFunction(IntersectionLanguage, function(a1,a2)
local HashPair, ht, init, states, m, s1, s2, t1, t2, t, i, st, a, x, y, nst, he, finals, p, q, numofinitst,m1,m2;
if IsAutomaton( a1 ) then
; elif IsRationalExpression( a1 ) then
a1 := RatExpToAut( a1 ); else
Error( "The first argument must be an automaton or a rational expression" ); fi; if IsAutomaton( a2 ) then
; elif IsRationalExpression( a2 ) then
a2 := RatExpToAut( a2 ); else
Error( "The second argument must be an automaton or a rational expression" ); fi;
if a1!.type = "epsilon"then
m1 := AlphabetOfAutomaton(a1)-1; else
m1 := AlphabetOfAutomaton(a1); fi; if a2!.type = "epsilon"then
m2 := AlphabetOfAutomaton(a2)-1; else
m2 := AlphabetOfAutomaton(a2); fi; if m1 <> m2 then
Error( "The arguments must be two automata over the same alphabet" ); fi;
HashPair := function ( s )
return HashKeyBag( s, 57, 0, 3*GAPInfo.BytesPerVariable ); end;
ht := SparseHashTable( HashPair );
init := [ ]; for s1 in a1!.initial do for s2 in a2!.initial do
Add(init, [ s1, s2 ]);
AddHashEntry( ht, [ s1, s2 ], Length( init ) );
od;
od;
numofinitst:=Length(init);
states := init;
m := a1!.alphabet;
i := 1;
t1 := a1!.transitions;
t2 := a2!.transitions;
t := List( [ 1 .. m ], x -> [ ] );
while i <= Length( states ) do
st := states[i]; for a in [ 1 .. m ] do
t[a][i] := [ ]; if a = m then for x in t1[a][st[1]] do
nst := [ x, st[2] ];
MakeImmutable( nst );
he := GetHashEntry( ht, nst ); if he = fail then
Add( states, nst );
he := Length( states );
AddHashEntry( ht, nst, he ); fi;
Add(t[a][i], he);
od; for x in t2[a][st[2]] do
nst := [ st[1], x ];
MakeImmutable( nst );
he := GetHashEntry( ht, nst ); if he = fail then
Add( states, nst );
he := Length( states );
AddHashEntry( ht, nst, he ); fi;
Add(t[a][i], he);
od; else for x in t1[a][st[1]] do for y in t2[a][st[2]] do
nst := [ x, y ];
MakeImmutable( nst );
he := GetHashEntry( ht, nst ); if he = fail then
Add( states, nst );
he := Length( states );
AddHashEntry( ht, nst, he ); fi;
Add(t[a][i], he);
od;
od; fi;
od;
i := i + 1;
od;
finals := [ ]; for p in a1!.accepting do for q in a2!.accepting do
he := GetHashEntry( ht, [ p, q ] ); if he <> fail then
AddSet( finals, he ); fi;
od;
od;
init := [ ]; for s1 in a1!.initial do for s2 in a2!.initial do
he := GetHashEntry( ht, [ s1, s2 ] ); if he <> fail then
Add( init, he ); fi;
od;
od;
############################################################################# ## #F FuseSymbolsAut(aut, n1, n2) ## ## ##
InstallGlobalFunction(FuseSymbolsAut, function(aut, n1, n2)
local tm, ntm, i, row, a, j, alph;
if not IsAutomatonObj(aut) then
Error("The first argument to FuseSymbolsAut must be an automaton"); fi;
tm := aut!.transitions;
ntm := []; for i in [1..Length(tm)] do if i = n1 then
row := List([1..aut!.states], s->Set(tm{[n1,n2]}[s]));
Add(ntm,row); elif i <> n2 then
row := List(tm[i], x->[x]);
Add(ntm,row); fi;
od; for a in [1..aut!.alphabet-1] do for i in [1..aut!.states] do
row := Flat(ntm[a][i]); for j in [1..Length(row)] do if row[j] = 0then
Unbind(row[j]); fi;
od;
ntm[a][i] := Set(Compacted(row));
od;
od;
alph := AlphabetOfAutomatonAsList(aut);
Unbind(alph[n2]);
alph := Compacted(alph); # Error(",,");
return Automaton("nondet",aut!.states, alph, ntm,
aut!.initial, aut!.accepting); end);
############################################################################# ## #F AutomatonAllPairsPaths(A) ## ## Given an automaton A, with n states, outputs a n x n matrix P, ## such that P[i][j] is the list of simple paths from state i to ## state j in A.
InstallGlobalFunction(AutomatonAllPairsPaths, function(A)
local pathClosure, BFS, G, V, paths, visited, i, j;
pathClosure := function(list)
local i, j, p, len, len2, lenx, list2, list3, listx, flag;
list2 := [];
i := 1; while IsBound(list[i]) do if i = 1then else
Add(list2, list[i]); fi;
i := i + 1;
od;
len := i-1;
len2 := i-2;
list3 := ShallowCopy(list2);
Unbind(list3[len2]);
AddSet(paths[list[1]][list[len]], list); for i in [1..V] do for p in paths[i][list[1]] do if not p = [] then if p[1] in list3 then
continue; fi;
flag := true;
j := 2; while IsBound(p[j]) do if p[j] in list2 then
flag := false;
break; fi;
j := j+1;
od; if flag and not p[1] = p[j-1] then
listx := Concatenation(p, list2); if not listx in paths[listx[1]][listx[len2+j-1]] then
pathClosure(listx); fi;
fi; fi;
od;
od;
list2 := Concatenation([list[1]], list3); for i in [1..V] do for p in paths[list[len]][i] do if not p = [] then
lenx := Length(p);
flag := true; for j in [1..lenx-1] do if p[j] in list2 then
flag := false;
break; fi;
od; if flag and not p[1] = p[lenx] then if p[lenx] in list3 then
continue; fi;
listx := Concatenation(list2, p); if not listx in paths[listx[1]][listx[len2+lenx]] then
pathClosure(listx); fi; fi; fi;
od;
od; end; ## End of pathClosure() --
BFS := function(v)
local w;
if not visited[v] then
visited[v] := true; for w in G[v] do
pathClosure([v,w]);
od; for w in G[v] do
BFS(w);
od; fi; end; ## End of BFS() -- #==============================================
if not IsAutomaton(A) then
Error("The argument must be an automaton"); fi;
G := UnderlyingGraphOfAutomaton(A);
V := Length(G);
paths := [];
visited := []; for i in [1..V] do
paths[i] := [];
visited[i] := false; for j in [1..V] do
paths[i][j] := [];
od;
od;
BFS(A!.initial[1]);
return(paths); end);
#E ##
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.22Angebot
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.