public static Bimachine PseudoMinimal(this Bimachine bm)
    {
        var leftProfiles = bm.Output
                           .GroupBy(
            o => o.Key.Lstate,
            o => (Symbol: o.Key.Symbol, State: o.Key.Rstate, Word: o.Value))
                           .ToDictionary(g => g.Key, g => g.ToList());

        var rightProfiles = bm.Output
                            .GroupBy(
            o => o.Key.Rstate,
            o => (Symbol: o.Key.Symbol, State: o.Key.Lstate, Word: o.Value))
                            .ToDictionary(g => g.Key, g => g.ToList());

        var alphabet   = bm.Left.Transitions.Select(t => t.Key.Label).Distinct();
        var leftEqRel  = FindBmDfaEqRel(bm.Left, leftProfiles, alphabet);
        var rightEqRel = FindBmDfaEqRel(bm.Right, rightProfiles, alphabet);

        var leftMinDfaTrans = bm.Left.Transitions
                              .Select(t => (Key: (leftEqRel[t.Key.From], t.Key.Label), Value: leftEqRel[t.Value]))
                              .Distinct()
                              .ToDictionary(p => p.Key, p => p.Value);

        var leftMinDfa = new Dfsa(
            bm.Left.States.Select(s => leftEqRel[s]).Distinct(),
            leftEqRel[bm.Left.Initial],
            Array.Empty <int>(),
            leftMinDfaTrans);

        var rightMinDfaTrans = bm.Right.Transitions
                               .Select(t => (Key: (rightEqRel[t.Key.From], t.Key.Label), Value: rightEqRel[t.Value]))
                               .Distinct()
                               .ToDictionary(p => p.Key, p => p.Value);

        var rightMinDfa = new Dfsa(
            bm.Right.States.Select(s => rightEqRel[s]).Distinct(),
            rightEqRel[bm.Right.Initial],
            Array.Empty <int>(),
            rightMinDfaTrans);

        var minBmOutput = bm.Output
                          .Select(x => (Key: (leftEqRel[x.Key.Lstate], x.Key.Symbol, rightEqRel[x.Key.Rstate]), Value: x.Value))
                          .Distinct()
                          .ToDictionary(p => p.Key, p => p.Value);

        return(new Bimachine(leftMinDfa, rightMinDfa, minBmOutput));
    }
Exemple #2
0
    public static IList <int> ReverseRecognitionPath(this Dfsa automaton, InputStream input)
    {
        var current = automaton.Initial;
        var path    = new List <int> {
            current
        };

        for (input.SetToEnd(); !input.IsExhausted; input.MoveBackward())
        {
            var symbol = input.Peek();

            if (!automaton.Transitions.ContainsKey((current, symbol)))
            {
                return(path);
            }

            current = automaton.Transitions[(current, symbol)];
Exemple #3
0
    // Removes the states that are not on a successful path in the deterministic automaton.
    public static Dfsa Trim(this Dfsa automaton)
    {
        var reachableStates = automaton.Transitions
                              .Select(t => (t.Key.From, t.Value))
                              .ToHashSet()
                              .TransitiveClosure();

        var newStates = new[] { automaton.Initial }
        .Union(reachableStates
               .Where(pair => pair.Item1 == automaton.Initial)
               .Select(pair => pair.Item2))
        .Intersect(automaton.Final
                   .Union(reachableStates
                          .Where(pair => automaton.Final.Contains(pair.Item2))
                          .Select(pair => pair.Item1)))
        .ToList();

        if (!newStates.Any())
        {
            return(new Dfsa(
                       new[] { 1 },
                       1,
                       Array.Empty <int>(),
                       new Dictionary <(int, char), int>()));
        }

        // States are renamed to their indices in the newStates array
        var newTransitions = automaton.Transitions
                             .Where(t => newStates.Contains(t.Key.From) && newStates.Contains(t.Value))
                             .ToDictionary(
            t => (newStates.IndexOf(t.Key.From), t.Key.Label), // key
            t => newStates.IndexOf(t.Value));                  // value

        return(new Dfsa(
                   newStates.Select(s => newStates.IndexOf(s)),
                   newStates.IndexOf(automaton.Initial),
                   automaton.Final.Intersect(newStates).Select(s => newStates.IndexOf(s)),
                   newTransitions));
    }
 static Dictionary <int, int> FindBmDfaEqRel(
     Dfsa automaton, Dictionary <int, List <(char, int, string)> > profiles, IEnumerable <char> alphabet)
Exemple #5
0
 public static IList <int> RecognitionPathRToL(this Dfsa automaton, string input) =>
 ReverseRecognitionPath(automaton, new InputStream(input));
Exemple #6
0
 public Bimachine(
     Dfsa left,
     Dfsa right,
     IReadOnlyDictionary <(int Lstate, char Symbol, int Rstate), string> output)