Example #1
0
        public static string NonRegularCheckWord(ArithmeticLanguage lang, int n, string word)
        {
            if (word.Length < n)
            {
                return("<false>Word is too short.</false>");
            }

            foreach (char c in word)
            {
                if (!lang.alphabet.Contains(c + ""))
                {
                    return("<false>Word contains illegal letters.</false>");
                }
            }

            if (lang.symbolic_string.isFlat())
            {
                SymbolicString wordSS = Parser.parseSymbolicString(word, lang.alphabet.ToList());
                if (ProofChecker.checkContainment(wordSS, lang, LogicalExpression.True()))
                {
                    return("<true></true>");
                }
                else
                {
                    return("<false>Word is not in the language.</false>");
                }
            }
            else
            {
                throw new PumpingLemmaException("Arithmetic Language must be flat!");
            }
        }
        public static bool checkContainment(SymbolicString s, ArithmeticLanguage l, BooleanExpression additionalConstraints)
        {
            var condition = containmentCondition(s, l, additionalConstraints);

            // Check if the containment condition is valid
            return(!LogicalExpression.Not(condition).isSatisfiable());
        }
        public static bool checkNonContainment(SymbolicString s, ArithmeticLanguage l, BooleanExpression additionalConstraints)
        {
            var condition = containmentCondition(s, l, additionalConstraints);

            // Check if the containment condition is unsatisfiable
            return(!condition.isSatisfiable());
        }
