Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/fga/lib/   (GAP Algebra Version 4.15.1©)  Datei vom 4.3.2023 mit Größe 10 kB image not shown  

Quelle  Autom.gi   Sprache: Shell

 

#############################################################################
##
#W  Autom.gi                FGA package                    Christian Sievers
##
##  Methods to create and compute with inverse automata
##
#Y  2003 - 2018
##


DeclareRepresentation( "IsSimpleInvAutomatonRep", 
    IsComponentObjectRep and IsInvAutomatonCategory and
      IsAttributeStoringRep and IsCollection,
#    [ "initial", "terminal", "states", "group" ] );
    [ "states", "group" ] );

InstallMethod( TrivialInvAutomaton,
    [ IsFreeGroup ],
    function(G)
    local state;
    state := FGA_newstate();
    return Objectify( NewType( FamilyObj( G ),
                               IsSimpleInvAutomatonRep and IsMutable),
                      rec(initial:=state, terminal:=state, group:=G) );
    end );

InstallMethod( InvAutomatonInsertGenerator,
    IsCollsElms,
    [ IsSimpleInvAutomatonRep and IsMutable, IsElementOfFreeGroup ],
    function(A,gen)
        FGA_AutomInsertGeneratorLetterRep( A, LetterRepAssocWord( gen ) );
    end );

InstallMethod( \in,
    "for a simple inverse automaton",
    IsElmsColls,
    [ IsElementOfFreeGroup, IsSimpleInvAutomatonRep ],
    function(g,A)
        return IsIdenticalObj(FGA_deltas( A!.initial,
                                          LetterRepAssocWord(g)),
                              A!.terminal);
    end );

InstallMethod( PrintObj,
   [ IsSimpleInvAutomatonRep ],
   function(A)
       Print("<simple inverse automaton representation>");
   end );

InstallMethod( AsGroup,
    "for a simple inverse Automaton",
    [ IsSimpleInvAutomatonRep ],
    function(A)
    local G;

    if IsMutable(A) then
        TryNextMethod();
    fi;

    G := rec ();
    ObjectifyWithAttributes( G,
        NewType( FamilyObj( A ),
                 IsFreeGroup and IsAttributeStoringRep and
                     HasOneImmutable and HasFreeGroupAutomaton ),
        OneImmutable, One( A!.group ),
        FreeGroupAutomaton, A );
    return G;
    end );

InstallGlobalFunction( FGA_newstate,
    function()
    return (rec (delta:=[], deltainv:=[]));
    end );

InstallGlobalFunction( FGA_connectpos,
    function(s1, s2, g)
    s1.delta[g] := s2;
    s2.deltainv[g] := s1;
    end );

InstallGlobalFunction( FGA_connect,
    function(s1, s2, g)
    if g>0 then
        FGA_connectpos(s1, s2, g);
    else
        FGA_connectpos(s2, s1, -g);
    fi;
    end );


InstallGlobalFunction( FGA_define,
    function(state, gen)
    local nstate;
    nstate := FGA_newstate();
    FGA_connect(state, nstate, gen);
    return nstate;  # !!!
    end );

# "active"
InstallGlobalFunction( FGA_find,
    function(s)
    while IsBound(s.isnow) do
        s := s.isnow;
    od;
    return s;
# todo: path compression
    end );

InstallGlobalFunction( FGA_merge,
    function(s1, s2, Q)
    s1 := FGA_find(s1);
    s2 := FGA_find(s2);
    if IsNotIdenticalObj(s1,s2) then
        s2.isnow := s1;
        Add(Q,s2);
    fi;
    end );

