예제 #1
0
        public void TestBVAlgebraCharOperations()
        {
            var css          = new CharSetSolver();
            var regex        = new Regex("(?i:abc[^a-z])");
            var sr           = css.RegexConverter.ConvertToSymbolicRegex(regex, true);
            var mintermsList = new List <BDD>(sr.ComputeMinterms());
            var minterms     = mintermsList.ToArray();
            var all          = css.MkOr(minterms);

            Assert.IsTrue(all.IsFull);
            Assert.AreEqual(5, minterms.Length);
            var bva = BVAlgebra.Create(css, minterms);
            var bv1 = bva.MkBV(1, 2);
            var bv2 = bva.MkBV(2, 3, 4);
            var a   = bva.MkCharConstraint('A');
            var b   = bva.MkCharConstraint('b');
            var c   = bva.MkCharConstraint('C');
            var d   = bva.MkCharConstraint('6');
            var x   = bva.MkCharConstraint('x');

            Assert.AreEqual <ulong>(bva.atoms[bva.dtree.GetId('a')].first, a.first);
            Assert.AreEqual <ulong>(bva.atoms[bva.dtree.GetId('B')].first, b.first);
            Assert.AreEqual <ulong>(bva.atoms[bva.dtree.GetId('C')].first, c.first);
            Assert.AreEqual <ulong>(bva.atoms[bva.dtree.GetId('7')].first, d.first);
            Assert.AreEqual <ulong>(bva.atoms[bva.dtree.GetId('z')].first, x.first);
        }
예제 #2
0
        public void TestCsAlgebra_Mk()
        {
            var css         = new CharSetSolver();
            var aA          = css.MkCharConstraint('a', true);
            var a           = css.MkCharConstraint('a', false);
            var b           = css.MkCharConstraint('b');
            var ab          = css.MkOr(a, b);
            var csa         = new CsAlgebra <BDD>(css, new ICounter[] { new BoundedCounter(0, 4, 5), new BoundedCounter(1, 4, 5), new BoundedCounter(2, 4, 5), });
            var alpha       = csa.MkPredicate(ab, true, CsCondition.TRUE, CsCondition.CANEXIT, CsCondition.TRUE);
            var alpha_cases = alpha.ToArray();

            Assert.IsTrue(alpha_cases.Length == 1);
            Assert.IsTrue(alpha_cases[0].Item2.Equals(ab));
            Assert.IsTrue(alpha_cases[0].Item1.Equals(CsConditionSeq.MkAND(CsCondition.TRUE, CsCondition.CANEXIT, CsCondition.TRUE)));
            var beta  = csa.MkPredicate(aA, true, CsCondition.TRUE, CsCondition.CANLOOP, CsCondition.TRUE);
            var gamma = csa.MkAnd(alpha, beta);
            var res   = new List <Tuple <CsConditionSeq, BDD> >(gamma.GetSumOfProducts());

            Assert.IsTrue(res.Count == 1);
            var counter_cond = res[0].Item1;
            var input_pred   = res[0].Item2;

            Assert.IsTrue(input_pred.Equals(a));
            Assert.IsTrue(counter_cond[1] == CsCondition.MIDDLE);
        }
        /// <summary>
        /// Each transition has the form int[]{fromState, intervalStart, intervalEnd, toState}.
        /// If intervalStart = intervalEnd = -1 then this is an epsilon move.
        /// </summary>
        public static Automaton <BDD> ReadFromRanges(CharSetSolver solver, int initialState, int[] finalStates, IEnumerable <int[]> transitions)
        {
            var moves    = new Dictionary <Pair <int, int>, BDD>();
            var allmoves = new List <Move <BDD> >();

            int[] finals = finalStates;
            foreach (var elems in transitions)
            {
                var key = new Pair <int, int>(elems[0], elems[3]);
                if (elems[1] == -1)
                {
                    allmoves.Add(Move <BDD> .Epsilon(elems[0], elems[3]));
                }
                else
                {
                    var pred = solver.MkCharSetFromRange((char)elems[1], (char)elems[2]);
                    if (moves.ContainsKey(key))
                    {
                        moves[key] = solver.MkOr(moves[key], pred);
                    }
                    else
                    {
                        moves[key] = pred;
                    }
                }
            }
            foreach (var kv in moves)
            {
                allmoves.Add(Move <BDD> .Create(kv.Key.First, kv.Key.Second, kv.Value));
            }

            var aut = Automaton <BDD> .Create(solver, initialState, finals, allmoves);

            return(aut);
        }
예제 #4
0
        public void TestRanges3()
        {
            CharSetSolver solver = new CharSetSolver(BitWidth.BV16);
            BDD           cond   = solver.MkCharSetFromRegexCharClass(@"\d");
            int           cnt    = cond.CountNodes();

            Pair <uint, uint>[] ranges = solver.ToRanges(cond);
            BDD set     = solver.MkCharSetFromRanges(ranges);
            int nodes   = set.CountNodes();
            var ranges2 = new List <Pair <uint, uint> >(ranges);

            ranges2.Reverse();
            BDD set2    = solver.MkCharSetFromRanges(ranges2);
            int nodes2  = set.CountNodes();
            var ranges3 = solver.ToRanges(set2);
            BDD set3    = solver.MkCharSetFromRanges(ranges3);

            int cnt2 = set2.CountNodes();
            int cnt3 = set3.CountNodes();

            Assert.IsTrue(set2 == set3);

            Assert.AreEqual <int>(nodes, nodes2);
            Assert.AreSame(set, set2);

            set.ToDot("digits.dot");

            //check equivalence
            bool equiv = solver.MkOr(solver.MkAnd(cond, solver.MkNot(set)), solver.MkAnd(set, solver.MkNot(cond))) == solver.False;

            Assert.AreEqual <int>(31, ranges.Length);
        }
        /// <summary>
        /// Each transition has the form int[]{fromState, intervalStart, intervalEnd, toState}.
        /// If intervalStart = intervalEnd = -1 then this is an epsilon move.
        /// </summary>
        public static Automaton<BDD> ReadFromRanges(CharSetSolver solver, int initialState, int[] finalStates, IEnumerable<int[]> transitions)
        {
            var moves = new Dictionary<Pair<int, int>, BDD>();
            var allmoves = new List<Move<BDD>>();
            int[] finals = finalStates;
            foreach (var elems in transitions)
            {
                var key = new Pair<int, int>(elems[0], elems[3]);
                if (elems[1] == -1)
                    allmoves.Add(Move<BDD>.Epsilon(elems[0], elems[3]));
                else
                {
                    var pred = solver.MkCharSetFromRange((char)elems[1], (char)elems[2]);
                    if (moves.ContainsKey(key))
                        moves[key] = solver.MkOr(moves[key], pred);
                    else
                        moves[key] = pred;
                }
            }
            foreach (var kv in moves)
                allmoves.Add(Move<BDD>.Create(kv.Key.First, kv.Key.Second, kv.Value));

            var aut = Automaton<BDD>.Create(solver, initialState, finals, allmoves);
            return aut;
        }
        public static Automaton<BDD> Read(CharSetSolver solver, string file)
        {
            var lines = System.IO.File.ReadAllLines(file);
            int initialState = int.Parse(lines[0]);
            var moves = new Dictionary<Pair<int, int>,BDD>();
            var allmoves = new List<Move<BDD>>();
            int[] finals = Array.ConvertAll(lines[1].TrimEnd(' ').Split(' '), s => int.Parse(s));
            for (int i = 2; i < lines.Length; i++)
            {
                int[] elems = Array.ConvertAll(lines[i].TrimEnd(' ').Split(' '), s => int.Parse(s));
                var key = new Pair<int, int>(elems[0], elems[3]);
                if (elems[1] == -1)
                    allmoves.Add(Move<BDD>.Epsilon(elems[0],elems[3]));
                else
                {
                    var pred = solver.MkCharSetFromRange((char)elems[1], (char)elems[2]);
                    if (moves.ContainsKey(key))
                        moves[key] = solver.MkOr(moves[key], pred);
                    else
                        moves[key] = pred;
                }
            }
            foreach (var kv in moves)
                allmoves.Add(Move<BDD>.Create(kv.Key.First, kv.Key.Second, kv.Value));

            var aut = Automaton<BDD>.Create(solver, initialState, finals, allmoves);
            return aut;
        }
예제 #7
0
        public void ChooseUnifromlyTest()
        {
            CharSetSolver solver = new CharSetSolver(BitWidth.BV16);

            BDD    set1    = solver.MkRangeConstraint('\0', '\x01', true);
            BDD    set2    = solver.MkRangeConstraint('\u0FFF', '\u0FFF');
            string set2str = solver.PrettyPrint(set2);
            BDD    set3    = solver.MkRangeConstraint('\u00FF', '\u00FF');
            BDD    set4    = solver.MkRangeConstraint('\u000F', '\u000F');

            BDD set = solver.MkOr(new BDD[] { set2, set3, set4, set1 });

            string setstr = solver.PrettyPrint(set);

            set.ToDot(@"foo.dot");

            var map = new Dictionary <char, int>();

            map['\0']     = 0;
            map['\x01']   = 0;
            map['\u0FFF'] = 0;
            map['\u00FF'] = 0;
            map['\u000F'] = 0;

            for (int i = 0; i < 50000; i++)
            {
                var c = solver.ChooseUniformly(set);
                map[c] += 1;
            }
            foreach (var kv in map)
            {
                Assert.IsTrue(kv.Value > 9700);
            }
        }
예제 #8
0
        public override WS1SFormula Normalize(CharSetSolver solver)
        {
            var ln = left.Normalize(solver);
            var rn = right.Normalize(solver);

            if (ln is WS1SUnaryPred && rn is WS1SUnaryPred)
            {
                var cln = ln as WS1SUnaryPred;
                var crn = rn as WS1SUnaryPred;
                if (cln.set == crn.set)
                {
                    return(new WS1SUnaryPred(cln.set, solver.MkOr(cln.pred, crn.pred)));
                }
            }
            else
            {
                if (ln is WS1STrue || rn is WS1STrue)
                {
                    return(ln);
                }
                if (ln is WS1SFalse)
                {
                    return(rn);
                }
                if (rn is WS1SFalse)
                {
                    return(ln);
                }
            }
            return(new WS1SOr(ln, rn));
        }
