public override string ToString() { StringBuilder sb = new StringBuilder(); switch (comparisonType) { case ComparisonType.EQUAL: return(variable.ToString() + " == " + constant); case ComparisonType.GREATER: sb.Append(variable.ToString() + " > " + constant); foreach (int i in neq) { sb.Append(" && " + variable.ToString() + " != " + i); } return(sb.ToString()); case ComparisonType.BETWEEN: if (min == -1) { sb.Append(variable.ToString() + " < " + max); } else { sb.Append(min + " < " + variable.ToString() + " < " + max); } foreach (int i in neq) { sb.Append(" && " + variable.ToString() + " != " + i); } return(sb.ToString()); default: throw new ArgumentException(); } }
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); }
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); }