InstallGlobalFunction( FGA_coincidence,
    function(s1,s2)
    local Q, s, g, s0, s01, delta, deltainv;
    Q := [];
    FGA_merge(s1, s2, Q);
    for s in Q do
        delta := ShallowCopy(s.delta);
        for g in BoundPositions(delta) do
            Unbind(delta[g].deltainv[g]);
        od;
        deltainv := ShallowCopy(s.deltainv);
        for g in BoundPositions(deltainv) do
            Unbind(deltainv[g].delta[g]);
        od;
        for g in BoundPositions(delta) do
            s0 := FGA_find(s);
            s01 := FGA_find(delta[g]);
            if IsBound(s0.delta[g]) then
                FGA_merge(s01, s0.delta[g], Q);
            elif IsBound(s01.deltainv[g]) then
                FGA_merge(s0, s01.deltainv[g], Q);
            else
                FGA_connectpos(s0, s01, g);
            fi;
        od;
        for g in BoundPositions(deltainv) do
            s0 := FGA_find(s);
            s01 := FGA_find(deltainv[g]);
            if IsBound(s0.deltainv[g]) then
                FGA_merge(s01, s0.deltainv[g], Q);
            elif IsBound(s01.delta[g]) then
                FGA_merge(s0, s01.delta[g], Q);
            else
                FGA_connectpos(s01, s0, g);
            fi;
        od;
    od;
    end );


InstallGlobalFunction( FGA_delta,
    function(state, gen)
    if gen>0 then
        return ATf(state.delta, gen);
    else
        return ATf(state.deltainv, -gen);
    fi;
    end );

InstallGlobalFunction( FGA_deltas,
    function(state, genlist)
    return IteratedF(genlist, FGA_delta, state);
    end );

InstallGlobalFunction( FGA_TmpState,
    function(state, genlist)
    local undo, oldstate, i;
    i := 1;
    while state <> fail and i <= Size(genlist) do
       oldstate := state;
       state := FGA_delta( oldstate, genlist[i] );
       i := i+1;
    od;
    if state = fail then
       i := i-1;
       if genlist[i] > 0 then
           undo := function() Unbind(oldstate.delta[genlist[i]]); end;
       else
           undo := function() Unbind(oldstate.deltainv[-genlist[i]]); end;
       fi;
       state := Iterated( genlist{[i..Size(genlist)]}, FGA_define, oldstate );
    else
       undo := ReturnTrue;
    fi;
    return rec( state:=state, undo:=undo);
    end );

InstallGlobalFunction( FGA_trace,
    function(s,w)
    local i, s1;
    s1 := s;
    i := 1;
    while i <= Length(w) and s1 <> fail do
        s := s1;
        s1 := FGA_delta(s, w[i]);
        i := i+1;
    od;
    if s1 = fail then
        return rec(state:=s, index:=i-1);
    else
        return rec(state:=s1, index:=i);
    fi;
    end );

InstallGlobalFunction( FGA_backtrace,
    function(s,w,j)
    local i, s1;
    s1 := s;
    i := Length(w);
    while i >= j and s1 <> fail do
        s := s1;
        s1 := FGA_delta(s, -w[i]);
        i := i-1;
    od;
    if s1 = fail then
        return rec(state:=s, index:=i+1);
    else
        return rec(state:=s1, index:=i);
    fi;
    end );

InstallGlobalFunction( FGA_InsertGenerator,
    function(s, gen)
    return FGA_InsertGeneratorLetterRep(s, LetterRepAssocWord(gen));
    end );

InstallGlobalFunction( FGA_AutomInsertGeneratorLetterRep,
    function(A, w)
    A!.initial := FGA_InsertGeneratorLetterRep( A!.initial, w);
    A!.terminal := A!.initial;
    end );

InstallGlobalFunction( FGA_InsertGeneratorLetterRep,
    function(s, w)
    local i, t, bt, s1, s2;
    t := FGA_trace(s, w);
    bt := FGA_backtrace(s, w, t.index);
    s1 := t.state;
    s2 := bt.state;
    if t.index > bt.index then  # trace complete
        FGA_coincidence(s1, s2);
    else
        if IsIdenticalObj(s1, s2) then
            while w[t.index] = -w[bt.index] do
                s1 := FGA_define(s1, w[t.index]);
                t.index  := t.index  + 1;
                bt.index := bt.index - 1;
            od;
            s2 := s1;
        fi;
        for i in [t.index .. bt.index-1] do
            s1 := FGA_define(s1, w[i]);
        od;
        FGA_connect(s1, s2, w[bt.index]);
    fi;
    return FGA_find(s);
    end );

InstallGlobalFunction( FGA_FromGroupWithGenerators,
#    gens -> Iterated(gens, FGA_InsertGenerator, FGA_newstate()) );
    function(G)
    local s;
    s := Iterated(GeneratorsOfGroup(G), FGA_InsertGenerator, FGA_newstate());
    return Objectify( NewType( FamilyObj( G ),IsSimpleInvAutomatonRep),
                      rec(initial:=s, terminal:=s, group:=G) );
    end );