예제 #9
0
        public void MkRegexFromAutomatonOf_3_Divisibility()
        {
            var solver = new CharSetSolver(BitWidth.BV7);
            var _0     = solver.MkCharConstraint('a');
            var _3     = solver.MkCharConstraint('d');
            var _03    = solver.MkOr(_0, _3);
            var _1     = solver.MkCharConstraint('b');
            var _2     = solver.MkCharConstraint('c');
            var moves  = new Move <BDD>[] {
                Move <BDD> .Create(0, 0, _03),
                Move <BDD> .Create(0, 1, _2),
                Move <BDD> .Create(0, 2, _1),
                Move <BDD> .Create(1, 1, _03),
                Move <BDD> .Create(1, 0, _1),
                Move <BDD> .Create(1, 2, _2),
                Move <BDD> .Create(2, 2, _03),
                Move <BDD> .Create(2, 0, _2),
                Move <BDD> .Create(2, 1, _1)
            };
            var aut = Automaton <BDD> .Create(solver, 0, new int[] { 0 }, moves);

            //solver.ShowGraph(aut, "div3a");
            string regex = solver.ConvertToRegex(aut).Replace("[ad]", "(a|d)").Replace("[b]", "b").Replace("[c]", "c");
            var    aut2  = solver.Convert(regex).Determinize().MinimizeHopcroft();
            // solver.ShowGraph(aut2, "div3b");
            bool equiv = aut.IsEquivalentWith(aut2);

            Assert.IsTrue(equiv);
            //binary version of the regex
            string regex01 = regex.Replace("a", "00").Replace("b", "01").Replace("c", "10").Replace("d", "11");
            var    bits30  = solver.Convert("^[01]{10,30}\\z");
            var    aut01_  = solver.Convert(regex01).Determinize();
            //solver.ShowGraph(aut01_, "aut01_");
            var aut01 = aut01_.MinimizeHopcroft();
            //solver.ShowGraph(aut01, "aut01");
            string regex01small = solver.ConvertToRegex(aut01);

            aut01 = aut01.Intersect(bits30);
            //genarate some random paths in this automaton and check that the binary representation is a numer that is divisible by 3.
            for (int i = 0; i < 1000; i++)
            {
                string sample = solver.ChooseString(aut01.ChoosePathToSomeFinalState(solver.Chooser));
                int    m      = 0;
                for (int j = sample.Length - 1; j >= 0; j--)
                {
                    if (sample[j] == '0')
                    {
                        m = m << 1;
                    }
                    else
                    {
                        m = (m << 1) | 1;
                    }
                }
                bool div3 = ((m % 3) == 0);
                Assert.IsTrue(div3);
            }
        }
예제 #10
0
파일: WS1S.cs 프로젝트: EgorGumin/Automata
        internal override Automaton <BDD> getAutomaton(SimpleList <string> variables, CharSetSolver solver)
        {
            var pos1 = variables.IndexOf(var1) + ((int)solver.Encoding);
            var pos2 = variables.IndexOf(var2) + ((int)solver.Encoding);

            var both1  = solver.MkAnd(solver.MkBitTrue(pos1), solver.MkBitTrue(pos2));
            var both0  = solver.MkAnd(solver.MkBitFalse(pos1), solver.MkBitFalse(pos2));
            var eqCond = solver.MkOr(both0, both1);

            //Create automaton for condition
            var moves = new Move <BDD>[] { new Move <BDD>(0, 0, eqCond) };

            return(Automaton <BDD> .Create(solver, 0, new int[] { 0 }, moves));//.Determinize(solver).Minimize(solver);
        }
예제 #11
0
        internal static Automaton <BDD> computeDFA(List <string> variables, BDD alphabet, CharSetSolver solver, string set1, string set2)
        {
            var pos1 = variables.IndexOf(set1);
            var pos2 = variables.IndexOf(set2);

            Dictionary <Pair <int, int>, Automaton <BDD> > dic1 = null;
            Pair <int, int> pair = null;

            if (hashing)
            {
                if (!hashedDfa.ContainsKey(alphabet))
                {
                    hashedDfa[alphabet] = new Dictionary <int, Dictionary <Pair <int, int>, Automaton <BDD> > >();
                }

                var dic = hashedDfa[alphabet];

                if (!dic.ContainsKey(variables.Count))
                {
                    dic[variables.Count] = new Dictionary <Pair <int, int>, Automaton <BDD> >();
                }

                dic1 = dic[variables.Count];

                pair = new Pair <int, int>(pos1, pos2);

                if (dic1.ContainsKey(pair))
                {
                    return(dic1[pair]);
                }
            }

            //Create conditions that bit in pos1 is smaller than pos2
            var trueBv     = solver.MkSetFromRange(0, (uint)(Math.Pow(2, variables.Count + 7) - 1), variables.Count + 7 - 1);
            var pos2is1    = solver.MkAnd(trueBv, solver.MkSetWithBitTrue(pos2));
            var pos1is0    = solver.MkAnd(trueBv, solver.MkSetWithBitFalse(pos1));
            var subsetCond = solver.MkOr(pos2is1, pos1is0);


            //Create automaton for condition
            var moves = new Move <BDD>[] { new Move <BDD>(0, 0, subsetCond) };

            var dfa = Automaton <BDD> .Create(0, new int[] { 0 }, moves).Determinize(solver).Minimize(solver);

            if (hashing)
            {
                dic1[pair] = dfa;
            }
            return(dfa);
        }
예제 #12
0
        public Automaton<BDD> getDFA(HashSet<char> alphabet, CharSetSolver solver)
        {            
            //Predicate representing the alphabet
            var alphPred = solver.False;
            foreach (var ch in alphabet)
                alphPred = solver.MkOr(solver.MkCharConstraint(false, ch), alphPred);
            
            var dfa1 =  this.Normalize(solver).PushQuantifiers().getDFA(new List<string>(), alphPred, solver);

            var moves = new List<Move<BDD>>();
            foreach (var move in dfa1.GetMoves())
                foreach (var ch in solver.GenerateAllCharacters(solver.MkAnd(move.Label,alphPred),false))                
                    moves.Add(new Move<BDD>(move.SourceState,move.TargetState,solver.MkCharConstraint(false,ch)));

            return Automaton<BDD>.Create(dfa1.InitialState,dfa1.GetFinalStates(),moves,true,true).Determinize(solver).Minimize(solver);
        }
예제 #13
0
        public void ChooseTest()
        {
            for (int i = 0; i < 10; i++)
            {
                CharSetSolver solver = new CharSetSolver(BitWidth.BV16);

                BDD    set1    = solver.MkRangeConstraint('a', 'c', true);
                string set1str = solver.PrettyPrint(set1);
                BDD    set2    = solver.MkRangeConstraint('a', 'c');
                string set2str = solver.PrettyPrint(set2);
                BDD    set3    = solver.MkRangeConstraint('A', 'C');
                string set3str = solver.PrettyPrint(set3);

                BDD set1a = solver.MkOr(set2, set3);

                Assert.AreEqual <string>("[A-Ca-c]", set1str);
                Assert.AreEqual <string>("[a-c]", set2str);
                Assert.AreEqual <string>("[A-C]", set3str);



                int  h1   = set1.GetHashCode();
                int  h2   = set1a.GetHashCode();
                bool same = (h1 == h2);
                Assert.AreSame(set1, set1a);
                Assert.IsTrue(same);
                Assert.IsTrue(solver.AreEquivalent(set1, set1a));

                //int seed = solver.Chooser.RandomSeed;
                char choice1 = (char)solver.Choose(set1);
                char choice2 = (char)solver.Choose(set1);
                char choice3 = (char)solver.Choose(set1);
                char choice4 = (char)solver.Choose(set1);

                //solver.Chooser.RandomSeed = seed;
                //char choice1a = solver.Choose(set1a);
                //char choice2a = solver.Choose(set1a);
                //char choice3a = solver.Choose(set1a);
                //char choice4a = solver.Choose(set1a);

                //string s = new String(new char[] { choice1, choice2, choice3, choice4 });
                //string sa = new String(new char[] { choice1a, choice2a, choice3a, choice4a });

                //Assert.AreEqual<string>(s, sa);
            }
        }
예제 #14
0
        public void ChooseTest2()
        {
            CharSetSolver solver = new CharSetSolver(BitWidth.BV16);

            BDD    set1    = solver.MkRangeConstraint('a', 'a', true);
            string set1str = solver.PrettyPrint(set1);
            BDD    set2    = solver.MkRangeConstraint('a', 'a');
            string set2str = solver.PrettyPrint(set2);
            BDD    set3    = solver.MkRangeConstraint('A', 'A');
            string set3str = solver.PrettyPrint(set3);

            BDD set1a = solver.MkOr(set2, set3);

            Assert.AreEqual <string>("[Aa]", set1str);
            Assert.AreEqual <string>("a", set2str);
            Assert.AreEqual <string>("A", set3str);
        }
예제 #15
0
        public void ChooseTest2()
        {
            CharSetSolver solver = new CharSetSolver(BitWidth.BV16);

            BDD set1 = solver.MkRangeConstraint('a', 'a', true);
            string set1str = solver.PrettyPrint(set1);
            BDD set2 = solver.MkRangeConstraint('a', 'a');
            string set2str = solver.PrettyPrint(set2);
            BDD set3 = solver.MkRangeConstraint('A', 'A');
            string set3str = solver.PrettyPrint(set3);

            BDD set1a = solver.MkOr(set2, set3);

            Assert.AreEqual<string>("[Aa]", set1str);
            Assert.AreEqual<string>("a", set2str);
            Assert.AreEqual<string>("A", set3str);
        }