Example #4
0
        public static string NonRegularGetRandomWord(ArithmeticLanguage language, int n)
        {
            HashSet <Dictionary <VariableType, int> > usedAssigments = new HashSet <Dictionary <VariableType, int> >();
            HashSet <VariableType> vars = language.constraint.GetVariables();

            for (int i = 0; i < Math.Pow(n, vars.Count); i++)
            {
                Dictionary <VariableType, int> newAssigment = new Dictionary <VariableType, int>();
                foreach (VariableType v in vars)
                {
                    newAssigment.Add(v, randInt(0, n));
                }
                if (usedAssigments.Contains(newAssigment))
                {
                    i--;
                }
                else
                {
                    usedAssigments.Add(newAssigment);
                    //check sat
                    HashSet <BooleanExpression> ops = new HashSet <BooleanExpression>();
                    ops.Add(language.constraint);
                    foreach (var entry in newAssigment)
                    {
                        ops.Add(ComparisonExpression.Equal(LinearIntegerExpression.Variable(entry.Key.ToString()), entry.Value));
                    }
                    BooleanExpression expr = LogicalExpression.And(ops);
                    if (expr.isSatisfiable())
                    {
                        return(pumpedWord(language.symbolic_string, newAssigment));
                    }
                }
            }
            return(wordError());
        }
        public static BooleanExpression containmentCondition(SymbolicString s, ArithmeticLanguage l, BooleanExpression additionalConstraints)
        {
            // Console.WriteLine("Checking containment of " + s + " in " + l);
            var goodMatches = Matcher
                .match(s, l.symbolic_string)
                .Select(x => x.forceFinish())
                .Select(x => x.withAdditionalConstraint(l.constraint))
                .Where(x => x.isFeasible())
                ;
            if (goodMatches.Count() == 0)
                return LogicalExpression.False();

            var matchCondition = LogicalExpression.False();
            foreach (var match in goodMatches)
            {
                // Console.WriteLine("Got good match: " + match);
                matchCondition = LogicalExpression.Or(matchCondition, match.constraint);
            }
            var condition = LogicalExpression.Implies(additionalConstraints, matchCondition);

            var variables = condition.GetVariables();
            var pVariables = s.GetIntegerVariables(); // Most of the times, should be 1
            var nonPVariables = variables.Where(x => !pVariables.Contains(x));

            var eCondition = QuantifiedExpression.Exists(nonPVariables, condition);
            var aCondition = QuantifiedExpression.Forall(pVariables, eCondition);

            return aCondition;
        }
        public static BooleanExpression containmentCondition(SymbolicString s, ArithmeticLanguage l, BooleanExpression additionalConstraints)
        {
            // Console.WriteLine("Checking containment of " + s + " in " + l);
            var goodMatches = Matcher
                              .match(s, l.symbolic_string)
                              .Select(x => x.forceFinish())
                              .Select(x => x.withAdditionalConstraint(l.constraint))
                              .Where(x => x.isFeasible())
            ;

            if (goodMatches.Count() == 0)
            {
                return(LogicalExpression.False());
            }

            var matchCondition = LogicalExpression.False();

            foreach (var match in goodMatches)
            {
                System.Diagnostics.Debug.WriteLine("Got good match: " + match);
                matchCondition = LogicalExpression.Or(matchCondition, match.constraint);
            }
            var condition = LogicalExpression.Implies(additionalConstraints, matchCondition);

            var variables     = condition.GetVariables();
            var pVariables    = s.GetIntegerVariables(); // Most of the times, should be 1
            var nonPVariables = variables.Where(x => !pVariables.Contains(x));

            var eCondition = QuantifiedExpression.Exists(nonPVariables, condition);
            var aCondition = QuantifiedExpression.Forall(pVariables, eCondition);

            return(aCondition);
        }
        // Returns true if start.(mid)^witness.end is not in the language for all models
        // that satisfy the additionalConstraint
        public static bool splitGoodWithWitness(
            Split split,
            ArithmeticLanguage language,
            BooleanExpression additionalConstraint,
            LinearIntegerExpression pumpingWitness)
        {
            // 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 (!canMismatchWitness(midLanguage, midSplit, fullConstraint, pumpingWitness))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Example #8
0
        public static Tuple <string, string, string> NonRegularGetRandomSplit(ArithmeticLanguage language, string word, int n)
        {
            int wordLength = word.Length;
            int splitPos1  = randInt(0, n - 1);
            // [0; pumpingVarValue-1]
            // splitPos1 + (splitPos2-splitPos1) <= pumpingVarValue
            // splitPos2 <= pumpingVarValue - 2 * splitPos1
            int splitPos2 = randInt(splitPos1 + 1, n);

            return(splitTuple(word, splitPos1, splitPos2));
        }
Example #9
0
 public static Tuple <string, string, string> NonRegularGetPumpableSplit(ArithmeticLanguage language, string word, int n)
 {
     foreach (var split in possibleSplits(word, n))
     {
         SymbolicString str = splitToSymbStr(language.alphabet.ToList(), split.Item1, split.Item2, split.Item3);
         if (ProofChecker.checkContainment(str, language, LogicalExpression.True()))
         {
             return(split);
         }
     }
     return(null);
 }
Example #10
0
        public static bool NonRegularCheckI(ArithmeticLanguage language, string start, string mid, string end, int i)
        {
            string fullWord = pumpMid(start, mid, end, i);

            if (language.symbolic_string.isFlat())
            {
                SymbolicString wordSS = Parser.parseSymbolicString(fullWord.ToString(), language.alphabet.ToList());
                return(ProofChecker.checkContainment(wordSS, language, LogicalExpression.True()));
            }
            else
            {
                throw new PumpingLemmaException("Arithmetic Language must be flat!");
            }
        }
        public DFA <string, HashSet <State <Set <State <string> > > > > ToDFA()
        {
            //check if every variable appears only once
            varsSeen = new HashSet <VariableType>();
            if (!checkVariableOnce(symbolic_string))
            {
                throw new PumpingLemmaException("Each variable must only appear once!");
            }

            NFA <string, string> nfa = null;
            var epsilonTransitions   = new HashSet <TwoTuple <State <string>, State <string> > >();

            ArithmeticLanguage unaryLanguage = this;
            var comparisons = unaryLanguage.getReducedUnaryConstraints();

            currentId = 0;

            //only epsilon
            if (symbolic_string.isEpsilon())
            {
                var startState = new State <string>(0, "0");
                var finalState = new State <string>(1, "1");
                var states     = new HashSet <State <string> >();
                states.Add(startState);
                states.Add(finalState);
                var Q_0 = new HashSet <State <string> >();
                Q_0.Add(startState);
                var F = new HashSet <State <string> >();
                F.Add(startState);
                var delta = new Dictionary <TwoTuple <State <string>, string>, HashSet <State <string> > >();
                foreach (var letter in alphabet)
                {
                    delta.Add(new TwoTuple <State <string>, string>(startState, letter), new HashSet <State <string> >(new State <string>[] { finalState }));
                }
                nfa = new NFA <string, string>(states, new HashSet <string>(alphabet), delta, Q_0, F);
            }
            else
            {
                var tuple = epsNFA(symbolic_string, new HashSet <string>(alphabet), comparisons);
                nfa = tuple.Item1;
                epsilonTransitions = tuple.Item2;
            }

            NFA <string, string> nfaCollected = StringDFA.collectEpsilonTransitions(nfa.Q, new HashSet <string>(alphabet), nfa.delta, nfa.Q_0, nfa.F, epsilonTransitions);

            var dfa     = nfaCollected.NFAtoDFA();
            var dfa_min = dfa.MinimizeHopcroft();

            return(dfa_min);
        }
        public static bool check(ArithmeticLanguage language, SymbolicString pumpingString)
        {
            if (pumpingString.GetIntegerVariables().Count() != 1)
            {
                return(false);
            }
            var pumpingLength         = pumpingString.GetIntegerVariables().First();
            var pumpingLengthVariable = PumpingLemma.LinearIntegerExpression
                                        .SingleTerm(1, pumpingLength);
            var additionalConstraint = LogicalExpression.And(
                PumpingLemma.ComparisonExpression.GreaterThan(pumpingLengthVariable, 0),
                LogicalExpression.And(pumpingString.repeats().Select(x => ComparisonExpression.GreaterThanOrEqual(x, 0)))
                );

            // 0. Need to check if pumping string grows unboundedly with p
            var pumpingStringLength = pumpingString.length();

            if (pumpingStringLength.isConstant() || pumpingStringLength.coefficients[pumpingLength] < 0)
            {
                return(false);
            }
            foreach (var r in pumpingString.repeats())
            {
                if (r.coefficients[pumpingLength] < 0)
                {
                    return(false);
                }
            }

            // 1. Check that the pumping string is in the language for all p
            if (!checkContainment(pumpingString, language, additionalConstraint))
            {
                return(false);
            }

            Console.WriteLine("Language is non-regular if all the following splits are good:");
            int i = 0;

            // 2. Check that each split of the pumping string has an valid pumping length
            foreach (var split in pumpingString.ValidSplits(pumpingLengthVariable, additionalConstraint))
            {
                Console.WriteLine("\t" + (i++) + ": " + split + " when " + additionalConstraint);
                if (!splitGood(split, language, additionalConstraint))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #13
0
        public static string NonRegularGetUnpumpableWord(ArithmeticLanguage language, SymbolicString unpumpableWord, int n)
        {
            Dictionary <VariableType, int> assignment = new Dictionary <VariableType, int>();

            assignment.Add(VariableType.Variable("n"), n);
            string         word = pumpedWord(unpumpableWord, assignment);
            SymbolicString ss   = SymbolicString.FromTextDescription(language.alphabet.ToList(), word);

            while (!ProofChecker.checkContainment(ss, language, LogicalExpression.True()))
            {
                assignment[VariableType.Variable("n")]++;
                word = pumpedWord(unpumpableWord, assignment);
                ss   = SymbolicString.FromTextDescription(language.alphabet.ToList(), word);
            }
            return(word);
        }
        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();
            }
        }
        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();
            }
        }
        public static bool check(ArithmeticLanguage language, SymbolicString pumpingString)
        {
            if (pumpingString.GetIntegerVariables().Count() != 1)
                return false;
            var pumpingLength = pumpingString.GetIntegerVariables().First();
            var pumpingLengthVariable = PumpingLemma.LinearIntegerExpression
                .SingleTerm(1, pumpingLength);
            var additionalConstraint = LogicalExpression.And(
                PumpingLemma.ComparisonExpression.GreaterThan(pumpingLengthVariable, 0),
                LogicalExpression.And(pumpingString.repeats().Select(x => ComparisonExpression.GreaterThanOrEqual(x, 0)))
            );

            // 0. Need to check if pumping string grows unboundedly with p
            var pumpingStringLength = pumpingString.length();
            if (pumpingStringLength.isConstant() || pumpingStringLength.coefficients[pumpingLength] < 0)
                return false;
            foreach (var r in pumpingString.repeats())
                if (r.coefficients[pumpingLength] < 0)
                    return false;

            // 1. Check that the pumping string is in the language for all p
            if (!checkContainment(pumpingString, language, additionalConstraint))
                return false;

            Console.WriteLine("Language is non-regular if all the following splits are good:");
            int i = 0;
            // 2. Check that each split of the pumping string has an valid pumping length 
            foreach (var split in pumpingString.ValidSplits(pumpingLengthVariable, additionalConstraint))
            {
                Console.WriteLine("\t" + (i++) + ": " + split + " when " + additionalConstraint);
                if (!splitGood(split, language, additionalConstraint))
                    return false;
            }

            return true;
        }
