Esempio n. 1
0
    /// <inheritdoc/>
    public string ToDot()
    {
        var writer = new DotWriter <TState>(this.StateComparer);

        writer.WriteStart("NFA");

        // Accepting states
        writer.WriteAcceptingStates(this.AcceptingStates);
        // Non-accepting states
        writer.WriteStates(this.States.Except(this.AcceptingStates, this.StateComparer));
        // Initial states
        writer.WriteInitialStates(this.InitialStates);

        // Transitions
        var tupleComparer      = new TupleEqualityComparer <TState, TState>(this.StateComparer, this.StateComparer);
        var transitionsByState = this.Transitions.GroupBy(t => (t.Source, t.Destination), tupleComparer);
        var remainingEpsilon   = this.epsilonTransitions.EpsilonTransitionMap
                                 .ToDictionary(kv => kv.Key, kv => kv.Value.ToHashSet(this.StateComparer), this.StateComparer);

        foreach (var group in transitionsByState)
        {
            var from = group.Key.Item1;
            var to   = group.Key.Item2;
            var on   = string.Join(" U ", group.Select(g => g.Symbol));
            if (this.EpsilonTransitions.Contains(new(from, to)))
            {
                remainingEpsilon[from].Remove(to);
                on = $"{on}, ε";
            }
            writer.WriteTransition(from, on, to);
        }

        // Epsilon-transitions
        foreach (var(from, toSet) in remainingEpsilon)
        {
            foreach (var to in toSet)
            {
                writer.WriteTransition(from, "ε", to);
            }
        }

        writer.WriteEnd();
        return(writer.Code.ToString());
    }