예제 #16
0
        internal static Automaton <BDD> computeDFA(List <string> variables, BDD alphabet, CharSetSolver solver, string set1, string set2)
        {
            int pos1 = variables.IndexOf(set1);
            int pos2 = variables.IndexOf(set2);

            Dictionary <int, Dictionary <Pair <int, int>, Automaton <BDD> > > dic1;

            if (!hashedDfa.ContainsKey(alphabet))
            {
                hashedDfa[alphabet] = new Dictionary <int, Dictionary <Pair <int, int>, Automaton <BDD> > >();
            }

            dic1 = hashedDfa[alphabet];

            Dictionary <Pair <int, int>, Automaton <BDD> > dic2;

            if (!dic1.ContainsKey(variables.Count))
            {
                dic1[variables.Count] = new Dictionary <Pair <int, int>, Automaton <BDD> >();
            }

            dic2 = dic1[variables.Count];

            var hash = new Pair <int, int>(pos1, pos2);

            if (dic2.ContainsKey(hash))
            {
                return(dic2[hash]);
            }

            //Create conditions that bit in pos1 is smaller than pos2
            var trueBv = solver.MkSetFromRange(0, (uint)(Math.Pow(2, variables.Count + 16) - 1), variables.Count + 16 - 1);
            var both1  = solver.MkAnd(new BDD[] { trueBv, solver.MkSetWithBitTrue(pos1), solver.MkSetWithBitTrue(pos2) });
            var both0  = solver.MkAnd(new BDD[] { trueBv, solver.MkSetWithBitFalse(pos1), solver.MkSetWithBitFalse(pos2) });
            var eqCond = solver.MkOr(new BDD[] { both0, both1 });

            //Create automaton for condition
            var moves = new Move <BDD>[] { new Move <BDD>(0, 0, eqCond) };
            var dfa   = Automaton <BDD> .Create(0, new int[] { 0 }, moves).Determinize(solver).Minimize(solver);

            if (hashing)
            {
                dic2[hash] = dfa;
            }
            return(dfa);
        }
예제 #17
0
파일: WS1S.cs 프로젝트: EgorGumin/Automata
        internal override Automaton <BDD> getAutomaton(SimpleList <string> variables, CharSetSolver solver)
        {
            var k = variables.IndexOf(var) + ((int)solver.Encoding);
            //var trueBv = MkTrue(variables, solver);

            //Compute predicates for k-th bit is 0 or 1
            //var posIs1 = solver.MkAnd(new BDD[] { trueBv, solver.MkSetWithBitTrue(k), solver.ShiftLeft(pred, variables.Count) });
            //var posIs0 = solver.MkAnd(trueBv, solver.MkSetWithBitFalse(k));
            var posIs1 = solver.MkAnd(solver.MkBitTrue(k), pred);
            var posIs0 = solver.MkBitFalse(k);
            var psi    = solver.MkOr(posIs0, posIs1);

            //Create automaton for condition
            var moves = new Move <BDD>[] { new Move <BDD>(0, 0, psi) };

            return(Automaton <BDD> .Create(solver, 0, new int[] { 0 }, moves));
        }
        public DensityFeedback(FeedbackLevel level, HashSet <char> alphabet, Automaton <BDD> dfaGoal, Automaton <BDD> dfaAttempt, double utility, CharSetSolver solver)
            : base(level, alphabet, utility, solver)
        {
            BDD pred = solver.False;

            foreach (var el in alphabet)
            {
                pred = solver.MkOr(pred, solver.MkCharConstraint(false, el));
            }

            var dfaAll = Automaton <BDD> .Create(0, new int[] { 0 }, new Move <BDD>[] { new Move <BDD>(0, 0, pred) });

            this.type = FeedbackType.Density;
            this.positiveDifference  = dfaGoal.Minus(dfaAttempt, solver).Determinize(solver).Minimize(solver);
            this.negativeDifference  = dfaAttempt.Minus(dfaGoal, solver).Determinize(solver).Minimize(solver);
            this.symmetricDifference = dfaAll.Minus(dfaAll.Minus(positiveDifference, solver).Intersect(dfaAll.Minus(negativeDifference, solver), solver), solver).Determinize(solver).Minimize(solver);
            this.solver = solver;
        }
예제 #19
0
        public void ChooseTest()
        {
            for (int i = 0; i < 10; i++)
            {
                CharSetSolver solver = new CharSetSolver(BitWidth.BV16);

                BDD set1 = solver.MkRangeConstraint('a', 'c', true);
                string set1str = solver.PrettyPrint(set1);
                BDD set2 = solver.MkRangeConstraint('a', 'c');
                string set2str = solver.PrettyPrint(set2);
                BDD set3 = solver.MkRangeConstraint( 'A', 'C');
                string set3str = solver.PrettyPrint(set3);

                BDD set1a = solver.MkOr(set2, set3);

                Assert.AreEqual<string>("[A-Ca-c]",set1str);
                Assert.AreEqual<string>("[a-c]", set2str);
                Assert.AreEqual<string>("[A-C]", set3str);

                int h1 = set1.GetHashCode();
                int h2 = set1a.GetHashCode();
                bool same = (h1 == h2);
                Assert.AreSame(set1, set1a);
                Assert.IsTrue(same);
                Assert.IsTrue(solver.AreEquivalent(set1, set1a));

                //int seed = solver.Chooser.RandomSeed;
                char choice1 = (char)solver.Choose(set1);
                char choice2 = (char)solver.Choose(set1);
                char choice3 = (char)solver.Choose(set1);
                char choice4 = (char)solver.Choose(set1);

                //solver.Chooser.RandomSeed = seed;
                //char choice1a = solver.Choose(set1a);
                //char choice2a = solver.Choose(set1a);
                //char choice3a = solver.Choose(set1a);
                //char choice4a = solver.Choose(set1a);

                //string s = new String(new char[] { choice1, choice2, choice3, choice4 });
                //string sa = new String(new char[] { choice1a, choice2a, choice3a, choice4a });

                //Assert.AreEqual<string>(s, sa);
            }
        }
        // automata come already determinized
        public NFACounterexampleFeedback(
            FeedbackLevel level, HashSet <char> alphabet,
            Automaton <BDD> solutionDFA, Automaton <BDD> attemptDFA,
            CharSetSolver solver)
            : base(level, alphabet, solver)
        {
            BDD pred = solver.False;

            foreach (var el in alphabet)
            {
                pred = solver.MkOr(pred, solver.MkCharConstraint(false, el));
            }

            var dfaAll = Automaton <BDD> .Create(0, new int[] { 0 }, new Move <BDD>[] { new Move <BDD>(0, 0, pred) });

            this.positiveDifference = solutionDFA.Minus(attemptDFA, solver).Determinize(solver).Minimize(solver);
            this.negativeDifference = attemptDFA.Minus(solutionDFA, solver).Determinize(solver).Minimize(solver);
            this.solver             = solver;
        }
        private static BDD BDDOf(IEnumerable <char> alphabet, CharSetSolver solver)
        {
            bool fst          = true;
            BDD  safeCharCond = null;

            foreach (var c in alphabet)
            {
                if (fst)
                {
                    fst          = false;
                    safeCharCond = solver.MkCharConstraint(false, c);
                }
                else
                {
                    safeCharCond = solver.MkOr(safeCharCond, solver.MkCharConstraint(false, c));
                }
            }
            return(safeCharCond);
        }
예제 #22
0
파일: WS1S.cs 프로젝트: EgorGumin/Automata
        internal override Automaton <BDD> getAutomaton(SimpleList <string> variables, CharSetSolver solver)
        {
            var pos1 = variables.IndexOf(X1) + ((int)solver.Encoding);
            var pos2 = variables.IndexOf(X2) + ((int)solver.Encoding);

            //pos1is1 implies pos2is1
            //  is equivalent to
            //not(pos1is1) or pos2is1
            //  is equivalent to
            //pos1is0 or pos2is1
            //var trueBv = MkTrue(variables, solver);
            var pos2is1    = solver.MkBitTrue(pos2);
            var pos1is0    = solver.MkBitFalse(pos1);
            var subsetCond = solver.MkOr(pos1is0, pos2is1);


            //Create automaton for condition
            var moves = new Move <BDD>[] { new Move <BDD>(0, 0, subsetCond) };

            return(Automaton <BDD> .Create(solver, 0, new int[] { 0 }, moves));//.Determinize(solver).Minimize(solver);
        }
예제 #23
0
        public List <Transduction> AvailableMoves()
        {
            IEnumerable <Move <BvSet> > movesFromCurrent = moveAutomaton.GetMovesFrom(currentState);
            BvSet       availableMoves = solver.MkAnd(solver.MkCharConstraint(true, '2'), solver.MkCharConstraint(true, '3'));
            List <char> charl;

            foreach (Move <BvSet> m in movesFromCurrent)
            {
                charl          = solver.GenerateAllCharacters(m.Condition, false).ToList();
                availableMoves = solver.MkOr(m.Condition, availableMoves);
            }
            List <Transduction> movel = new List <Transduction>();
            IEnumerable <char>  chare = solver.GenerateAllCharacters(availableMoves, false);

            //charl = chare.ToList();
            foreach (Char c in chare)
            {
                movel.Add(TransductionUtil.ToMove(c));
            }

            return(movel);
        }
        public static Automaton <BDD> ReadFromString(CharSetSolver solver, string automaton)
        {
            var lines        = automaton.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
            int initialState = int.Parse(lines[0]);
            var moves        = new Dictionary <Pair <int, int>, BDD>();
            var allmoves     = new List <Move <BDD> >();

            int[] finals = Array.ConvertAll(lines[1].TrimEnd(' ').Split(' '), s => int.Parse(s));
            for (int i = 2; i < lines.Length; i++)
            {
                int[] elems = Array.ConvertAll(lines[i].TrimEnd(' ').Split(' '), s => int.Parse(s));
                var   key   = new Pair <int, int>(elems[0], elems[3]);
                if (elems[1] == -1)
                {
                    allmoves.Add(Move <BDD> .Epsilon(elems[0], elems[3]));
                }
                else
                {
                    var pred = solver.MkCharSetFromRange((char)elems[1], (char)elems[2]);
                    if (moves.ContainsKey(key))
                    {
                        moves[key] = solver.MkOr(moves[key], pred);
                    }
                    else
                    {
                        moves[key] = pred;
                    }
                }
            }
            foreach (var kv in moves)
            {
                allmoves.Add(Move <BDD> .Create(kv.Key.First, kv.Key.Second, kv.Value));
            }

            var aut = Automaton <BDD> .Create(solver, initialState, finals, allmoves);

            return(aut);
        }
