Example #1
0
        /// <summary>
        /// Concertize the SFA by including at most k characters in the label.
        /// </summary>
        /// <param name="k">upper limit on the number of included characters in the output automaton, when 0 or negative then include all elements</param>
        /// <returns></returns>
        public Automaton <BDD> Concretize(int k = 0)
        {
            //if (k <= 0)
            //    throw new AutomataException(AutomataExceptionKind.InvalidArgument);

            var mem = new Dictionary <TERM, BDD>();

            var concrete_moves = new List <Move <BDD> >();

            var moveMap = new Dictionary <Tuple <int, int>, BDD>();
            Action <int, int, BDD> AddMove = (from, to, guard) =>
            {
                BDD pred;
                var key = new Tuple <int, int>(from, to);
                if (moveMap.TryGetValue(key, out pred))
                {
                    pred = solver.CharSetProvider.MkOr(pred, guard);
                }
                else
                {
                    pred = guard;
                }
                moveMap[key] = pred;
            };

            Predicate <TERM> IsGround = t =>
            {
                foreach (var v in solver.GetVars(t))
                {
                    return(false);
                }
                return(true);
            };

            foreach (var move in automaton.GetMoves())
            {
                if (move.IsEpsilon)
                {
                    concrete_moves.Add(Move <BDD> .Epsilon(move.SourceState, move.TargetState));
                    continue;
                }
                BDD set;
                if (mem.TryGetValue(move.Label, out set))
                {
                    AddMove(move.SourceState, move.TargetState, set);
                    //concrete_moves.Add(Move<BvSet>.M(move.SourceState, move.TargetState, set));
                    continue;
                }
                if (k > 0)
                {
                    if (IsGround(move.Label))  //must be satisfiable so same as true
                    {
                        set             = solver.CharSetProvider.MkRangeConstraint((char)0, (char)(k - 1));
                        mem[move.Label] = set;
                        AddMove(move.SourceState, move.TargetState, set);
                        //concrete_moves.Add(Move<BvSet>.M(move.SourceState, move.TargetState, set));
                        continue;
                    }
                    var elems = new List <uint>();
                    foreach (var v in solver.MainSolver.FindAllMembers(move.Label))
                    {
                        elems.Add(solver.GetNumeralUInt(v.Value));
                        if (elems.Count == k)
                        {
                            break;
                        }
                    }
                    set             = solver.CharSetProvider.MkSetFromElements(elems, ((int)solver.CharSetProvider.Encoding) - 1);
                    mem[move.Label] = set;
                    AddMove(move.SourceState, move.TargetState, set);
                    //concrete_moves.Add(Move<BvSet>.M(move.SourceState, move.TargetState, set));
                }
                else
                {
                    BDD cond = solver.ConvertToCharSet(solver.CharSetProvider, move.Label);
                    if (cond != null)
                    {
                        throw new AutomataException(AutomataExceptionKind.ConditionCannotBeConvertedToCharSet);
                    }

                    mem[move.Label] = cond;
                    AddMove(move.SourceState, move.TargetState, cond);
                    //concrete_moves.Add(Move<BvSet>.M(move.SourceState, move.TargetState, cond));
                }
            }
            foreach (var entry in moveMap)
            {
                concrete_moves.Add(Move <BDD> .Create(entry.Key.Item1, entry.Key.Item2, entry.Value));
            }

            var res = Automaton <BDD> .Create(this.solver.CharSetProvider, this.automaton.InitialState, this.automaton.GetFinalStates(), concrete_moves);

            return(res);
        }