InstallGlobalFunction( FGA_FromGeneratorsLetterRep,
    function(gens,G)
    local s;
    s := Iterated(gens, FGA_InsertGeneratorLetterRep, FGA_newstate());
    return Objectify( NewType( FamilyObj( G ),
                      IsSimpleInvAutomatonRep and IsMutable),
                      rec(initial:=s, terminal:=s, group:=G) );
    end );

   
InstallGlobalFunction( FGA_Check,
    function(s, w)
    return IsIdenticalObj(FGA_deltas(s, w), s);
   end );

InstallGlobalFunction( FGA_FindGeneratorsAndStates,
    function(A)
    local Q, Gens, nq, q, i, nr, freegens;
    q := A!.initial;
    nr := 0;
    Gens := [];
    q.repr := [];
    Q := [q];
    for nq in Q do
        freegens := [];
        nr := nr + 1;
        nq.nr := nr;
        for i in BoundPositions(nq.delta) do
            q := nq.delta[i];
            if IsBound(q.repr) then
                if nq.repr = [] or nq.repr[Length(nq.repr)] <> -i then
                    Add(Gens, Concatenation(nq.repr, [i], -Reversed(q.repr)));
                    freegens[i] := Length(Gens);
                fi;
            else
                q.repr := ShallowCopy(nq.repr);
                Add(q.repr, i);
                Add(Q, q);
            fi;
        od;
        for i in BoundPositions(nq.deltainv) do
            q := nq.deltainv[i];
            if not(IsBound(q.repr)) then
                q.repr := ShallowCopy(nq.repr);
                Add(q.repr, -i);
                Add(Q, q);
            fi;
        od;
        if freegens <> [] then
            nq.freegens := freegens;
        fi;
    od;
    ###
    A!.states := Q;
    A!.genslr := Gens;
    end );

InstallGlobalFunction( FGA_initial,
    A -> A!.initial );

InstallGlobalFunction( FGA_repr,
    state -> state.repr );

InstallGlobalFunction( FGA_GeneratorsLetterRep,
    function(A)
    if not IsBound( A!.genslr ) then
        FGA_FindGeneratorsAndStates(A);
    fi;
    return A!.genslr;
    end );

InstallGlobalFunction( FGA_States,
    function(A)
    if not IsBound( A!.states ) then
        FGA_FindGeneratorsAndStates(A);
    fi;
    return A!.states;
    end );
 
InstallGlobalFunction( FGA_reducedPos,
    function(A)
    local i, states, n;
    i := 0;
    states := FGA_States(A);
    repeat
        i := i+1;
        n := Size(BoundPositions(states[i].delta)) +
             Size(BoundPositions(states[i].deltainv));
    until n > 2 or ( n=2 and i=1);
    return i;
    end );

InstallGlobalFunction( FGA_Index,
    function(A)
    local states, r;
    states := FGA_States(A);
    r := Size(FreeGeneratorsOfWholeGroup(A!.group));
    if ForAny( List( states, s -> s.delta),
               delta -> not IsDenseList(delta) or Size(delta) <> r ) then
        return infinity;
    fi;
    return Size(states);
    end );

InstallGlobalFunction( FGA_AsWordLetterRepInFreeGenerators,
    function(g,A)
    local s,x,f,w;
    FGA_States(A); # do work in the automaton if needed
    w := [];
    s := A!.initial;
    for x in g do
        if x > 0 then
            if IsBound(s.freegens) and IsBound(s.freegens[x]) then
                Add(w, s.freegens[x]);
            fi;
            s := ATf(s.delta, x);
            if s = fail then
                return fail;
            fi;
        else
            s := ATf(s.deltainv, -x);
            if s=fail then
                return fail;
            fi;
            if IsBound(s.freegens) and IsBound(s.freegens[-x]) then
                Add(w, -s.freegens[-x]);
            fi;
        fi;
    od;

    if IsNotIdenticalObj( s, A!.terminal ) then
        return fail;
    fi;

    return w;
    end );


#############################################################################
##
#E

Messung
CHZG
869810094

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

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.