예제 #25
0
        public static Automaton <BDD> Read(CharSetSolver solver, string file)
        {
            var lines        = System.IO.File.ReadAllLines(file);
            int initialState = int.Parse(lines[0]);
            var moves        = new Dictionary <Tuple <int, int>, BDD>();
            var allmoves     = new List <Move <BDD> >();

            int[] finals = Array.ConvertAll(lines[1].TrimEnd(' ').Split(' '), s => int.Parse(s));
            for (int i = 2; i < lines.Length; i++)
            {
                int[] elems = Array.ConvertAll(lines[i].TrimEnd(' ').Split(' '), s => int.Parse(s));
                var   key   = new Tuple <int, int>(elems[0], elems[3]);
                if (elems[1] == -1)
                {
                    allmoves.Add(Move <BDD> .Epsilon(elems[0], elems[3]));
                }
                else
                {
                    var pred = solver.MkCharSetFromRange((char)elems[1], (char)elems[2]);
                    if (moves.ContainsKey(key))
                    {
                        moves[key] = solver.MkOr(moves[key], pred);
                    }
                    else
                    {
                        moves[key] = pred;
                    }
                }
            }
            foreach (var kv in moves)
            {
                allmoves.Add(Move <BDD> .Create(kv.Key.Item1, kv.Key.Item2, kv.Value));
            }

            var aut = Automaton <BDD> .Create(solver, initialState, finals, allmoves);

            return(aut);
        }
        /// <summary>
        /// Returns an automaton where transitions between states are collapsed to a single one
        /// </summary>
        /// <param name="automaton"></param>
        /// <param name="solver"></param>
        /// <returns></returns>
        public static Automaton <BDD> normalizeMoves(Automaton <BDD> automaton, CharSetSolver solver)
        {
            List <Move <BDD> > normMoves = new List <Move <BDD> >();

            foreach (var sourceState in automaton.States)
            {
                Dictionary <int, BDD> moveConditions = new Dictionary <int, BDD>();
                foreach (var moveFromSourceState in automaton.GetMovesFrom(sourceState))
                {
                    var target       = moveFromSourceState.TargetState;
                    BDD oldCondition = null;
                    if (moveConditions.ContainsKey(target))
                    {
                        oldCondition = moveConditions[target];
                    }
                    else
                    {
                        oldCondition = solver.False;
                    }

                    if (!moveFromSourceState.IsEpsilon)
                    {
                        moveConditions[target] = solver.MkOr(oldCondition, moveFromSourceState.Label);
                    }
                    else
                    {
                        normMoves.Add(moveFromSourceState);
                    }
                }

                foreach (var targetState in moveConditions.Keys)
                {
                    normMoves.Add(new Move <BDD>(sourceState, targetState, moveConditions[targetState]));
                }
            }

            return(Automaton <BDD> .Create(automaton.InitialState, automaton.GetFinalStates(), normMoves));
        }
예제 #27
0
        public Automaton <BDD> getDFA(HashSet <char> alphabet, CharSetSolver solver)
        {
            //Predicate representing the alphabet
            var alphPred = solver.False;

            foreach (var ch in alphabet)
            {
                alphPred = solver.MkOr(solver.MkCharConstraint(false, ch), alphPred);
            }

            var dfa1 = this.Normalize(solver).PushQuantifiers().getDFA(new List <string>(), alphPred, solver);

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

            foreach (var move in dfa1.GetMoves())
            {
                foreach (var ch in solver.GenerateAllCharacters(solver.MkAnd(move.Label, alphPred), false))
                {
                    moves.Add(new Move <BDD>(move.SourceState, move.TargetState, solver.MkCharConstraint(false, ch)));
                }
            }

            return(Automaton <BDD> .Create(dfa1.InitialState, dfa1.GetFinalStates(), moves, true, true).Determinize(solver).Minimize(solver));
        }
 private static BDD BDDOf(IEnumerable<char> alphabet, CharSetSolver solver)
 {
     bool fst = true;
     BDD safeCharCond = null;
     foreach (var c in alphabet)
         if (fst)
         {
             fst = false;
             safeCharCond = solver.MkCharConstraint(false, c);
         }
         else
             safeCharCond = solver.MkOr(safeCharCond, solver.MkCharConstraint(false, c));
     return safeCharCond;
 }
