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 Match PartialFirst(BooleanExpression _c, SymbolicString remaining1) { return new Match( _c, remaining1, SymbolicString.Epsilon() ); }
internal Match withAdditionalConstraint(BooleanExpression additionalConstraint) { return new Match( LogicalExpression.And(this.constraint, additionalConstraint), this.remaining1, this.remaining2 ); }
public static Match FullMatch(BooleanExpression _c) { return new Match( _c, SymbolicString.Epsilon(), SymbolicString.Epsilon() ); }
public static Match PartialSecond(BooleanExpression _c, SymbolicString remaining2) { return new Match( _c, SymbolicString.Epsilon(), remaining2 ); }
// 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); }
// 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 QuantifiedExpression Forall(IEnumerable<VariableType> vars, BooleanExpression b) { return Make(Quantifier.Forall, vars, b); }
public static QuantifiedExpression Make(Quantifier q, IEnumerable<VariableType> vars, BooleanExpression b) { var freeVars = b.GetVariables(); foreach (var v in vars) if (!freeVars.Contains(v)) throw new ArgumentException(); return new QuantifiedExpression(q, vars, b); }
public static LogicalExpression Not(BooleanExpression op1) { return new LogicalExpression(LogicalOperator.Not, op1, null); }
private Split(SymbolicString s, SymbolicString m, SymbolicString e, BooleanExpression c) { start = s; mid = m; end = e; start.flatten(); mid.flatten(); end.flatten(); constraints = c; }
public static BooleanExpression Implies(BooleanExpression op1, BooleanExpression op2) { return(LogicalExpression.Or(LogicalExpression.Not(op1), op2)); }
public static bool canMismatchOne(SymbolicString language, SymbolicString midSplit, BooleanExpression fullConstraint) { /* var matches = Matcher .matchRepeatedFull(language, midSplit) .Select(x => x.finishMatch()); foreach (var match in matches) { var x = LogicalExpression.And(match.constraint, fullConstraint); // Do something here } */ throw new NotImplementedException(); }
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 TwoSplit MakeSplit(SymbolicString s, SymbolicString e, BooleanExpression c) { return new TwoSplit(s, e, c); }
private TwoSplit(SymbolicString s, SymbolicString e, BooleanExpression c) { start = s; end = e; constraints = c; }
public void AddConstraint(BooleanExpression c) { this.constraints = LogicalExpression.And(this.constraints, c); }
private Match(BooleanExpression _c, SymbolicString _s1, SymbolicString _s2) { this.constraint = _c; this.remaining1 = _s1; this.remaining2 = _s2; }
private LogicalExpression(LogicalOperator op, BooleanExpression oper1, BooleanExpression oper2) { boolean_expression_type = OperatorType.Logical; switch (op) { case LogicalOperator.True: boolean_operation_arity = OperatorArity.Zero; break; case LogicalOperator.False: boolean_operation_arity = OperatorArity.Zero; break; case LogicalOperator.And: boolean_operation_arity = OperatorArity.Two; break; case LogicalOperator.Or: boolean_operation_arity = OperatorArity.Two; break; case LogicalOperator.Not: boolean_operation_arity = OperatorArity.One; break; } logical_operator = op; operand1 = oper1; operand2 = oper2; boolean_operand1 = oper1; boolean_operand2 = oper2; }
internal static Match MakeMatch(BooleanExpression _c, SymbolicString remaining1, SymbolicString remaining2) { return new Match(_c, remaining1, remaining2); }
public static BooleanExpression Implies(BooleanExpression op1, BooleanExpression op2) { return LogicalExpression.Or(LogicalExpression.Not(op1), op2); }
public static LogicalExpression Or(BooleanExpression op1, BooleanExpression op2) { return(new LogicalExpression(LogicalOperator.Or, op1, op2)); }
public static bool canMismatchWitness( SymbolicString midLanguage, SymbolicString midSplit, BooleanExpression fullConstraint, LinearIntegerExpression pumpingWitness ) { throw new NotImplementedException(); }
public static LogicalExpression Not(BooleanExpression op1) { return(new LogicalExpression(LogicalOperator.Not, op1, null)); }
public static QuantifiedExpression Make(Quantifier q, IEnumerable <VariableType> vars, BooleanExpression b) { var freeVars = b.GetVariables(); foreach (var v in vars) { if (!freeVars.Contains(v)) { throw new ArgumentException(); } } return(new QuantifiedExpression(q, vars, b)); }
public static BooleanExpression And(BooleanExpression op1, BooleanExpression op2) { if (op1 as LogicalExpression != null && (op1 as LogicalExpression).logical_operator == LogicalOperator.True) return op2; if (op2 as LogicalExpression != null && (op2 as LogicalExpression).logical_operator == LogicalOperator.True) return op1; return new LogicalExpression(LogicalOperator.And, op1, op2); }
public static QuantifiedExpression Exists(IEnumerable <VariableType> vars, BooleanExpression b) { return(Make(Quantifier.Exists, vars, b)); }
public static LogicalExpression Or(BooleanExpression op1, BooleanExpression op2) { return new LogicalExpression(LogicalOperator.Or, op1, op2); }
public static QuantifiedExpression Forall(IEnumerable <VariableType> vars, BooleanExpression b) { return(Make(Quantifier.Forall, vars, b)); }
private QuantifiedExpression(Quantifier q, IEnumerable<VariableType> v, BooleanExpression oper1) { quantified_variables = new HashSet<VariableType>(); quantified_variables.UnionWith(v); boolean_expression_type = OperatorType.Quantifier; boolean_operation_arity = OperatorArity.One; switch (q) { case Quantifier.Exists: case Quantifier.Forall: quantifier = q; break; default: throw new ArgumentOutOfRangeException(); } operand1 = inner = oper1; }
// 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 QuantifiedExpression Exists(IEnumerable<VariableType> vars, BooleanExpression b) { return Make(Quantifier.Exists, vars, b); }
// 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 ArithmeticLanguage(IEnumerable<String> _alphabet, SymbolicString _symbolic_string, BooleanExpression _constraint) { this.alphabet = _alphabet; this.symbolic_string = _symbolic_string; this.constraint = _constraint; }
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(); }