GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#############################################################################
##
##
#W transducers.gi Michael Albert,
#W Steve Linton,
#W Ruth Hoffmann
##
#Y Copyright (C) 2004-2015 School of Computer Science,
#Y University of St. Andrews, North Haugh,
#Y St. Andrews, Fife KY16 9SS, Scotland
##
#############################################################################
##
#F Transducer(states,init,transitions,accepting)
##
## Returns a recording of a transducer with s states, with init being the
## start state, transitions of the form [in,out,from to] and the set of
## accept states.
##
InstallGlobalFunction(Transducer, function(states,init,transitions,accepting)
return rec(states := states, initial := init, transitions := transitions,
accepting := accepting);
end );
#############################################################################
##
#F DeletionTransducer(k)
##
## Returns a transducer over k+1 states, which removes an entry in a
## permutation, written in the rank encoding and produces the new correct
## rank encoding.
##
InstallGlobalFunction(DeletionTransducer, function(k)
local states, init, accepting, trans, i, j;
states := k+1;
init := k+1;
accepting := [1..k];
trans := [];
for i in [1..k] do
Add(trans,[i,i,k+1,k+1]);
Add(trans,[i,0,k+1,i]);
for j in [i+1..k] do
Add(trans,[j,j-1,i,i]);
Add(trans,[i,i,j-1,j]);
od;
Add(trans,[i,i,k,k]);
od;
return Transducer(states, init, trans, accepting);
end );
#############################################################################
##
#F TransposedTransducer(t)
##
## Returns the transducer t with the input and output letters in each
## transition interchanged.
##
InstallGlobalFunction(TransposedTransducer, function(t)
return Transducer(t.states, t.initial,
List(t.transitions,x->[x[2],x[1],x[3],x[4]]), t.accepting);
end );
#############################################################################
##
#V HashPair
##
InstallValue(HashPair, s->HashKeyBag(s,57,0,12));
#############################################################################
##
#F CombineAutTransducer(aut,trans)
##
## Returns an automaton that represents the concatenation of the automaton
## aut and the transducer trans.
##
InstallGlobalFunction(CombineAutTransducer, function(aut,trans)
local initstates, states, ht, i, ptrans, st, s, a,
targets, s1, tr, nst, he, newalpha, tm, b, brow,
t, type;
initstates := Cartesian(aut!.initial,[trans.initial]);
states := ShallowCopy(initstates);
ht := SparseHashTable(HashPair);
for i in [1..Length(states)] do
AddHashEntry(ht, states[i],i);
od;
ptrans := [];
i := 1;
while i <= Length(states) do
st := states[i];
s := st[1];
for a in [1..aut!.alphabet] do
targets := aut!.transitions[a][s];
if not IsList(targets) then
if (targets <> 0) then
targets := [targets];
else
targets := [];
fi;
fi;
for s1 in targets do
for tr in trans.transitions do
if tr[1] = a and tr[3] = st[2] then
nst := [s1,tr[4]];
MakeImmutable(nst);
he := GetHashEntry(ht,nst);
if he = fail then
Add(states, nst);
he := Length(states);
AddHashEntry(ht, nst, he);
fi;
Add(ptrans, [i,he,tr[2]]);
fi;
od;
od;
od;
for tr in trans.transitions do
if tr[1] = 0 and tr[3] = st[2] then
nst := [s,tr[4]];
MakeImmutable(nst);
he := GetHashEntry(ht,nst);
if he = fail then
Add(states, nst);
he := Length(states);
AddHashEntry(ht, nst, he);
fi;
Add(ptrans, [i,he,tr[2]]);
fi;
od;
if aut!.type = "epsilon" then
targets := aut!.transitions[aut!.alphabet][s];
for s1 in targets do
nst := [s1,st[2]];
MakeImmutable(nst);
he := GetHashEntry(ht,nst);
if he = fail then
Add(states, nst);
he := Length(states);
AddHashEntry(ht, nst, he);
fi;
Add(ptrans, [i,he,0]);
od;
fi;
i := i+1;
od;
newalpha := Set(trans.transitions, tr->tr[2]);
newalpha := [Minimum(Minimum(newalpha), 1)..Maximum(newalpha)];
tm := List(newalpha, b->List([1..Length(states)],i->[]));
for t in ptrans do
if t[3] = 0 then
AddSet(tm[Length(tm)][t[1]],t[2]);
else
AddSet(tm[t[3]][t[1]],t[2]);
fi;
od;
if 0 in newalpha then
type := "epsilon";
else
type := "nondet";
fi;
Info(InfoAutomataSL, 1, "Combined Transducer(",trans.states,") with ",
aut!.type," aut(",aut!.states,") to make ",type," aut(",Length(states),")");
return Automaton(type,Length(states),Length(tm),tm,
List(initstates, st -> GetHashEntry(ht, st)),
Filtered([1..Length(states)],
i->states[i][1] in aut!.accepting and
states[i][2] in trans.accepting));
end );
#############################################################################
##
#F InvolvementTransducer(k)
##
## Returns a transducer over k+1 states that removes an arbitrary number of
## entries in a rank encoded permutation, and produces the new applicable
## rank encoding.
##
InstallGlobalFunction(InvolvementTransducer, function(k)
local IntToBlist, states, init, m, accepting, trans, i,
t, e, lowBits, target, eModified;
states := 2^(k-1);
init := 2^(k-1);
m := init;
accepting := [1..2^(k-1)];
trans := [];
for i in [1..2^(k-1)] do
for e in [1..k] do
if (e < k) then
t := (2*i mod m);
lowBits := (t mod 2^e)/2;
target := t - lowBits;
else
target := i;
lowBits := i mod 2^(k-1);
fi;
eModified := e;
while (lowBits > 0) do
eModified:= eModified - (lowBits mod 2);
lowBits := QuoInt(lowBits, 2);
od;
if (target <> 0) then
Add(trans, [e, eModified, i, target]);
else
Add(trans, [e, eModified, i, init]);
fi;
if (e < k) then target := target + 2^(e-1); fi;
Add(trans, [e, 0,i, target]);
od;
od;
return Transducer(states, init, trans, accepting);
end );