예제 #1
0
        public static SymbolicString repeatLast(SymbolicString s, LinearIntegerExpression e)
        {
            if (s == null || e == null)
            {
                return(null);
            }

            switch (s.expression_type)
            {
            case SymbolicString.SymbolicStringType.Symbol:
                return(SymbolicString.Repeat(s, e));

            case SymbolicString.SymbolicStringType.Repeat:
                return(SymbolicString.Repeat(s, e));

            case SymbolicString.SymbolicStringType.Concat:
                List <SymbolicString> sub_strings = new List <SymbolicString>();
                sub_strings.AddRange(s.sub_strings.Take(s.sub_strings.Count - 1));
                var last = s.sub_strings[s.sub_strings.Count - 1];
                sub_strings.Add(SymbolicString.Repeat(last, e));
                return(SymbolicString.Concat(sub_strings));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #2
0
        public static SymbolicString repeat(SymbolicString s, LinearIntegerExpression e)
        {
            if (s == null || e == null)
            {
                return(null);
            }

            return(SymbolicString.Repeat(s, e));
        }
예제 #3
0
        private static IEnumerable <Match> longLeftMatches(SymbolicString s1, SymbolicString s2)
        {
            var l1    = s1.root.wordLength();
            var l2    = s2.root.wordLength();
            var g     = gcd(l1, l2);
            var v_beg = LinearIntegerExpression.FreshVariable();
            var v_end = LinearIntegerExpression.FreshVariable();

            // Split exactly at s2 root border
            yield return(Match.PartialSecond(
                             LogicalExpression.And(
                                 // the beginning matches the s1
                                 ComparisonExpression.Equal(
                                     LinearIntegerExpression.Times(l2, v_beg),
                                     LinearIntegerExpression.Times(l1, s1.repeat)
                                     ),
                                 // left over right bit is nonempty
                                 ComparisonExpression.GreaterThan(
                                     LinearIntegerExpression.Times(l2, v_end),
                                     0
                                     ),
                                 // beginning and end match s2
                                 ComparisonExpression.Equal(v_beg + v_end, s2.repeat),
                                 ComparisonExpression.GreaterThanOrEqual(v_beg, 0),
                                 ComparisonExpression.GreaterThanOrEqual(v_end, 0)
                                 ),
                             SymbolicString.Repeat(s2.root, v_end)
                             ));

            // Split in the middle of s2 root
            if (l2 != 1)
            {
                for (int i = g; i < l2; i += g)
                {
                    var suffix = SymbolicString.Concat(s2.root.sub_strings.Skip(i));
                    yield return(Match.PartialSecond(
                                     LogicalExpression.And(
                                         ComparisonExpression.Equal(
                                             LinearIntegerExpression.Times(l2, v_beg) + g,
                                             LinearIntegerExpression.Times(l1, s1.repeat)
                                             ),
                                         ComparisonExpression.GreaterThan(
                                             LinearIntegerExpression.Times(l2, v_beg) + suffix.length(),
                                             0
                                             ),
                                         ComparisonExpression.Equal(v_beg + v_end + 1, s2.repeat),
                                         ComparisonExpression.GreaterThanOrEqual(v_beg, 0),
                                         ComparisonExpression.GreaterThanOrEqual(v_end, 0)
                                         ),
                                     SymbolicString.Concat(suffix, SymbolicString.Repeat(s2.root, v_end))
                                     ));
                }
            }
        }
예제 #4
0
        // Either consume symbol with first symbol of repeat and say repeat is positive
        // Or don't consume symbol and say repeat is zero
        private static IEnumerable <Match> matchSymbolRepeat(SymbolicString s1, SymbolicString s2)
        {
            Debug.Assert(s2.isFlat());

            // When repeat is 0
            yield return(Match.PartialFirst(ComparisonExpression.Equal(s2.repeat, 0), s1));

            // When repeat is non-zero
            foreach (var m in match(s1, s2.root))
            {
                // Because the root is a word, we immediately know if the symbol matches or not
                // and get an m if and only if the symbol matches
                Debug.Assert(!m.FirstRemaining);
                yield return(Match.PartialSecond(
                                 LogicalExpression.And(m.constraint, ComparisonExpression.GreaterThan(s2.repeat, 0)),
                                 SymbolicString.Concat(m.remaining2, SymbolicString.Repeat(s2.root, s2.repeat - 1))
                                 ));
            }
        }
예제 #5
0
        private static SymbolicString splitToSymbStr(List <string> alphabet, string start, string mid, string end)
        {
            VariableType          freshVar = VariableType.FreshVariable();
            List <SymbolicString> strings  = new List <SymbolicString>();

            if (!start.Equals(""))
            {
                strings.Add(SymbolicString.FromTextDescription(alphabet, start));
            }
            SymbolicString pumpedMid = SymbolicString.Repeat(SymbolicString.FromTextDescription(alphabet, mid), LinearIntegerExpression.Variable(freshVar.ToString()));

            strings.Add(pumpedMid);
            if (!end.Equals(""))
            {
                strings.Add(SymbolicString.FromTextDescription(alphabet, end));
            }

            SymbolicString matchingString = SymbolicString.Concat(strings);

            return(matchingString);
        }
예제 #6
0
        // Generate TwoSplit's where either one may be empty
        // Generates the splits in order, i.e., by length of the prefix
        // So, for s being symbol and concat, first one will always be (\epsilon, s) and last one always (s, \epsilon)
        // So, for s being repeat (abc)^n, first will be ((abc)^i,(abc)^j) and last one always ((abc)^i ab, c(abc)^j)
        // Requires a flat symbolic string
        public IEnumerable <TwoSplit> TwoSplits()
        {
            SymbolicString prefix, suffix;

            // Contract.Requires(this.isFlat());


            switch (this.expression_type)
            {
            case SymbolicStringType.Symbol:
                yield return(TwoSplit.MakeSplit(SymbolicString.Epsilon(), this, LogicalExpression.True()));

                yield return(TwoSplit.MakeSplit(this, SymbolicString.Epsilon(), LogicalExpression.True()));

                break;

            case SymbolicStringType.Concat:
                yield return(TwoSplit.MakeSplit(SymbolicString.Epsilon(), this, LogicalExpression.True()));

                for (int i = 0; i < this.sub_strings.Count; i++)
                {
                    prefix = SymbolicString.Concat(this.sub_strings.Take(i).ToList());
                    suffix = SymbolicString.Concat(this.sub_strings.Skip(i + 1).ToList());
                    foreach (var split in this.sub_strings[i].TwoSplits())
                    {
                        if (!split.start.isEpsilon())
                        {
                            yield return(split.extend(prefix, suffix));
                        }
                    }
                }
                break;

            case SymbolicStringType.Repeat:
                var v1 = LinearIntegerExpression.FreshVariable();
                var v2 = LinearIntegerExpression.FreshVariable();
                var sanityConstraint = LogicalExpression.And(
                    ComparisonExpression.GreaterThanOrEqual(v1, 0),
                    ComparisonExpression.GreaterThanOrEqual(v2, 0)
                    );
                prefix = SymbolicString.Repeat(this.root, v1);
                suffix = SymbolicString.Repeat(this.root, v2);
                yield return(TwoSplit.MakeSplit(
                                 prefix,
                                 suffix,
                                 LogicalExpression.And(sanityConstraint, ComparisonExpression.Equal(v1 + v2, this.repeat))
                                 ));

                if (this.root.expression_type != SymbolicStringType.Concat)
                {
                    break;
                }
                for (int i = 1; i < this.root.sub_strings.Count; i++)
                {
                    var split = TwoSplit.MakeSplit(
                        SymbolicString.Concat(this.root.sub_strings.Take(i)),
                        SymbolicString.Concat(this.root.sub_strings.Skip(i)),
                        LogicalExpression.And(
                            ComparisonExpression.Equal(v1 + v2 + 1, this.repeat),
                            sanityConstraint
                            )
                        );
                    yield return(split.extend(prefix, suffix));
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #7
0
        // Generates splits where all three parts may be empty
        public IEnumerable <Split> Splits()
        {
            // Contract.Requires<ArgumentException>(this.isFlat());
            switch (this.expression_type)
            {
            case SymbolicStringType.Symbol:
                yield return(Split.MakeSplit(this, SymbolicString.Epsilon(), SymbolicString.Epsilon(), LogicalExpression.True()));

                yield return(Split.MakeSplit(SymbolicString.Epsilon(), this, SymbolicString.Epsilon(), LogicalExpression.True()));

                yield return(Split.MakeSplit(SymbolicString.Epsilon(), SymbolicString.Epsilon(), this, LogicalExpression.True()));

                break;

            case SymbolicStringType.Repeat:
                var v1 = LinearIntegerExpression.FreshVariable();
                var v2 = LinearIntegerExpression.FreshVariable();
                var v3 = LinearIntegerExpression.FreshVariable();
                var sanityConstraint = LogicalExpression.And(
                    ComparisonExpression.GreaterThanOrEqual(v1, 0),
                    ComparisonExpression.GreaterThanOrEqual(v2, 0),
                    ComparisonExpression.GreaterThanOrEqual(v3, 0)
                    );
                // Suppose the word w = a_0 a_1 \ldots a_{n-1}
                // All splits are of the form
                //    BEG: (a_0 \ldots a_{n-1})^i (a_0 \ldots a_p)                              = w^i . w_1
                //    MID: (a_{p+1} \ldots a_{n-1} a_0 \ldots a_p)^j (a_{p+1} \ldots a_q)       = (w_2 w_1)^j  w_3
                //    END: (a_{q+1} \ldots a_{n-1}) (a_0 \ldots a_{n-1})^k                          = w_4 w^k
                var w  = this.root.wordSymbols();
                var ww = w.Concat(w);
                int n  = w.Count();
                for (int w1len = 0; w1len < n; w1len++)
                {
                    var w_1 = w.Take(w1len);
                    var w_2 = w.Skip(w1len);
                    var beg = SymbolicString.Concat(
                        SymbolicString.Repeat(this.root, v1),
                        SymbolicString.Concat(w_1));
                    var mid_root = SymbolicString.Concat(
                        SymbolicString.Concat(w_2),
                        SymbolicString.Concat(w_1));
                    var mid_beg = SymbolicString.Repeat(mid_root, v2);
                    for (int w3len = 0; w3len < n; w3len++)
                    {
                        var w_3 = ww.Skip(w1len).Take(w3len);
                        var mid = SymbolicString.Concat(mid_beg, SymbolicString.Concat(w_3.ToList()));

                        IEnumerable <SymbolicString> w_4;
                        if (w1len + w3len == 0)
                        {
                            w_4 = new List <SymbolicString>();
                        }
                        else if (w1len + w3len <= n)
                        {
                            w_4 = w.Skip(w1len).Skip(w3len);
                        }
                        else
                        {
                            w_4 = ww.Skip(w1len).Skip(w3len);
                        }
                        var end = SymbolicString.Concat(
                            SymbolicString.Concat(w_4.ToList()),
                            SymbolicString.Repeat(this.root, v3)
                            );

                        var consumed = (w_1.Count() + w_3.Count() + w_4.Count()) / w.Count();
                        yield return(Split.MakeSplit(
                                         beg,
                                         mid,
                                         end,
                                         LogicalExpression.And(
                                             ComparisonExpression.Equal(v1 + v2 + v3 + consumed, this.repeat),
                                             sanityConstraint
                                             )
                                         ));
                    }
                }
                break;

            case SymbolicStringType.Concat:
                foreach (var beg_midend in this.TwoSplits())
                {
                    foreach (var mid_end in beg_midend.end.TwoSplits())
                    {
                        yield return(Split.MakeSplit(
                                         beg_midend.start,
                                         mid_end.start,
                                         mid_end.end,
                                         LogicalExpression.And(beg_midend.constraints, mid_end.constraints)));
                    }
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }