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()); }
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); }
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)); }
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); }
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); }
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; }
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(); }