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); } } }
/* 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); }