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 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(); } }
private static IEnumerable <Match> matchRepeatRepeat(SymbolicString s1, SymbolicString s2) { Debug.Assert(s1.root.isWord()); Debug.Assert(s2.root.isWord()); // Assume s1 is fully consumed foreach (var m in allLeftMatches(s1, s2)) { yield return(m); } // Assume s2 is fully consumed foreach (var m in allLeftMatches(s2, s1)) { yield return(m.reverse()); } // Assume both are fully consumed if (omegaEqual(s1.root, s2.root)) { yield return(Match.FullMatch(ComparisonExpression.Equal( LinearIntegerExpression.Times(s1.root.wordLength(), s1.repeat), LinearIntegerExpression.Times(s2.root.wordLength(), s2.repeat) ))); } else { yield return(Match.FullMatch(LogicalExpression.And( ComparisonExpression.Equal(s2.length(), 0), ComparisonExpression.Equal(s1.length(), 0) ))); } }
private void Copy(SymbolicString that) { this.expression_type = that.expression_type; this.atomic_symbol = that.atomic_symbol; this.root = that.root; this.repeat = that.repeat; this.sub_strings = that.sub_strings; }
public static bool canMismatchWitness( SymbolicString midLanguage, SymbolicString midSplit, BooleanExpression fullConstraint, LinearIntegerExpression pumpingWitness ) { throw new NotImplementedException(); }
public static SymbolicString repeat(SymbolicString s, LinearIntegerExpression e) { if (s == null || e == null) { return(null); } return(SymbolicString.Repeat(s, e)); }
// 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); }
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)) )); } } }
public static LinearIntegerExpression Times(int multiplier, LinearIntegerExpression b) { int constant = b.constant * multiplier; var coefficients = new Dictionary <VariableType, int>(); foreach (var kv in b.coefficients) { coefficients[kv.Key] = kv.Value * multiplier; } return(new LinearIntegerExpression(constant, coefficients)); }
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 LinearIntegerExpression length() { switch (this.expression_type) { case SymbolicStringType.Symbol: return(LinearIntegerExpression.Constant(1)); case SymbolicStringType.Concat: return(LinearIntegerExpression.Plus(this.sub_strings.Select(x => x.length()))); case SymbolicStringType.Repeat: var sub = this.root.length(); Contract.Assert(sub.isConstant()); return(LinearIntegerExpression.Times(sub.constant, this.repeat)); default: throw new ArgumentOutOfRangeException(); } }
// Generates splits (x, y, z) such that |y| > 0 and |xy| < p public IEnumerable <Split> ValidSplits( LinearIntegerExpression pumpingLengthVariable, BooleanExpression additionalConstraints) { foreach (var split in this.Splits()) { if (split.mid.isEpsilon()) { continue; } var cond1 = ComparisonExpression.GreaterThan(split.mid.length(), LinearIntegerExpression.Constant(0)); var cond2 = ComparisonExpression.LessThan(split.start.length() + split.mid.length(), pumpingLengthVariable); var condition = LogicalExpression.And(additionalConstraints, cond1, cond2); if (condition.isMaybeSatisfiable()) { split.AddConstraint(condition); yield return(split); } } }
private ComparisonExpression(ComparisonOperator op, LinearIntegerExpression oper1, LinearIntegerExpression oper2) { boolean_expression_type = OperatorType.Comparison; switch (op) { case ComparisonOperator.LEQ: boolean_operation_arity = OperatorArity.Two; break; case ComparisonOperator.LT: boolean_operation_arity = OperatorArity.Two; break; case ComparisonOperator.GEQ: boolean_operation_arity = OperatorArity.Two; break; case ComparisonOperator.GT: boolean_operation_arity = OperatorArity.Two; break; case ComparisonOperator.EQ: boolean_operation_arity = OperatorArity.Two; break; case ComparisonOperator.NEQ: boolean_operation_arity = OperatorArity.Two; break; default: throw new ArgumentOutOfRangeException(); } comparison_operator = op; operand1 = oper1; operand2 = oper2; arithmetic_operand1 = oper1; arithmetic_operand2 = oper2; }
// 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(); } }
private SymbolicString(SymbolicString root, LinearIntegerExpression repeat) { this.expression_type = SymbolicStringType.Repeat; this.root = root; this.repeat = repeat; }
private static UnaryComparison compExprToUnaryComp(ComparisonExpression expr) { if (!expr.isUnary()) { return(null); } if (expr.arithmetic_operand1.isConstant()) { LinearIntegerExpression tmp = expr.arithmetic_operand1; expr.arithmetic_operand1 = expr.arithmetic_operand2; expr.arithmetic_operand2 = tmp; switch (expr.comparison_operator) { case ComparisonExpression.ComparisonOperator.GEQ: expr.comparison_operator = ComparisonExpression.ComparisonOperator.LEQ; break; case ComparisonExpression.ComparisonOperator.GT: expr.comparison_operator = ComparisonExpression.ComparisonOperator.LT; break; case ComparisonExpression.ComparisonOperator.LEQ: expr.comparison_operator = ComparisonExpression.ComparisonOperator.GEQ; break; case ComparisonExpression.ComparisonOperator.LT: expr.comparison_operator = ComparisonExpression.ComparisonOperator.GT; break; default: break; } } VariableType variable = expr.GetVariables().First(); int coefficient = expr.arithmetic_operand1.coefficients[variable]; int constant = expr.arithmetic_operand2.constant; double divided = (double)constant / (double)coefficient; switch (expr.comparison_operator) { case ComparisonExpression.ComparisonOperator.EQ: case ComparisonExpression.ComparisonOperator.NEQ: if (!isInt(divided)) { return(null); } else { expr.arithmetic_operand2 = LinearIntegerExpression.Constant(Convert.ToInt32(divided)); } break; case ComparisonExpression.ComparisonOperator.GEQ: expr.arithmetic_operand2 = LinearIntegerExpression.Constant(Convert.ToInt32(Math.Ceiling(divided))); break; case ComparisonExpression.ComparisonOperator.GT: expr.arithmetic_operand2 = LinearIntegerExpression.Constant(Convert.ToInt32(Math.Floor(divided))); break; case ComparisonExpression.ComparisonOperator.LEQ: expr.arithmetic_operand2 = LinearIntegerExpression.Constant(Convert.ToInt32(Math.Floor(divided))); break; case ComparisonExpression.ComparisonOperator.LT: expr.arithmetic_operand2 = LinearIntegerExpression.Constant(Convert.ToInt32(Math.Ceiling(divided))); break; default: throw new ArgumentException(); } if (expr.comparison_operator == ComparisonExpression.ComparisonOperator.GEQ) { expr.comparison_operator = ComparisonExpression.ComparisonOperator.GT; expr.arithmetic_operand2.constant--; } if (expr.comparison_operator == ComparisonExpression.ComparisonOperator.LEQ) { expr.comparison_operator = ComparisonExpression.ComparisonOperator.LT; expr.arithmetic_operand2.constant++; } switch (expr.comparison_operator) { case ComparisonExpression.ComparisonOperator.EQ: return(UnaryComparison.equal(variable, expr.arithmetic_operand2.constant)); case ComparisonExpression.ComparisonOperator.GT: return(UnaryComparison.greater(variable, expr.arithmetic_operand2.constant, new HashSet <int>())); case ComparisonExpression.ComparisonOperator.LT: return(UnaryComparison.between(variable, -1, expr.arithmetic_operand2.constant, new HashSet <int>())); default: return(null); } }
public static ComparisonExpression GreaterThanOrEqual(LinearIntegerExpression op1, LinearIntegerExpression op2) { return new ComparisonExpression(ComparisonOperator.GEQ, op1, op2); }
public static ComparisonExpression LessThan(LinearIntegerExpression op1, LinearIntegerExpression op2) { return new ComparisonExpression(ComparisonOperator.LT, op1, op2); }
public static LinearIntegerExpression operator -(LinearIntegerExpression a, int b) { return(Plus(a, LinearIntegerExpression.Constant(-b))); }
public static LinearIntegerExpression operator -(LinearIntegerExpression a, LinearIntegerExpression b) { return(Plus(a, LinearIntegerExpression.Times(-1, b))); }
public static LinearIntegerExpression Plus(LinearIntegerExpression a, LinearIntegerExpression b) { return(Plus(new List <LinearIntegerExpression> { a, b })); }
public static ComparisonExpression LessThan(LinearIntegerExpression op1, int op2) { return(LessThan(op1, LinearIntegerExpression.Constant(op2))); }
public static ComparisonExpression NotEqual(LinearIntegerExpression op1, int op2) { return(NotEqual(op1, LinearIntegerExpression.Constant(op2))); }
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); }
public static ComparisonExpression NotEqual(LinearIntegerExpression op1, LinearIntegerExpression op2) { return new ComparisonExpression(ComparisonOperator.NEQ, op1, op2); }
public static ComparisonExpression LessThan(LinearIntegerExpression op1, int op2) { return LessThan(op1, LinearIntegerExpression.Constant(op2)); }
// Generates splits (x, y, z) such that |y| > 0 and |xy| < p public IEnumerable<Split> ValidSplits( LinearIntegerExpression pumpingLengthVariable, BooleanExpression additionalConstraints) { foreach (var split in this.Splits()) { if (split.mid.isEpsilon()) continue; var cond1 = ComparisonExpression.GreaterThan(split.mid.length(), LinearIntegerExpression.Constant(0)); var cond2 = ComparisonExpression.LessThan(split.start.length() + split.mid.length(), pumpingLengthVariable); var condition = LogicalExpression.And(additionalConstraints, cond1, cond2); if (condition.isMaybeSatisfiable()) { split.AddConstraint(condition); yield return split; } } }
public static ComparisonExpression NotEqual(LinearIntegerExpression op1, LinearIntegerExpression op2) { return(new ComparisonExpression(ComparisonOperator.NEQ, op1, op2)); }
// Generates XML for the public XElement SplitDisplayXML( VariableType pumpingLength, BooleanExpression additionalConstraints) { Contract.Assert(additionalConstraints.GetVariables().Count() <= 1); if (additionalConstraints.GetVariables().Count == 1) { Contract.Assert(additionalConstraints.GetVariables().First().Equals(pumpingLength)); } var pumpingLengthVariable = LinearIntegerExpression.SingleTerm(1, pumpingLength); var repeatLengths = repeats(); // For great and inexplicable reasons. Trust me, it looks better this way. var displayConstraints = LogicalExpression.And(repeatLengths.Select(x => ComparisonExpression.GreaterThanOrEqual(x, LinearIntegerExpression.Constant(5)) )); XElement symbstrings = new XElement("symbstrings"); foreach (var split in this.ValidSplits(pumpingLengthVariable, additionalConstraints)) { var splitRepeatLengths = split.start.repeats(); splitRepeatLengths.AddRange(split.mid.repeats()); splitRepeatLengths.AddRange(split.end.repeats()); // Get models that don't look terrible var splitDisplayConstraints = LogicalExpression.And(splitRepeatLengths.Select(x => ComparisonExpression.GreaterThanOrEqual(x, LinearIntegerExpression.Constant(1)) )); var constraint = LogicalExpression.And(displayConstraints, split.constraints, splitDisplayConstraints); if (!constraint.isSatisfiable()) { continue; } var splitModel = constraint.getModel(); var symbstr = new XElement("symbstr"); var strings = new XElement("strings"); var splits = new XElement("splits"); var constrs = new XElement("constraints"); Func <string, Tuple <int, int, SymbolicString>, XElement> handleSegment = (parentTagName, segment) => { var parent = new XElement(parentTagName); var from = new XElement("from"); from.Value = segment.Item1.ToString(); var to = new XElement("to"); to.Value = segment.Item2.ToString(); var label = new XElement("label"); label.Add(segment.Item3.ToDisplayXML()); parent.Add(from); parent.Add(to); parent.Add(label); return(parent); }; int strIndex = 0; foreach (var segment in getSegments(splitModel, ref strIndex)) { strings.Add(handleSegment("string", segment)); } int splitIndex = 0; foreach (var segment in new[] { split.start, split.mid, split.end }) { splits.Add(handleSegment("split", segment.makeSegment(splitModel, ref splitIndex))); } var constr = new XElement("constraint"); constr.Add(split.constraints.ToDisplayXML()); constrs.Add(constr); symbstr.Add(strings); symbstr.Add(splits); symbstr.Add(constrs); symbstrings.Add(symbstr); } return(symbstrings); }
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(); } }
// 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(); } }
public static ArithmeticLanguage FromTextDescriptions(List <String> alphabet, string symbolicStringText, string constraintText) { var symbolPattern = new Regex(@"^[a-zA-Z0-9]$"); var illegalSymbols = alphabet.FindAll(s => !symbolPattern.IsMatch(s)); if (illegalSymbols.Count > 0) { var message = string.Format( "Found illegal symbols {0} in alphabet. Symbols should match [a-zA-Z0-9]", string.Join(", ", illegalSymbols) ); throw new PumpingLemmaException(message); } // Parse the language var ss = PumpingLemma.Parser.parseSymbolicString(symbolicStringText, alphabet); if (ss == null) { throw new PumpingLemmaException("Unable to parse language"); } // Parse the constraintDesc var constraint = PumpingLemma.Parser.parseCondition(constraintText); if (constraint == null) { throw new PumpingLemmaException("Unable to parse constraint"); } // Make sure all the variables are bound var boundVariables = ss.GetIntegerVariables(); var constraintVariables = constraint.GetVariables(); // Console.WriteLine("Bound variables: " + String.Join(", ", boundVariables)); // Console.WriteLine("Constriant variables: " + String.Join(", ", constraintVariables)); foreach (var consVar in constraintVariables) { if (!boundVariables.Contains(consVar)) { throw new PumpingLemmaException( string.Format("Constraint variable {0} not bound", consVar)); } } // Add constraints saying that all variables are >= 0 BooleanExpression defaultConstraint = LogicalExpression.True(); foreach (var consVar in constraintVariables) { defaultConstraint = LogicalExpression.And( defaultConstraint, ComparisonExpression.GreaterThanOrEqual( LinearIntegerExpression.SingleTerm(1, consVar), LinearIntegerExpression.Constant(0) ) ); } return(new ArithmeticLanguage(alphabet, ss, constraint)); }
// 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 SymbolicString Repeat(SymbolicString root, LinearIntegerExpression repeat) { return(new SymbolicString(root, repeat)); }
public static SymbolicString Repeat(SymbolicString root, LinearIntegerExpression repeat) { return new SymbolicString(root, repeat); }
public static ComparisonExpression GreaterThanOrEqual(LinearIntegerExpression op1, int op2) { return GreaterThanOrEqual(op1, LinearIntegerExpression.Constant(op2)); }
public static ComparisonExpression GreaterThanOrEqual(LinearIntegerExpression op1, int op2) { return(GreaterThanOrEqual(op1, LinearIntegerExpression.Constant(op2))); }
public static SymbolicString repeat(SymbolicString s, LinearIntegerExpression e) { if (s == null || e == null) return null; return SymbolicString.Repeat(s, e); }
public static ComparisonExpression NotEqual(LinearIntegerExpression op1, int op2) { return NotEqual(op1, LinearIntegerExpression.Constant(op2)); }
public Dictionary <VariableType, UnaryComparison> getReducedUnaryConstraints() { if (!getComparisonExpressions(constraint).All(expr => expr.isUnary())) { throw new PumpingLemmaException("The Language doesn't contain only unary constraints."); } if (!constraint.isSatisfiable()) { throw new PumpingLemmaException("The Language constraint is not satisfiable."); } Dictionary <VariableType, UnaryComparison> comparisonsToReturn = new Dictionary <VariableType, UnaryComparison>(); IEnumerable <ComparisonExpression> allExpr = getComparisonExpressions(constraint); //delete non-constraints allExpr = allExpr.Except(allExpr.Where(e => e.arithmetic_operand1.isConstant() && e.arithmetic_operand2.isConstant())); //put variable on left side //divide, so that coefficient = 1 HashSet <ComparisonExpression> ToDelete = new HashSet <ComparisonExpression>(); var exprToAdd = new HashSet <ComparisonExpression>(); foreach (ComparisonExpression expr in allExpr) { if (expr.arithmetic_operand1.isConstant()) { switch (expr.comparison_operator) { case ComparisonExpression.ComparisonOperator.GEQ: exprToAdd.Add(ComparisonExpression.LessThanOrEqual(expr.arithmetic_operand2, expr.arithmetic_operand1)); break; case ComparisonExpression.ComparisonOperator.GT: exprToAdd.Add(ComparisonExpression.LessThan(expr.arithmetic_operand2, expr.arithmetic_operand1)); break; case ComparisonExpression.ComparisonOperator.LEQ: exprToAdd.Add(ComparisonExpression.GreaterThanOrEqual(expr.arithmetic_operand2, expr.arithmetic_operand1)); break; case ComparisonExpression.ComparisonOperator.LT: exprToAdd.Add(ComparisonExpression.GreaterThan(expr.arithmetic_operand2, expr.arithmetic_operand1)); break; default: break; } } } ToDelete = new HashSet <ComparisonExpression>(allExpr.Where(e => e.arithmetic_operand1.isConstant())); allExpr = allExpr.Except(ToDelete); allExpr = allExpr.Union(exprToAdd); ToDelete = new HashSet <ComparisonExpression>(); exprToAdd = new HashSet <ComparisonExpression>(); foreach (var expr in allExpr) { foreach (VariableType variable in expr.GetVariables()) { int coefficient = expr.arithmetic_operand1.coefficients[variable]; int constant = expr.arithmetic_operand2.constant; double divided = (double)constant / (double)coefficient; switch (expr.comparison_operator) { case ComparisonExpression.ComparisonOperator.EQ: case ComparisonExpression.ComparisonOperator.NEQ: if (!isInt(divided)) { ToDelete.Add(expr); } else { expr.arithmetic_operand2 = LinearIntegerExpression.Constant(Convert.ToInt32(divided)); } break; case ComparisonExpression.ComparisonOperator.GEQ: expr.arithmetic_operand2 = LinearIntegerExpression.Constant(Convert.ToInt32(Math.Ceiling(divided))); break; case ComparisonExpression.ComparisonOperator.GT: expr.arithmetic_operand2 = LinearIntegerExpression.Constant(Convert.ToInt32(Math.Floor(divided))); break; case ComparisonExpression.ComparisonOperator.LEQ: expr.arithmetic_operand2 = LinearIntegerExpression.Constant(Convert.ToInt32(Math.Floor(divided))); break; case ComparisonExpression.ComparisonOperator.LT: expr.arithmetic_operand2 = LinearIntegerExpression.Constant(Convert.ToInt32(Math.Ceiling(divided))); break; default: throw new ArgumentException(); } } } allExpr = allExpr.Except(ToDelete); allExpr = allExpr.Union(exprToAdd); ToDelete = new HashSet <ComparisonExpression>(); exprToAdd = new HashSet <ComparisonExpression>(); //reduce if equal constraint is found HashSet <string> varsToDelete = new HashSet <string>(); foreach (ComparisonExpression expr in allExpr) { if (expr.comparison_operator == ComparisonExpression.ComparisonOperator.EQ) { VariableType variable = expr.arithmetic_operand1.GetVariables().First(); int coefficient = expr.arithmetic_operand1.coefficients[variable]; int constant = expr.arithmetic_operand2.constant; int divided = divideConstant(constant, coefficient); comparisonsToReturn.Add(variable, UnaryComparison.equal(variable, divided)); varsToDelete.Add(variable.ToString()); } } IEnumerable <ComparisonExpression> exprToDelete = allExpr.Where(e => varsToDelete.Contains(e.arithmetic_operand1.GetVariables().First().ToString())); allExpr = allExpr.Except(exprToDelete); //GEQ -> GT, LEQ -> LT exprToDelete = new HashSet <ComparisonExpression>(); exprToAdd = new HashSet <ComparisonExpression>(); foreach (ComparisonExpression expr in allExpr) { if (expr.comparison_operator == ComparisonExpression.ComparisonOperator.GEQ) { ComparisonExpression newExpr = ComparisonExpression.GreaterThan(expr.arithmetic_operand1, expr.arithmetic_operand2.constant - 1); exprToAdd.Add(newExpr); } if (expr.comparison_operator == ComparisonExpression.ComparisonOperator.LEQ) { ComparisonExpression newExpr = ComparisonExpression.LessThan(expr.arithmetic_operand1, expr.arithmetic_operand2.constant + 1); exprToAdd.Add(newExpr); } } exprToDelete = allExpr.Where(e => e.comparison_operator == ComparisonExpression.ComparisonOperator.LEQ || e.comparison_operator == ComparisonExpression.ComparisonOperator.GEQ); allExpr = allExpr.Except(exprToDelete); allExpr = allExpr.Union(exprToAdd); HashSet <VariableType> allVars = new HashSet <VariableType>(); foreach (ComparisonExpression expr in allExpr) { allVars.Add(expr.arithmetic_operand1.GetVariables().First()); } foreach (VariableType variable in allVars) { IEnumerable <ComparisonExpression> varExpr = allExpr.Where(e => variable.ToString().Equals(e.GetVariables().First().ToString())); //reduce to single constraints IEnumerable <ComparisonExpression> gtExpr = varExpr.Where(e => e.comparison_operator == ComparisonExpression.ComparisonOperator.GT); int gthan = -1; foreach (ComparisonExpression expr in gtExpr) { int coefficient = expr.arithmetic_operand1.coefficients[variable]; int constant = expr.arithmetic_operand2.constant; //floor int divided = constant / coefficient; if (constant > gthan) { gthan = constant; } } IEnumerable <ComparisonExpression> ltExpr = varExpr.Where(e => e.comparison_operator == ComparisonExpression.ComparisonOperator.LT); int lthan = Int32.MaxValue; foreach (ComparisonExpression expr in ltExpr) { int coefficient = expr.arithmetic_operand1.coefficients[variable]; int constant = expr.arithmetic_operand2.constant; if (constant < lthan) { lthan = constant; } } varExpr = varExpr.Except(gtExpr); varExpr = varExpr.Except(ltExpr); //rest should be NEQ HashSet <int> neqInts = new HashSet <int>(); foreach (ComparisonExpression expr in varExpr) { if (expr.comparison_operator != ComparisonExpression.ComparisonOperator.NEQ) { throw new PumpingLemmaException("The programmer is stupid."); } int coefficient = expr.arithmetic_operand1.coefficients[variable]; int constant = expr.arithmetic_operand2.constant; double divided = (double)constant / coefficient; //if not int, discard if (Math.Abs(divided % 1) <= (Double.Epsilon * 100)) { int divided_int = (int)divided; neqInts.Add(divided_int); } } if (gthan > -1 && lthan < Int32.MaxValue) { comparisonsToReturn.Add(variable, UnaryComparison.between(variable, gthan, lthan, neqInts)); } else if (gthan > -1 && lthan == Int32.MaxValue) { comparisonsToReturn.Add(variable, UnaryComparison.greater(variable, gthan, neqInts)); } else if (gthan == -1 && lthan < Int32.MaxValue) { comparisonsToReturn.Add(variable, UnaryComparison.between(variable, -1, lthan, neqInts)); } else { comparisonsToReturn.Add(variable, UnaryComparison.greater(variable, -1, neqInts)); } } return(comparisonsToReturn); }
public static LinearIntegerExpression Times(int multiplier, LinearIntegerExpression b) { int constant = b.constant * multiplier; var coefficients = new Dictionary<VariableType, int>(); foreach (var kv in b.coefficients) coefficients[kv.Key] = kv.Value * multiplier; return new LinearIntegerExpression(constant, coefficients); }
private static Tuple <NFA <string, string>, HashSet <TwoTuple <State <string>, State <string> > > > epsNFA(SymbolicString symbolicString, HashSet <string> alphabet, Dictionary <VariableType, UnaryComparison> comparisons) { var states = new HashSet <State <string> >(); var delta = new Dictionary <TwoTuple <State <string>, string>, HashSet <State <string> > >(); var Q_0 = new HashSet <State <string> >(); var F = new HashSet <State <string> >(); var epsilonTransitions = new HashSet <TwoTuple <State <string>, State <string> > >(); var nfa = new NFA <string, string>(states, alphabet, delta, Q_0, F); switch (symbolicString.expression_type) { case SymbolicString.SymbolicStringType.Symbol: var symbol = symbolicString.atomic_symbol; var q_0 = createState(); Q_0.Add(q_0); states.Add(q_0); var q_1 = createState(); states.Add(q_1); F.Add(q_1); var twoTuple = new TwoTuple <State <string>, string>(q_0, symbol); var to = new HashSet <State <string> >(); to.Add(q_1); delta.Add(twoTuple, to); nfa = new NFA <string, string>(states, alphabet, delta, Q_0, F); return(Tuple.Create(nfa, epsilonTransitions)); case SymbolicString.SymbolicStringType.Concat: var listOfNFAs = new LinkedList <Tuple <NFA <string, string>, HashSet <TwoTuple <State <string>, State <string> > > > >(); foreach (SymbolicString str in symbolicString.sub_strings) { listOfNFAs.AddLast(epsNFA(str, alphabet, comparisons)); } return(concatAutomata(listOfNFAs)); case SymbolicString.SymbolicStringType.Repeat: LinearIntegerExpression lie = symbolicString.repeat; var lisNFAs = new LinkedList <Tuple <NFA <string, string>, HashSet <TwoTuple <State <string>, State <string> > > > >(); for (int i = 0; i < lie.constant; i++) { lisNFAs.AddLast(epsNFA(symbolicString.root, alphabet, comparisons)); } foreach (var coeff in lie.coefficients) { var compar = comparisons[coeff.Key]; switch (compar.comparisonType) { case UnaryComparison.ComparisonType.EQUAL: for (int i = 0; i < coeff.Value * compar.constant; i++) { lisNFAs.AddLast(epsNFA(symbolicString.root, alphabet, comparisons)); } break; case UnaryComparison.ComparisonType.GREATER: for (int i = 0; i < coeff.Value * (compar.min + 1) - 1; i++) { lisNFAs.AddLast(epsNFA(symbolicString.root, alphabet, comparisons)); } var autom = epsNFA(symbolicString.root, alphabet, comparisons); var autom_start = autom.Item1.Q_0.First(); var newEpsTrans = new HashSet <TwoTuple <State <string>, State <string> > >(); newEpsTrans.UnionWith(autom.Item2); foreach (var acceptingState in autom.Item1.F) { newEpsTrans.Add(new TwoTuple <State <string>, State <string> >(acceptingState, autom_start)); } lisNFAs.AddLast(Tuple.Create(autom.Item1, newEpsTrans)); break; case UnaryComparison.ComparisonType.BETWEEN: for (int i = 0; i < coeff.Value * compar.min; i++) { lisNFAs.AddLast(epsNFA(symbolicString.root, alphabet, comparisons)); } var rememberedStates = new HashSet <State <string> >(); int upperbound = 0; if (compar.min == -1 || compar.min == 0) { upperbound = compar.max - 1; } else { upperbound = compar.max - compar.min - 1; } for (int i = 0; i < coeff.Value * upperbound; i++) { var aut = epsNFA(symbolicString.root, alphabet, comparisons); foreach (var q_f in aut.Item1.F) { rememberedStates.Add(q_f); } lisNFAs.AddLast(aut); } if (compar.min == -1) { rememberedStates.Add(lisNFAs.First.Value.Item1.Q_0.First()); } var epsTrans = new HashSet <TwoTuple <State <string>, State <string> > >(); var lastAut = lisNFAs.Last.Value; foreach (var state in rememberedStates) { foreach (var q_f in lastAut.Item1.F) { epsTrans.Add(new TwoTuple <State <string>, State <string> >(state, q_f)); } } lisNFAs.RemoveLast(); lisNFAs.AddLast(Tuple.Create(lastAut.Item1, new HashSet <TwoTuple <State <string>, State <string> > >(epsTrans.Union(lastAut.Item2)))); break; } } return(concatAutomata(lisNFAs)); default: throw new ArgumentException(); } }
public static LinearIntegerExpression Plus(LinearIntegerExpression a, LinearIntegerExpression b) { return Plus(new List<LinearIntegerExpression> { a, b }); }