Example #17
0
        public static int NonRegularGetI(ArithmeticLanguage language, string start, string mid, string end)
        {
            SymbolicString matchingString = splitToSymbStr(language.alphabet.ToList(), start, mid, end);

            if (ProofChecker.checkContainment(matchingString, language, LogicalExpression.True()))
            {
                return(1); // AI surrenders
            }
            else
            {
                int i = 0;
                do
                {
                    string         word = pumpMid(start, mid, end, i);
                    SymbolicString ss   = SymbolicString.FromTextDescription(language.alphabet.ToList(), word);
                    if (!ProofChecker.checkContainment(ss, language, LogicalExpression.True()))
                    {
                        return(i);
                    }
                    i++;
                } while (i < 99); //for debugging purposes
                return(-1);
            }
        }
        // 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;
        }
 public static bool checkContainment(SymbolicString s, ArithmeticLanguage l, BooleanExpression additionalConstraints)
 {
     var condition = containmentCondition(s, l, additionalConstraints);
     // Check if the containment condition is valid
     return !LogicalExpression.Not(condition).isSatisfiable();
 }
 public static bool checkNonContainment(SymbolicString s, ArithmeticLanguage l, BooleanExpression additionalConstraints)
 {
     var condition = containmentCondition(s, l, additionalConstraints);
     // Check if the containment condition is unsatisfiable
     return !condition.isSatisfiable();
 }