Ejemplo n.º 1
0
        public static bool checkPumping(
            ArithmeticLanguage language,
            SymbolicString pumpingString,
            Split split,
            LinearIntegerExpression pump)
        {
            if (pump.isConstant())
            {
                var k = pump.constant;
                var pumpedMid = SymbolicString.Concat(Enumerable.Repeat(split.mid, k));
                var pumpedString = SymbolicString.Concat(split.start, pumpedMid, split.end);

                return checkNonContainment(pumpedString, language, split.constraints);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Ejemplo n.º 2
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();
            }
        }
Ejemplo n.º 3
0
        // Strategy:
        // a) Match the prefix and suffix of the language with the x and z 
        // b) See if y can be pumped against the middle part
        // The horrifying part is the quantifiers
        public static bool splitGood(Split split, ArithmeticLanguage language, BooleanExpression additionalConstraint)
        {
            // We just need to find a k such that (x y^k z) \not\in L
            // If we cannot find such a k for some p, it is a bad split

            // Say i, j are the variables in the language constraint and 
            // v_1, v_2 are variables in split constraints
            // Therefore, if for all p, v_1, \ldots, v_n that satisfies split constraints
            // and additional constraints and exists k such that for all i, j language 
            // constraint does not hold, then split is bad
            Console.WriteLine("\t\tSplit is good if none of the following mids can be pumped: ");

            // We will definitely go through the loop at least once as match is working
            var beginningMatches = Matcher
                .match(split.start, language.symbolic_string)
                .Where(x => !x.FirstRemaining)
                .Select(x => x.withAdditionalConstraint(language.constraint))
                .Select(x => x.withAdditionalConstraint(additionalConstraint))
                .Where(x => x.isFeasible());
            foreach (var beginMatch in beginningMatches)
            {
                var remainingLanguage = beginMatch.remaining2;
                var endMatches = Matcher
                    .match(split.end.reverse(), remainingLanguage.reverse())
                    .Where(x => !x.FirstRemaining)
                    .Select(x => x.withAdditionalConstraint(language.constraint))
                    .Select(x => x.withAdditionalConstraint(additionalConstraint))
                    .Where(x => x.isFeasible());

                foreach (var endMatch in endMatches)
                {
                    var fullConstraint = LogicalExpression.And(beginMatch.constraint, endMatch.constraint);
                    if (!fullConstraint.isSatisfiable())
                        continue;
                    var midLanguage = endMatch.remaining2.reverse();
                    var midSplit = split.mid;
                    var ctx = new Context();
                    // Console.WriteLine("\t\t" + midLanguage + " ===== " + midSplit + " when " + fullConstraint);
                    // var z3exp = fullConstraint.toZ3(ctx).Simplify();
                    // Console.WriteLine("\t\t" + midLanguage + " ===== " + midSplit + " when " + z3exp);
                    if (!canMismatchOne(midLanguage, midSplit, fullConstraint))
                    {
                        return false;
                    }
                }
            }
            return true;
        }