예제 #29
0
        public void TestRanges3()
        {
            CharSetSolver solver = new CharSetSolver(BitWidth.BV16);
            BDD cond = solver.MkCharSetFromRegexCharClass(@"\d");
            int cnt = cond.CountNodes();
            Pair<uint, uint>[] ranges = solver.ToRanges(cond);
            BDD set = solver.MkCharSetFromRanges(ranges);
            int nodes = set.CountNodes();
            var ranges2 = new List<Pair<uint, uint>>(ranges);
            ranges2.Reverse();
            BDD set2 = solver.MkCharSetFromRanges(ranges2);
            int nodes2 = set.CountNodes();
            var ranges3 = solver.ToRanges(set2);
            BDD set3 = solver.MkCharSetFromRanges(ranges3);

            int cnt2 = set2.CountNodes();
            int cnt3 = set3.CountNodes();
            Assert.IsTrue(set2 == set3);

            Assert.AreEqual<int>(nodes, nodes2);
            Assert.AreSame(set,set2);

            set.ToDot("digits.dot");

            //check equivalence
            bool equiv = solver.MkOr(solver.MkAnd(cond, solver.MkNot(set)), solver.MkAnd(set, solver.MkNot(cond))) == solver.False;

            Assert.AreEqual<int>(31, ranges.Length);
        }
        private static void WriteRangeFields(BitWidth encoding, StreamWriter sw, string field)
        {
            int bits    = (int)encoding;
            int maxChar = (1 << bits) - 1;
            var catMap  = new Dictionary <UnicodeCategory, Ranges>();

            for (int c = 0; c < 30; c++)
            {
                catMap[(UnicodeCategory)c] = new Ranges();
            }
            Ranges whitespace    = new Ranges();
            Ranges wordcharacter = new Ranges();

            for (int i = 0; i <= maxChar; i++)
            {
                char ch = (char)i;
                if (char.IsWhiteSpace(ch))
                {
                    whitespace.Add(i);
                }
                UnicodeCategory cat = char.GetUnicodeCategory(ch);
                catMap[cat].Add(i);
                int catCode = (int)cat;
                //in .NET 3.5
                if (bits == 7)
                {
                    if (catCode == 0 || catCode == 1 || catCode == 2 || catCode == 3 || catCode == 4 || catCode == 5 || catCode == 8 || catCode == 18)
                    {
                        wordcharacter.Add(i);
                    }
                }
            }
            //generate bdd reprs for each of the category ranges
            BDD[]         catBDDs = new BDD[30];
            CharSetSolver bddb    = new CharSetSolver(encoding);

            for (int c = 0; c < 30; c++)
            {
                catBDDs[c] = bddb.MkBddForIntRanges(catMap[(UnicodeCategory)c].ranges);
            }

            BDD whitespaceBdd = bddb.MkBddForIntRanges(whitespace.ranges);

            //in .NET 3.5 category 5 was NOT a word character
            //union of categories 0,1,2,3,4,8,18
            BDD wordCharBdd = bddb.MkOr(catBDDs[0],
                                        bddb.MkOr(catBDDs[1],
                                                  bddb.MkOr(catBDDs[2],
                                                            bddb.MkOr(catBDDs[3],
                                                                      bddb.MkOr(catBDDs[4],
                                                                                bddb.MkOr(catBDDs[5],
                                                                                          bddb.MkOr(catBDDs[8], catBDDs[18])))))));

            if (bits == 7)
            {
                sw.WriteLine(@"/// <summary>
/// Array of 30 UnicodeCategory ranges. Each entry is a pair of integers. 
/// corresponding to the lower and upper bounds of the unicodes of the characters
/// that have the given UnicodeCategory code (between 0 and 29).
/// </summary>");
                sw.WriteLine("public static int[][][] " + field + " = new int[][][]{");
                foreach (UnicodeCategory c in catMap.Keys)
                {
                    sw.WriteLine("//{0}({1}):", c, (int)c);
                    if (catMap[c].Count == 0)
                    {
                        sw.WriteLine("null,");
                    }
                    else
                    {
                        sw.WriteLine("new int[][]{");
                        foreach (int[] range in catMap[c].ranges)
                        {
                            sw.WriteLine("    new int[]{" + string.Format("{0},{1}", range[0], range[1]) + "},");
                        }
                        sw.WriteLine("},");
                    }
                }
                sw.WriteLine("};");
            }

            sw.WriteLine(@"/// <summary>
/// Compact BDD encodings of the categories.
/// </summary>");
            sw.WriteLine("public static int[][] " + field + "Bdd = new int[][]{");
            foreach (UnicodeCategory c in catMap.Keys)
            {
                sw.WriteLine("//{0}({1}):", c, (int)c);
                BDD catBdd = catBDDs[(int)c];
                if (catBdd == null || catBdd.IsEmpty)
                {
                    sw.WriteLine("null, //false");
                }
                else if (catBdd.IsFull)
                {
                    sw.WriteLine("new int[]{0,0}, //true");
                }
                else
                {
                    sw.WriteLine("new int[]{");
                    foreach (var arc in bddb.SerializeCompact(catBdd))
                    {
                        sw.WriteLine("{0},", arc);
                    }
                    sw.WriteLine("},");
                }
            }
            sw.WriteLine("};");

            if (bits == 7)
            {
                sw.WriteLine(@"/// <summary>
/// Whitespace character ranges.
/// </summary>");
                sw.WriteLine("public static int[][] " + field + "Whitespace = new int[][]{");
                foreach (int[] range in whitespace.ranges)
                {
                    sw.WriteLine("    new int[]{" + string.Format("{0},{1}", range[0], range[1]) + "},");
                }
                sw.WriteLine("};");

                sw.WriteLine(@"/// <summary>
/// Word character ranges.
/// </summary>");
                sw.WriteLine("public static int[][] " + field + "WordCharacter = new int[][]{");
                foreach (int[] range in wordcharacter.ranges)
                {
                    sw.WriteLine("    new int[]{" + string.Format("{0},{1}", range[0], range[1]) + "},");
                }
                sw.WriteLine("};");
            }

            sw.WriteLine(@"/// <summary>
/// Compact BDD encoding of the whitespace characters.
/// </summary>");
            sw.WriteLine("public static int[] " + field + "WhitespaceBdd = new int[]{");
            foreach (var arc in bddb.SerializeCompact(whitespaceBdd))
            {
                sw.WriteLine("{0},", arc);
            }
            sw.WriteLine("};");

            sw.WriteLine(@"/// <summary>
/// Compact BDD encoding of word characters
/// </summary>");
            sw.WriteLine("public static int[] " + field + "WordCharacterBdd = new int[]{");
            foreach (var arc in bddb.SerializeCompact(wordCharBdd))
            {
                sw.WriteLine("{0},", arc);
            }
            sw.WriteLine("};");
        }
        // looks for an edit at depth "depth"
        // returns false and null in bestScript if no edit is found at depth "depth"
        // returns false and not null in bestScript if found
        // returns true if timeout
        internal bool GetNFAEditScriptTimeout(
            int depth, long lastEditHash,
            Automaton <BDD> currentNfa2,
            List <NFAEdit> editList, int scriptCost,
            NFAEditScript bestScript)
        {
            // if timeout return true
            if (sw.ElapsedMilliseconds > timeout)
            {
                return(true);
            }


            //Stop if no more moves left
            if (depth == 0)
            {
                if (DFAUtilities.ApproximateMNEquivalent(tests, nfa1density, currentNfa2, al, solver) && currentNfa2.IsEquivalentWith(nfa1, solver))
                {
                    //check if totalCost < finalScript cost and replace if needed
                    if (bestScript.script == null || scriptCost < bestScript.GetCost())
                    {
                        bestScript.script = ObjectCopier.Clone <List <NFAEdit> >(editList);
                    }
                }
                return(false);
            }

            NFAEdit edit = null;

            long thisEditHash = 0;

            #region Flip one state from fin to non fin
            foreach (var state in currentNfa2.States)
            {
                thisEditHash = state;
                if (CanAdd(thisEditHash, lastEditHash))
                {
                    //flip its final non final status

                    var             newFinalStates = new HashSet <int>(currentNfa2.GetFinalStates());
                    Automaton <BDD> nfa2new        = null;
                    if (currentNfa2.GetFinalStates().Contains(state))
                    {
                        edit = new NFAEditState(state, false);
                        editList.Insert(0, edit);
                        newFinalStates.Remove(state);
                        nfa2new = Automaton <BDD> .Create(currentNfa2.InitialState, newFinalStates, currentNfa2.GetMoves());
                    }
                    else
                    {
                        edit = new NFAEditState(state, true);
                        editList.Insert(0, edit);
                        newFinalStates.Add(state);
                        nfa2new = Automaton <BDD> .Create(currentNfa2.InitialState, newFinalStates, currentNfa2.GetMoves());
                    }

                    if (GetNFAEditScriptTimeout(depth - 1, thisEditHash, nfa2new, editList, scriptCost + edit.GetCost(), bestScript))
                    {
                        return(true);
                    }

                    editList.RemoveAt(0);
                }
            }
            #endregion

            #region Change transition from source state
            currentNfa2 = NFAUtilities.normalizeMoves(currentNfa2, solver);
            foreach (var sourceState in currentNfa2.States)
            {
                HashSet <int> unreachedStates = new HashSet <int>(currentNfa2.States);
                foreach (var moveFromSource in currentNfa2.GetMovesFrom(sourceState))
                {
                    // take all chars in alphabet
                    foreach (var c in al)
                    {
                        long moveHash = currentNfa2.StateCount + IntegerUtil.TripleToInt(sourceState, moveFromSource.TargetState, alphabetMap[c]);
                        thisEditHash = currentNfa2.StateCount + moveHash;
                        if (CanAdd(thisEditHash, lastEditHash))
                        {
                            BDD cCond   = solver.False;
                            BDD newCond = solver.False;

                            //skip epsilon moves
                            if (moveFromSource.Label != null)
                            {
                                // if c in move, remove it and recursion
                                if (solver.Contains(moveFromSource.Label, c))
                                {
                                    cCond   = solver.MkNot(solver.MkCharConstraint(false, c));
                                    newCond = solver.MkAnd(moveFromSource.Label, cCond);
                                }
                                else // if c not in move, add it and recursion
                                {
                                    cCond   = solver.MkCharConstraint(false, c);
                                    newCond = solver.MkOr(moveFromSource.Label, cCond);
                                }

                                var newMoves = new List <Move <BDD> >(currentNfa2.GetMoves());
                                newMoves.Remove(moveFromSource);
                                newMoves.Add(new Move <BDD>(sourceState, moveFromSource.TargetState, newCond));
                                var nfa2new = Automaton <BDD> .Create(currentNfa2.InitialState, currentNfa2.GetFinalStates(), newMoves);

                                edit = new NFAEditMove(sourceState, moveFromSource.TargetState, c);
                                editList.Insert(0, edit);

                                if (GetNFAEditScriptTimeout(depth - 1, thisEditHash, nfa2new, editList, scriptCost + edit.GetCost(), bestScript))
                                {
                                    return(true);
                                }

                                editList.RemoveAt(0);
                            }
                        }
                    }

                    unreachedStates.Remove(moveFromSource.TargetState);
                }

                foreach (var targetState in unreachedStates)
                {
                    //try adding a symbol not in transition
                    foreach (var c in al)
                    {
                        long moveHash = IntegerUtil.TripleToInt(sourceState, targetState, alphabetMap[c]);
                        thisEditHash = currentNfa2.StateCount + moveHash;

                        var moveCond = solver.MkCharConstraint(false, c);
                        var newMoves = new List <Move <BDD> >(currentNfa2.GetMoves());
                        newMoves.Add(new Move <BDD>(sourceState, targetState, moveCond));
                        var nfa2new = Automaton <BDD> .Create(currentNfa2.InitialState, currentNfa2.GetFinalStates(), newMoves);

                        edit = new NFAEditMove(sourceState, targetState, c);
                        editList.Insert(0, edit);

                        //TODO put correct hash
                        if (GetNFAEditScriptTimeout(depth - 1, thisEditHash, nfa2new, editList, scriptCost + edit.GetCost(), bestScript))
                        {
                            return(true);
                        }

                        editList.RemoveAt(0);
                    }
                }
            }
            #endregion

            return(false);
        }
        private static void WriteRangeFields(BitWidth encoding, StreamWriter sw, string field)
        {
            int bits = (int)encoding;
            int maxChar = (1 << bits) - 1;
            var catMap = new Dictionary<UnicodeCategory, Ranges>();
            for (int c = 0; c < 30; c++)
                catMap[(UnicodeCategory)c] = new Ranges();
            Ranges whitespace = new Ranges();
            Ranges wordcharacter = new Ranges();
            for (int i = 0; i <= maxChar; i++)
            {
                char ch = (char)i;
                if (char.IsWhiteSpace(ch))
                    whitespace.Add(i);
                UnicodeCategory cat = char.GetUnicodeCategory(ch);
                catMap[cat].Add(i);
                int catCode = (int)cat;
                //in .NET 3.5
                if (bits == 7)
                    if (catCode == 0 || catCode == 1 || catCode == 2 || catCode == 3 || catCode == 4 || catCode == 5 || catCode == 8 || catCode == 18)
                        wordcharacter.Add(i);
            }
            //generate bdd reprs for each of the category ranges
            BDD[] catBDDs = new BDD[30];
            CharSetSolver bddb = new CharSetSolver(encoding);
            for (int c = 0; c < 30; c++)
                catBDDs[c] = bddb.MkBddForIntRanges(catMap[(UnicodeCategory)c].ranges);

            BDD whitespaceBdd = bddb.MkBddForIntRanges(whitespace.ranges);

            //in .NET 3.5 category 5 was NOT a word character
            //union of categories 0,1,2,3,4,8,18
            BDD wordCharBdd = bddb.MkOr(catBDDs[0],
                              bddb.MkOr(catBDDs[1],
                              bddb.MkOr(catBDDs[2],
                              bddb.MkOr(catBDDs[3],
                              bddb.MkOr(catBDDs[4],
                              bddb.MkOr(catBDDs[5],
                              bddb.MkOr(catBDDs[8], catBDDs[18])))))));
            if (bits == 7)
            {
                sw.WriteLine(@"/// <summary>
            /// Array of 30 UnicodeCategory ranges. Each entry is a pair of integers.
            /// corresponding to the lower and upper bounds of the unicodes of the characters
            /// that have the given UnicodeCategory code (between 0 and 29).
            /// </summary>");
                sw.WriteLine("public static int[][][] " + field + " = new int[][][]{");
                foreach (UnicodeCategory c in catMap.Keys)
                {
                    sw.WriteLine("//{0}({1}):", c, (int)c);
                    if (catMap[c].Count == 0)
                        sw.WriteLine("null,");
                    else
                    {
                        sw.WriteLine("new int[][]{");
                        foreach (int[] range in catMap[c].ranges)
                            sw.WriteLine("    new int[]{" + string.Format("{0},{1}", range[0], range[1]) + "},");
                        sw.WriteLine("},");
                    }
                }
                sw.WriteLine("};");
            }

            sw.WriteLine(@"/// <summary>
            /// Compact BDD encodings of the categories.
            /// </summary>");
            sw.WriteLine("public static int[][] " + field + "Bdd = new int[][]{");
            foreach (UnicodeCategory c in catMap.Keys)
            {
                sw.WriteLine("//{0}({1}):", c, (int)c);
                BDD catBdd = catBDDs[(int)c];
                if (catBdd == null || catBdd.IsEmpty)
                    sw.WriteLine("null, //false");
                else if (catBdd.IsFull)
                    sw.WriteLine("new int[]{0,0}, //true");
                else
                {
                    sw.WriteLine("new int[]{");
                    foreach (var arc in bddb.SerializeCompact(catBdd))
                        sw.WriteLine("{0},", arc);
                    sw.WriteLine("},");
                }
            }
            sw.WriteLine("};");

            if (bits == 7)
            {
                sw.WriteLine(@"/// <summary>
            /// Whitespace character ranges.
            /// </summary>");
                sw.WriteLine("public static int[][] " + field + "Whitespace = new int[][]{");
                foreach (int[] range in whitespace.ranges)
                    sw.WriteLine("    new int[]{" + string.Format("{0},{1}", range[0], range[1]) + "},");
                sw.WriteLine("};");

                sw.WriteLine(@"/// <summary>
            /// Word character ranges.
            /// </summary>");
                sw.WriteLine("public static int[][] " + field + "WordCharacter = new int[][]{");
                foreach (int[] range in wordcharacter.ranges)
                    sw.WriteLine("    new int[]{" + string.Format("{0},{1}", range[0], range[1]) + "},");
                sw.WriteLine("};");
            }

            sw.WriteLine(@"/// <summary>
            /// Compact BDD encoding of the whitespace characters.
            /// </summary>");
            sw.WriteLine("public static int[] " + field + "WhitespaceBdd = new int[]{");
            foreach (var arc in bddb.SerializeCompact(whitespaceBdd))
                sw.WriteLine("{0},", arc);
            sw.WriteLine("};");

            sw.WriteLine(@"/// <summary>
            /// Compact BDD encoding of word characters
            /// </summary>");
            sw.WriteLine("public static int[] " + field + "WordCharacterBdd = new int[]{");
            foreach (var arc in bddb.SerializeCompact(wordCharBdd))
                sw.WriteLine("{0},", arc);
            sw.WriteLine("};");
        }
예제 #33
0
 public override WS1SFormula Normalize(CharSetSolver solver)
 {
     var ln = left.Normalize(solver);
     var rn = right.Normalize(solver);
     if (ln is WS1SUnaryPred && rn is WS1SUnaryPred)
     {
         var cln = ln as WS1SUnaryPred;
         var crn = rn as WS1SUnaryPred;
         if (cln.set == crn.set)
             return new WS1SUnaryPred(cln.set, solver.MkOr(cln.pred, crn.pred));
     }
     else{
         if (ln is WS1STrue || rn is WS1STrue)
             return ln;
         if (ln is WS1SFalse)
             return rn;
         if (rn is WS1SFalse)
             return ln;
     }
     return new WS1SOr(ln, rn);
 }
        public DensityFeedback(FeedbackLevel level, HashSet<char> alphabet, Automaton<BDD> dfaGoal, Automaton<BDD> dfaAttempt, double utility, CharSetSolver solver)
            : base(level, alphabet, utility,solver)
        {
            BDD pred = solver.False;
            foreach (var el in alphabet)
                pred=solver.MkOr(pred,solver.MkCharConstraint(false,el));

            var dfaAll = Automaton<BDD>.Create(0,new int[]{0},new Move<BDD>[]{new Move<BDD>(0,0,pred)});
            this.type = FeedbackType.Density;
            this.positiveDifference = dfaGoal.Minus(dfaAttempt, solver).Determinize(solver).Minimize(solver);
            this.negativeDifference = dfaAttempt.Minus(dfaGoal, solver).Determinize(solver).Minimize(solver);
            this.symmetricDifference = dfaAll.Minus(dfaAll.Minus(positiveDifference,solver).Intersect(dfaAll.Minus(negativeDifference,solver),solver),solver).Determinize(solver).Minimize(solver);                
            this.solver = solver;
        }
        // automata come already determinized
        public NFACounterexampleFeedback(
            FeedbackLevel level, HashSet<char> alphabet, 
            Automaton<BDD> solutionDFA, Automaton<BDD> attemptDFA, 
            CharSetSolver solver)
            : base(level, alphabet, solver)
        {
            BDD pred = solver.False;
            foreach (var el in alphabet)
                pred = solver.MkOr(pred, solver.MkCharConstraint(false, el));

            var dfaAll = Automaton<BDD>.Create(0, new int[] { 0 }, new Move<BDD>[] { new Move<BDD>(0, 0, pred) });
            this.positiveDifference = solutionDFA.Minus(attemptDFA, solver).Determinize(solver).Minimize(solver);
            this.negativeDifference = attemptDFA.Minus(solutionDFA, solver).Determinize(solver).Minimize(solver);
            this.solver = solver;
        }
예제 #36
0
        internal static Automaton<BDD> computeDFA(List<string> variables, BDD alphabet, CharSetSolver solver, string set1, string set2)
        {
            var pos1 = variables.IndexOf(set1);
            var pos2 = variables.IndexOf(set2);

            Dictionary<Pair<int, int>, Automaton<BDD>> dic1 = null;
            Pair<int, int> pair = null;
            if (hashing)
            {
                if (!hashedDfa.ContainsKey(alphabet))
                    hashedDfa[alphabet] = new Dictionary<int, Dictionary<Pair<int, int>, Automaton<BDD>>>();

                var dic = hashedDfa[alphabet];

                if (!dic.ContainsKey(variables.Count))
                    dic[variables.Count] = new Dictionary<Pair<int, int>, Automaton<BDD>>();

                dic1 = dic[variables.Count];

                pair = new Pair<int, int>(pos1, pos2);

                if (dic1.ContainsKey(pair))
                    return dic1[pair];
            }

            //Create conditions that bit in pos1 is smaller than pos2
            var trueBv = solver.MkSetFromRange(0, (uint)(Math.Pow(2, variables.Count + 7) - 1), variables.Count + 7 - 1);
            var pos2is1 = solver.MkAnd(trueBv, solver.MkSetWithBitTrue(pos2));
            var pos1is0 = solver.MkAnd(trueBv, solver.MkSetWithBitFalse(pos1));
            var subsetCond = solver.MkOr(pos2is1, pos1is0);


            //Create automaton for condition
            var moves = new Move<BDD>[] { new Move<BDD>(0, 0, subsetCond) };

            var dfa = Automaton<BDD>.Create(0, new int[] { 0 }, moves).Determinize(solver).Minimize(solver);
            if(hashing)
                dic1[pair] = dfa;
            return dfa;
        }
예제 #37
0
        public void ChooseUnifromlyTest()
        {
            CharSetSolver solver = new CharSetSolver(BitWidth.BV16);

            BDD set1 = solver.MkRangeConstraint('\0', '\x01', true);
            BDD set2 = solver.MkRangeConstraint( '\u0FFF', '\u0FFF');
            string set2str = solver.PrettyPrint(set2);
            BDD set3 = solver.MkRangeConstraint( '\u00FF', '\u00FF');
            BDD set4 = solver.MkRangeConstraint( '\u000F', '\u000F');

            BDD set = solver.MkOr(new BDD[]{set2, set3, set4, set1});

            string setstr = solver.PrettyPrint(set);

            set.ToDot(@"foo.dot");

            var map = new Dictionary<char, int>();
            map['\0'] = 0;
            map['\x01'] = 0;
            map['\u0FFF'] = 0;
            map['\u00FF'] = 0;
            map['\u000F'] = 0;

            for (int i = 0; i < 50000; i++)
            {
                var c = solver.ChooseUniformly(set);
                map[c] += 1;
            }
            foreach (var kv in map)
                Assert.IsTrue(kv.Value > 9700);
        }
예제 #38
0
        internal static Automaton<BDD> computeDFA(List<string> variables, BDD alphabet, CharSetSolver solver, string set1, string set2)
        {
            int pos1 = variables.IndexOf(set1);
            int pos2 = variables.IndexOf(set2);

            Dictionary<int, Dictionary<Pair<int, int>, Automaton<BDD>>> dic1;
            if (!hashedDfa.ContainsKey(alphabet))
                hashedDfa[alphabet] = new Dictionary<int, Dictionary<Pair<int, int>, Automaton<BDD>>>();

            dic1 = hashedDfa[alphabet];

            Dictionary<Pair<int, int>, Automaton<BDD>> dic2;
            if (!dic1.ContainsKey(variables.Count))
                dic1[variables.Count] = new Dictionary<Pair<int, int>, Automaton<BDD>>();

            dic2 = dic1[variables.Count];

            var hash = new Pair<int, int>(pos1, pos2);
            if (dic2.ContainsKey(hash))
                return dic2[hash];

            //Create conditions that bit in pos1 is smaller than pos2
            var trueBv = solver.MkSetFromRange(0, (uint)(Math.Pow(2, variables.Count + 16) - 1), variables.Count + 16 - 1);
            var both1 = solver.MkAnd(new BDD[] { trueBv, solver.MkSetWithBitTrue(pos1), solver.MkSetWithBitTrue(pos2) });
            var both0 = solver.MkAnd(new BDD[] { trueBv, solver.MkSetWithBitFalse(pos1), solver.MkSetWithBitFalse(pos2) });
            var eqCond = solver.MkOr(new BDD[] { both0, both1 });

            //Create automaton for condition
            var moves = new Move<BDD>[] { new Move<BDD>(0, 0, eqCond) };
            var dfa = Automaton<BDD>.Create(0, new int[] { 0 }, moves).Determinize(solver).Minimize(solver);
            if(hashing)
                dic2[hash] = dfa;
            return dfa;
        }
예제 #39
0
        STModel ConvertReplace(replace repl)
        {
            //create a disjunction of all the regexes
            //each case terminated by the identifier
            int K = 0; //max pattern length
            //HashSet<int> finalReplacers = new HashSet<int>();

            //for efficieny keep lookup tables of character predicates to sets
            Dictionary <Expr, BDD> predLookup = new Dictionary <Expr, BDD>();

            Automaton <BDD> previouspatterns = Automaton <BDD> .MkEmpty(css);

            Automaton <BV2> N = Automaton <BV2> .MkFull(css2);

            var hasNoEndAnchor = new HashSet <int>();

            for (int i = 0; i < repl.CaseCount; i++)
            {
                replacecase rcase = repl.GetCase(i);
                var         pat   = "^" + rcase.Pattern.val;
                var         M     = css.Convert("^" + rcase.Pattern.val, System.Text.RegularExpressions.RegexOptions.Singleline).Determinize().Minimize();

                #region check that the pattern is a feasible nonempty sequence
                if (M.IsEmpty)
                {
                    throw new BekParseException(string.Format("Semantic error: pattern {0} is infeasible.", rcase.Pattern.ToString()));
                }
                int _K;
                if (!M.CheckIfSequence(out _K))
                {
                    throw new BekParseException(string.Format("Semantic error: pattern {0} is not a sequence.", rcase.Pattern.ToString()));
                }
                if (_K == 0)
                {
                    throw new BekParseException(string.Format("Semantic error: empty pattern {0} is not allowed.", rcase.Pattern.ToString()));
                }
                K = Math.Max(_K, K);
                #endregion

                var liftedMoves   = new List <Move <BV2> >();
                var st            = M.InitialState;
                var newFinalState = M.MaxState + 1;
                var endAnchor     = css.MkCharConstraint((char)i);

                //lift the moves to BV2 moves, adding end-markers
                while (!M.IsFinalState(st))
                {
                    var mv         = M.GetMoveFrom(st);
                    var pair_cond  = new BV2(mv.Label, css.False);
                    var liftedMove = new Move <BV2>(mv.SourceState, mv.TargetState, pair_cond);
                    liftedMoves.Add(liftedMove);
                    if (M.IsFinalState(mv.TargetState))
                    {
                        var end_cond = new BV2(css.False, endAnchor);
                        if (M.IsLoopState(mv.TargetState))
                        {
                            hasNoEndAnchor.Add(i);
                            //var loop_cond = css2.MkNot(end_cond);
                            //var loopMove = new Move<BV2>(mv.TargetState, mv.TargetState, loop_cond);
                            //liftedMoves.Add(loopMove);
                        }
                        var endMove = new Move <BV2>(mv.TargetState, newFinalState, end_cond);
                        liftedMoves.Add(endMove);
                    }
                    st = mv.TargetState;
                }
                var N_i = Automaton <BV2> .Create(css2, M.InitialState, new int[] { newFinalState }, liftedMoves);

                //Microsoft.Automata.Visualizer.ToDot(N_i, "N" + i , "C:\\Automata\\Docs\\Papers\\Bex\\N" + i +".dot", x => "(" + css.PrettyPrint(x.First) + "," + css.PrettyPrint(x.Second) + ")");

                N = N.Intersect(N_i.Complement());

                #region other approach: disallow overlapping patterns

                //Visualizer.ShowGraph(M2.Complement(css2), "M2", lab => { return "<" + css.PrettyPrint(lab.First) + "," + css.PrettyPrint(lab.Second) + ">"; });

                //note: keep here the original pattern, add only the start anchor to synchronize prefixes
                //var thispattern = css.Convert("^" + rcase.Pattern.val, System.Text.RegularExpressions.RegexOptions.Singleline).Determinize(css).Minimize(css);

                //var thispattern1 = thispattern.Minus(previouspatterns, css);
                //Visualizer.ShowGraph(thispattern1, "test", css.PrettyPrint);

                //#region check that thispattern does not overlap with any previous pattern
                //var common = thispattern.Intersect(previouspatterns, css);
                //if (!(common.IsEmpty))
                //{
                //    int j = 0;
                //    while ((j < i) && css.Convert("^" + repl.GetCase(j).Pattern.val,
                //        System.Text.RegularExpressions.RegexOptions.Singleline).Determinize(css).Intersect(thispattern, css).IsEmpty)
                //        j++;

                //    throw new BekParseException(rcase.id.line, rcase.id.pos, string.Format("Semantic error: pattern {0} overlaps pattern {1}.",
                //        rcase.Pattern.ToString(), repl.GetCase(j).Pattern.ToString()));
                //}
                //previouspatterns = previouspatterns.Union(thispattern).RemoveEpsilons(css.MkOr); //TBD: better union
                //#endregion

                #endregion
            }

            N = N.Complement().Minimize();
            //Microsoft.Automata.Visualizer.ShowGraph(N, "N", x => "<" + css.PrettyPrint(x.First) + "," + css.PrettyPrint(x.Second) + ">");
            //Microsoft.Automata.Visualizer.ToDot(N, "N","C:\\Automata\\Docs\\Papers\\Bex\\N.dot", x => "(" + css.PrettyPrint(x.First) + "," + css.PrettyPrint(x.Second) + ")");

            var D = new Dictionary <int, int>();
            var G = new Dictionary <int, BDD>();

            #region compute distance from initial state and compute guard unions
            var S = new Stack <int>();
            D[N.InitialState] = 0;
            G[N.InitialState] = css.False;
            S.Push(N.InitialState);
            while (S.Count > 0)
            {
                var q = S.Pop();
                foreach (var move in N.GetMovesFrom(q))
                {
                    G[q] = css.MkOr(G[q], move.Label.Item1);
                    var p = move.TargetState;
                    var d = D[q] + 1;
                    if (!(N.IsFinalState(p)) && !D.ContainsKey(p))
                    {
                        D[p] = d;
                        G[p] = css.False;
                        S.Push(p);
                    }
                    if (!(N.IsFinalState(p)) && D[p] != d)
                    {
                        throw new BekException(string.Format("Unexpected error, inconsitent distances {0} and {1} to state {2}", D[p], d, p));
                    }
                }
            }

            #endregion

            #region check that outputs do not have out of bound variables
            foreach (var fs in N.GetFinalStates())
            {
                foreach (var move in N.GetMovesTo(fs))
                {
                    if (move.Label.Item2.IsEmpty)
                    {
                        throw new BekException("Internal error: missing end anchor");
                    }

                    //if (!css.IsSingleton(move.Condition.Second))
                    //{
                    //    var one = (int)css.GetMin(move.Condition.Second);
                    //    var two = (int)css.GetMax(move.Condition.Second);
                    //    throw new BekParseException(repl.GetCase(two).id.line, repl.GetCase(two).id.pos, string.Format("Ambiguous replacement patterns {0} and {1}.", repl.GetCase(one).Pattern, repl.GetCase(two).Pattern));
                    //}

                    //pick the minimum case identifer when there are several, essentially pick the earliest case
                    int id = (int)css.GetMin(move.Label.Item2);

                    int           distFromRoot = D[move.SourceState];
                    var           e            = repl.GetCase(id).Output;
                    HashSet <int> vars         = new HashSet <int>();
                    foreach (var v in e.GetBoundVars())
                    {
                        if (v.GetVarId() >= distFromRoot)
                        {
                            throw new BekParseException(v.line, v.pos, string.Format("Syntax error: pattern variable '{0}' is out ouf bounds, valid range is from '#0' to '#{1}']", v.name, distFromRoot - 1));
                        }
                    }
                }
            }
            #endregion

            int finalState = N.FinalState;
            K = K - 1; //this many registers are needed

            var zeroChar       = stb.Solver.MkCharExpr('\0');
            var STmoves        = new List <Move <Rule <Expr> > >();
            var STstates       = new HashSet <int>();
            var STdelta        = new Dictionary <int, List <Move <Rule <Expr> > > >();
            var STdeltaInv     = new Dictionary <int, List <Move <Rule <Expr> > > >();
            var FinalSTstates  = new HashSet <int>();
            var STdeletedMoves = new HashSet <Move <Rule <Expr> > >();
            Action <Move <Rule <Expr> > > STmovesAdd = r =>
            {
                var p = r.SourceState;
                var q = r.TargetState;
                STmoves.Add(r);
                if (STstates.Add(p))
                {
                    STdelta[p]    = new List <Move <Rule <Expr> > >();
                    STdeltaInv[p] = new List <Move <Rule <Expr> > >();
                }
                if (STstates.Add(q))
                {
                    STdelta[q]    = new List <Move <Rule <Expr> > >();
                    STdeltaInv[q] = new List <Move <Rule <Expr> > >();
                }
                if (r.Label.IsFinal)
                {
                    FinalSTstates.Add(p);
                }
                STdelta[p].Add(r);
                STdeltaInv[q].Add(r);
            };
            var regsorts = new Sort[K];
            for (int j = 0; j < K; j++)
            {
                regsorts[j] = stb.Solver.CharSort;
            }
            var regsort = stb.Solver.MkTupleSort(regsorts);
            var regvar  = stb.MkRegister(regsort);
            var initialRegisterValues = new Expr[K];
            for (int j = 0; j < K; j++)
            {
                initialRegisterValues[j] = zeroChar;
            }
            var initialRegister = stb.Solver.MkTuple(initialRegisterValues);

            Predicate <int> IsCaseEndState = s => { return(N.OutDegree(s) == 1 && N.GetMoveFrom(s).Label.Item1.IsEmpty); };

            #region compute the forward moves and the completion moves
            var V = new HashSet <int>();
            S.Push(N.InitialState);
            while (S.Count > 0)
            {
                var p = S.Pop();

                #region forward moves
                foreach (var move in N.GetMovesFrom(p))
                {
                    var q = move.TargetState;
                    //this move occurs if p has both an end-move and a non-end-move
                    //note that if p is an case-end-state then it is never pushed to S
                    if (N.IsFinalState(q))
                    {
                        continue;
                    }

                    var  distance = D[p];
                    Expr chExpr;
                    Expr chPred;
                    MkExprPred(move.Label.Item1, out chExpr, out chPred);
                    predLookup[chPred] = move.Label.Item1;

                    Expr[] regUpds = new Expr[K];
                    for (int i = 0; i < K; i++)
                    {
                        if (i == distance)
                        {
                            regUpds[i] = chExpr;
                        }
                        else //if (i < distance)
                        {
                            regUpds[i] = stb.Solver.MkProj(i, regvar);
                        }
                        //else
                        //    regUpds[i] = zeroChar;
                    }
                    Expr regExpr = stb.Solver.MkTuple(regUpds);
                    var  moveST  = stb.MkRule(p, q, chPred, regExpr); //there are no yields
                    STmovesAdd(moveST);

                    if (V.Add(q) && !IsCaseEndState(q))
                    {
                        S.Push(q);
                    }
                }
                #endregion


                #region completion is only enabled if there exists an else case
                if (repl.HasElseCase)
                {
                    var guards  = G[p];
                    var guards0 = G[N.InitialState];

                    #region nonmatching cases to the initial state
                    var nomatch = css.MkNot(css.MkOr(guards, guards0));

                    if (!nomatch.IsEmpty)
                    {
                        Expr chExpr;
                        Expr nomatchPred;
                        MkExprPred(nomatch, out chExpr, out nomatchPred);
                        predLookup[nomatchPred] = nomatch;

                        var else_yields_list = new List <Expr>();
                        for (int i = 0; i < D[p]; i++)
                        {
                            else_yields_list.AddRange(GetElseYieldInstance(repl.ElseOutput, stb.Solver.MkProj(i, regvar)));
                        }
                        else_yields_list.AddRange(GetElseYieldInstance(repl.ElseOutput, stb.MkInputVariable(stb.Solver.CharSort)));

                        var else_yields = else_yields_list.ToArray();
                        var resetMove   = stb.MkRule(p, N.InitialState, nomatchPred, initialRegister, else_yields);
                        STmovesAdd(resetMove);
                    }
                    #endregion

                    #region matching cases via the initial state
                    foreach (var move0 in N.GetMovesFrom(N.InitialState))
                    {
                        var g0    = move0.Label.Item1;
                        var match = css.MkAnd(css.MkNot(guards), g0);
                        if (!match.IsEmpty)
                        {
                            Expr chExpr;
                            Expr matchPred;
                            MkExprPred(match, out chExpr, out matchPred);
                            predLookup[matchPred] = match;


                            var resetYieldsList = new List <Expr>();
                            //for all unprocessed inputs produce the output yield according to the else case
                            for (int i = 0; i < D[p]; i++)
                            {
                                resetYieldsList.AddRange(GetElseYieldInstance(repl.ElseOutput, stb.Solver.MkProj(i, regvar)));
                            }
                            var resetYields = resetYieldsList.ToArray();

                            Expr[] regupd = new Expr[K];
                            regupd[0] = chExpr;
                            for (int j = 1; j < K; j++)
                            {
                                regupd[j] = zeroChar;
                            }
                            var regupdExpr = stb.Solver.MkTuple(regupd);
                            var resetMove  = stb.MkRule(p, move0.TargetState, matchPred, regupdExpr, resetYields);
                            STmovesAdd(resetMove);
                        }
                    }
                    #endregion
                }
                #endregion
            }

            #endregion

            foreach (var last_move in N.GetMovesTo(N.FinalState))
            {
                //i is the case identifier
                int i = (int)css.GetMin(last_move.Label.Item2);

                if (hasNoEndAnchor.Contains(i))
                {
                    #region this corresponds to looping back to the initial state on the given input
                    //the final outputs produced after a successful pattern match

                    #region compute the output terms

                    int distFromRoot = D[last_move.SourceState];
                    Func <ident, Expr> registerMap = id =>
                    {
                        // --- already checked I think ---
                        if (!id.IsVar || id.GetVarId() >= distFromRoot)
                        {
                            throw new BekParseException(id.Line, id.Pos, string.Format("illeagal variable '{0}' in output", id.name));
                        }

                        if (id.GetVarId() == distFromRoot - 1) //the last reg update refers to the current variable
                        {
                            return(stb.MkInputVariable(stb.Solver.CharSort));
                        }
                        else
                        {
                            return(stb.Solver.MkProj(id.GetVarId(), regvar));
                        }
                    };
                    Expr[] yields;
                    var    outp = repl.GetCase(i).Output;
                    if (outp is strconst)
                    {
                        var s = ((strconst)outp).val;
                        yields = Array.ConvertAll(s.ToCharArray(),
                                                  c => this.str_handler.iter_handler.expr_handler.Convert(new charconst("'" + StringUtility.Escape(c) + "'"), registerMap));
                    }
                    else //must be an explicit list construct
                    {
                        if (!(outp is functioncall) || !((functioncall)outp).id.name.Equals("string"))
                        {
                            throw new BekParseException("Invalid pattern output.");
                        }

                        var s = ((functioncall)outp).args;
                        yields = Array.ConvertAll(s.ToArray(),
                                                  e => this.str_handler.iter_handler.expr_handler.Convert(e, registerMap));
                    }
                    #endregion

                    //shortcut all the incoming transitions to the initial state
                    foreach (var move in STdeltaInv[last_move.SourceState])
                    {
                        //go to the initial state, i.e. the matching raps around
                        int         p       = move.SourceState;
                        int         q0      = N.InitialState;
                        List <Expr> yields1 = new List <Expr>(move.Label.Yields); //incoming yields are
                        yields1.AddRange(yields);
                        var rule = stb.MkRule(p, q0, move.Label.Guard, initialRegister, yields1.ToArray());
                        STmovesAdd(rule);
                        //STdeletedMoves.Add(move);
                        STmoves.Remove(move); //the move has been replaced
                    }
                    #endregion
                }
                else
                {
                    #region this is the end of the input stream case

                    #region compute the output terms

                    int distFromRoot = D[last_move.SourceState];
                    Func <ident, Expr> registerMap = id =>
                    {
                        if (!id.IsVar || id.GetVarId() >= distFromRoot)
                        {
                            throw new BekParseException(id.Line, id.Pos, string.Format("illeagal variable '{0}' in output", id.name));
                        }

                        return(stb.Solver.MkProj(id.GetVarId(), regvar));
                    };
                    Expr[] yields;
                    var    outp = repl.GetCase(i).Output;
                    if (outp is strconst)
                    {
                        var s = ((strconst)outp).val;
                        yields = Array.ConvertAll(s.ToCharArray(),
                                                  c => this.str_handler.iter_handler.expr_handler.Convert(new charconst("'" + c.ToString() + "'"), registerMap));
                    }
                    else //must be an explicit list construct
                    {
                        if (!(outp is functioncall) || !((functioncall)outp).id.name.Equals("string"))
                        {
                            throw new BekParseException("Invalid pattern output.");
                        }

                        var s = ((functioncall)outp).args;
                        yields = Array.ConvertAll(s.ToArray(),
                                                  e => this.str_handler.iter_handler.expr_handler.Convert(e, registerMap));
                    }
                    #endregion

                    int p    = last_move.SourceState;
                    var rule = stb.MkFinalOutput(p, stb.Solver.True, yields);
                    STmovesAdd(rule);
                    #endregion
                }
            }

            if (repl.HasElseCase)
            {
                #region final completion (upon end of input) for all non-final states
                foreach (var p in STstates)
                {
                    if (!FinalSTstates.Contains(p) && !IsCaseEndState(p)) //there is no final rule for p, so add the default one
                    {
                        Expr[] finalYields;
                        finalYields = new Expr[D[p]];
                        for (int i = 0; i < finalYields.Length; i++)
                        {
                            finalYields[i] = stb.Solver.MkProj(i, regvar);
                        }
                        var p_finalMove = stb.MkFinalOutput(p, stb.Solver.True, finalYields);
                        STmovesAdd(p_finalMove);
                    }
                }
                #endregion
            }
            else
            {
                //in this case there is a final rule from the initial state
                var q0_finalMove = stb.MkFinalOutput(N.InitialState, stb.Solver.True);
                STmovesAdd(q0_finalMove);
            }

            var resST  = stb.MkST(name, initialRegister, stb.Solver.CharSort, stb.Solver.CharSort, regsort, N.InitialState, STmoves);
            var resSTb = new STModel(stb.Solver, name, stb.Solver.CharSort, stb.Solver.CharSort, regsort, initialRegister, N.InitialState);

            //create STb from the moves, we use here the knowledge that the ST is deterministic
            //we also use the lookuptable of conditions to eliminate dead code


            //resST.ShowGraph();

            //resST.ToDot("C:\\Automata\\Docs\\Papers\\Bex\\B.dot");

            #region compute the rules of the resulting STb

            //V.Clear();
            //S.Push(resST.InitialState);
            //V.Add(resST.InitialState);

            foreach (var st in resST.GetStates())
            {
                var condUnion = css.False;
                var st_moves  = new List <Move <Rule <Expr> > >();
                foreach (var move in resST.GetNonFinalMovesFrom(st))
                {
                    condUnion = css.MkOr(condUnion, predLookup[move.Label.Guard]);
                    st_moves.Add(move);
                }

                BranchingRule <Expr> st_rule;
                if (st_moves.Count > 0)
                {
                    //collect all rules with singleton guards and put them into a switch statement
                    var st_rules1 = new List <KeyValuePair <Expr, BranchingRule <Expr> > >();
                    var st_moves2 = new List <Move <Rule <Expr> > >();
                    foreach (var move in st_moves)
                    {
                        if (css.ComputeDomainSize(predLookup[move.Label.Guard]) == 1)
                        {
                            var v = stb.Solver.MkNumeral(css.Choose(predLookup[move.Label.Guard]), stb.Solver.CharSort);
                            var r = new BaseRule <Expr>(new Sequence <Expr>(move.Label.Yields),
                                                        move.Label.Update, move.TargetState);
                            st_rules1.Add(new KeyValuePair <Expr, BranchingRule <Expr> >(v, r));
                        }
                        else
                        {
                            st_moves2.Add(move);
                        }
                    }
                    BranchingRule <Expr> defaultcase = new UndefRule <Expr>("reject");
                    //make st_moves2 into an ite rule
                    if (st_moves2.Count > 0)
                    {
                        for (int j = st_moves2.Count - 1; j >= 0; j--)
                        {
                            var r = new BaseRule <Expr>(new Sequence <Expr>(st_moves2[j].Label.Yields),
                                                        st_moves2[j].Label.Update, st_moves2[j].TargetState);
                            if (j == (st_moves2.Count - 1) && condUnion.IsFull)
                            {
                                defaultcase = r;
                            }
                            else
                            {
                                defaultcase = new IteRule <Expr>(st_moves2[j].Label.Guard, r, defaultcase);
                            }
                        }
                    }
                    else if (condUnion.IsFull)
                    {
                        defaultcase = st_rules1[st_rules1.Count - 1].Value;
                        st_rules1.RemoveAt(st_rules1.Count - 1);
                    }
                    if (st_rules1.Count == 0)
                    {
                        st_rule = defaultcase;
                    }
                    else
                    {
                        st_rule = new SwitchRule <Expr>(stb.MkInputVariable(stb.Solver.CharSort), defaultcase, st_rules1.ToArray());
                    }
                }
                else
                {
                    st_rule = new UndefRule <Expr>("reject");
                }

                resSTb.AssignRule(st, st_rule);

                var st_finalrules = new List <Rule <Expr> >(resST.GetFinalRules(st));
                if (st_finalrules.Count > 1)
                {
                    throw new BekException("Unexpected error: multiple final rules per state.");
                }
                if (st_finalrules.Count > 0)
                {
                    resSTb.AssignFinalRule(st, new BaseRule <Expr>(new Sequence <Expr>(st_finalrules[0].Yields), initialRegister, st));
                }
            }

            resSTb.ST = resST;
            resST.STb = resSTb;
            #endregion

            return(resSTb);
        }
        /// <summary>
        /// Returns an automaton where transitions between states are collapsed to a single one
        /// </summary>
        /// <param name="automaton"></param>
        /// <param name="solver"></param>
        /// <returns></returns>
        public static Automaton<BDD> normalizeMoves(Automaton<BDD> automaton, CharSetSolver solver)
        {
            List<Move<BDD>> normMoves = new List<Move<BDD>>();
            foreach (var sourceState in automaton.States)
            {
                Dictionary<int, BDD> moveConditions = new Dictionary<int, BDD>();
                foreach (var moveFromSourceState in automaton.GetMovesFrom(sourceState))
                {
                    var target = moveFromSourceState.TargetState;
                    BDD oldCondition = null;
                    if (moveConditions.ContainsKey(target))                    
                        oldCondition = moveConditions[target];                    
                    else
                        oldCondition = solver.False;

                    if (!moveFromSourceState.IsEpsilon)
                        moveConditions[target] = solver.MkOr(oldCondition, moveFromSourceState.Label);
                    else
                        normMoves.Add(moveFromSourceState);
                }

                foreach (var targetState in moveConditions.Keys)             
                    normMoves.Add(new Move<BDD>(sourceState,targetState,moveConditions[targetState]));                
            }

            return Automaton<BDD>.Create(automaton.InitialState, automaton.GetFinalStates(), normMoves);
        }