示例#1
0
    private IEnumerable <string> GenerateMembers(SymbolicFiniteAutomaton <BinaryDecisionDiagram> sfa, int count)
    {
        if (sfa == null)
        {
            throw new ArgumentNullException(nameof(sfa));
        }
        if (sfa.IsEmpty)
        {
            throw new ArgumentException("Cannot generate a member for an empty state machine.", nameof(sfa));
        }

        return(GenerateMembersIterator());

        IEnumerable <string> GenerateMembersIterator()
        {
            var generatedValues = new HashSet <string>();

            for (var i = 0; i < count; ++i)
            {
                var member   = GenerateMember(sfa);
                var tryCount = Math.Min(100 + generatedValues.Count, 200);
                while (generatedValues.Contains(member) && tryCount-- > 0)
                {
                    member = GenerateMember(sfa);
                }
                if (tryCount < 0 && generatedValues.Contains(member))
                {
                    break;
                }
                generatedValues.Add(member);
                yield return(member);
            }
        }
    }
示例#2
0
    /* Uncomment if we want combinations of regexes together, probably not though
     * private SymbolicFiniteAutomaton<BinaryDecisionDiagram> CreateSFAFromRegexes(params string[] regexes)
     * {
     *  SymbolicFiniteAutomaton<BinaryDecisionDiagram> result = null;
     *  foreach (var regex in regexes)
     *  {
     *      var sfa = _regexConverter.Convert(regex, _options);
     *      result = result == null ? sfa : SymbolicFiniteAutomaton<BinaryDecisionDiagram>.MkProduct(result, sfa, _solver.And, _solver.Or, b => b != _solver.False);
     *      if (result.IsEmpty)
     *          break;
     *  }
     *  return result;
     * }
     */

    private string GenerateMember(SymbolicFiniteAutomaton <BinaryDecisionDiagram> fa)
    {
        var builder = new StringBuilder();
        Move <BinaryDecisionDiagram> nthMoveFrom;

        for (var state = fa.InitialState; !fa.IsFinalState(state) || (fa.OutDegree(state) > 0 && _chooser.ChooseBoolean()); state = nthMoveFrom.TargetState)
        {
            nthMoveFrom = fa.GetNthMoveFrom(state, _chooser.Choose(fa.GetMovesCountFrom(state)));
            if (!nthMoveFrom.IsEpsilon)
            {
                builder.Append(_solver.GenerateMember(_chooser, nthMoveFrom.Condition));
            }
        }
        return(builder.ToString());
    }
    public void Concat(SymbolicFiniteAutomaton <TConstraint> fa)
    {
        foreach (var state in fa.States)
        {
            _delta[state]    = new List <Move <TConstraint> >(fa._delta[state]);
            _deltaInv[state] = new List <Move <TConstraint> >(fa._deltaInv[state]);
        }
        if (HasSingleFinalSink)
        {
            foreach (var finalState in _finalStateSet)
            {
                foreach (Move <TConstraint> move1 in _deltaInv[finalState])
                {
                    _delta[move1.SourceState].Remove(move1);
                    var move2 = Move <TConstraint> .To(move1.SourceState == finalState?fa.InitialState : move1.SourceState, fa.InitialState, move1.Condition);

                    _delta[move2.SourceState].Add(move2);
                    _deltaInv[move2.TargetState].Add(move2);
                }
                _delta.Remove(finalState);
                _deltaInv.Remove(finalState);
            }
            if (_finalStateSet.Contains(InitialState))
            {
                InitialState = fa.InitialState;
            }
            _isEpsilonFree   = _isEpsilonFree && fa._isEpsilonFree;
            _isDeterministic = _isDeterministic && fa._isDeterministic;
        }
        else
        {
            foreach (var finalState in _finalStateSet)
            {
                var move = Move <TConstraint> .Epsilon(finalState, fa.InitialState);

                _delta[finalState].Add(move);
                _deltaInv[fa.InitialState].Add(move);
            }
            _isEpsilonFree   = false;
            _isDeterministic = false;
        }
        _finalStateSet = fa._finalStateSet;
        MaxState       = Math.Max(MaxState, fa.MaxState);
    }
    public static SymbolicFiniteAutomaton <TConstraint> MkProduct(SymbolicFiniteAutomaton <TConstraint> sfa1, SymbolicFiniteAutomaton <TConstraint> sfa2, Func <TConstraint, TConstraint, TConstraint> conjunction, Func <TConstraint, TConstraint, TConstraint> disjunction, Func <TConstraint, bool> isSat)
    {
        sfa1 = sfa1.RemoveEpsilons(disjunction);
        sfa2 = sfa2.RemoveEpsilons(disjunction);
        var dictionary1 = new Dictionary <Pair <int, int>, int>();
        var index1      = new Pair <int, int>(sfa1.InitialState, sfa2.InitialState);
        var pairStack   = new Stack <Pair <int, int> >();

        pairStack.Push(index1);
        dictionary1[index1] = 0;
        var delta = new Dictionary <int, List <Move <TConstraint> > > {
            [0] = new List <Move <TConstraint> >()
        };
        var intList1 = new List <int> {
            0
        };
        var intList2 = new List <int>();

        if (sfa1.IsFinalState(sfa1.InitialState) && sfa2.IsFinalState(sfa2.InitialState))
        {
            intList2.Add(0);
        }
        var state = 1;

        while (pairStack.Count > 0)
        {
            var index2      = pairStack.Pop();
            var sourceState = dictionary1[index2];
            var moveList    = delta[sourceState];
            foreach (var move1 in sfa1.GetMovesFrom(index2.First))
            {
                foreach (var move2 in sfa2.GetMovesFrom(index2.Second))
                {
                    var condition = conjunction(move1.Condition, move2.Condition);
                    if (isSat(condition))
                    {
                        var key = new Pair <int, int>(move1.TargetState, move2.TargetState);
                        if (!dictionary1.TryGetValue(key, out var targetState))
                        {
                            targetState = state;
                            ++state;
                            dictionary1[key] = targetState;
                            intList1.Add(targetState);
                            delta[targetState] = new List <Move <TConstraint> >();
                            pairStack.Push(key);
                            if (sfa1.IsFinalState(move1.TargetState) && sfa2.IsFinalState(move2.TargetState))
                            {
                                intList2.Add(targetState);
                            }
                        }
                        moveList.Add(Move <TConstraint> .To(sourceState, targetState, condition));
                    }
                }
            }
        }
        var dictionary2 = new Dictionary <int, List <Move <TConstraint> > >();

        foreach (var index2 in intList1)
        {
            dictionary2[index2] = new List <Move <TConstraint> >();
        }
        foreach (var index2 in intList1)
        {
            foreach (var move in delta[index2])
            {
                dictionary2[move.TargetState].Add(move);
            }
        }
        var intStack = new Stack <int>(intList2);
        var intSet   = new HashSet <int>(intList2);

        while (intStack.Count > 0)
        {
            foreach (var move in dictionary2[intStack.Pop()])
            {
                if (!intSet.Contains(move.SourceState))
                {
                    intStack.Push(move.SourceState);
                    intSet.Add(move.SourceState);
                }
            }
        }
        if (intSet.Count == 0)
        {
            return(Empty);
        }
        var intList3 = new List <int>();

        foreach (var key in intList1)
        {
            if (!intSet.Contains(key))
            {
                delta.Remove(key);
            }
            else
            {
                intList3.Add(key);
            }
        }
        var intList4 = intList3;

        foreach (var index2 in intList4)
        {
            var moveList = new List <Move <TConstraint> >();
            foreach (var move in delta[index2])
            {
                if (intSet.Contains(move.TargetState))
                {
                    moveList.Add(move);
                }
            }
            delta[index2] = moveList;
        }
        if (intList4.Count == 0)
        {
            return(Empty);
        }
        var sfa = Create(0, intList2, EnumerateMoves(delta));

        sfa._isEpsilonFree   = true;
        sfa._isDeterministic = sfa1.IsDeterministic || sfa2.IsDeterministic;
        return(sfa);
    }