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