public override Answer CheckVariableDisequality(Element /*!*/ e, IVariable /*!*/ var1, IVariable /*!*/ var2) { //Contract.Requires(var2 != null); //Contract.Requires(var1 != null); //Contract.Requires(e != null); PolyhedraLatticeElement /*!*/ ple = (PolyhedraLatticeElement)cce.NonNull(e); Contract.Assume(ple.lcs.Constraints != null); ArrayList /*LinearConstraint!*//*!*/ clist = (ArrayList /*LinearConstraint!*/)cce.NonNull(ple.lcs.Constraints.Clone()); LinearConstraint /*!*/ lc = new LinearConstraint(LinearConstraint.ConstraintRelation.EQ); Contract.Assert(lc != null); lc.SetCoefficient(var1, Rational.ONE); lc.SetCoefficient(var2, Rational.MINUS_ONE); clist.Add(lc); LinearConstraintSystem newLcs = new LinearConstraintSystem(clist); if (newLcs.IsBottom()) { return(Answer.Yes); } else { return(Answer.Maybe); } }
/// <summary> /// Precondition: positive || constraint.Relation == LinearConstraint.ConstraintRelation.EQ /// </summary> /// <param name="positive"></param> /// <param name="constraint"></param> public LinearConditionLiteral(bool positive, LinearConstraint /*!*/ constraint) { Contract.Requires(constraint != null); Contract.Requires(positive || constraint.Relation == LinearConstraint.ConstraintRelation.EQ); this.positive = positive; this.constraint = constraint; }
/// <summary> /// Adds to "lines" the lines implied by initial-variable columns not in basis /// (see section 3.4.2 of Cousot and Halbwachs), and adds to "constraints" the /// constraints to exclude those lines (see step 4.2 of section 3.4.3 of /// Cousot and Halbwachs). /// </summary> /// <param name="lines"></param> /// <param name="constraints"></param> public void ProduceLines(ArrayList /*FrameElement*//*!*/ lines, ArrayList /*LinearConstraint*//*!*/ constraints) { Contract.Requires(constraints != null); Contract.Requires(lines != null); // for every initial variable not in basis for (int i0 = 0; i0 < numInitialVars; i0++) { if (inBasis[i0] == -1) { FrameElement fe = new FrameElement(); LinearConstraint lc = new LinearConstraint(LinearConstraint.ConstraintRelation.EQ); for (int i = 0; i < numInitialVars; i++) { if (i == i0) { fe.AddCoordinate((IVariable)cce.NonNull(dims[i]), Rational.ONE); lc.SetCoefficient((IVariable)cce.NonNull(dims[i]), Rational.ONE); } else if (inBasis[i] != -1) { // i is a basis column Contract.Assert(m[inBasis[i], i].HasValue(1)); Rational val = -m[inBasis[i], i0]; fe.AddCoordinate((IVariable)cce.NonNull(dims[i]), val); lc.SetCoefficient((IVariable)cce.NonNull(dims[i]), val); } } lines.Add(fe); constraints.Add(lc); } } }
public LinearConstraint Clone() { LinearConstraint z = new LinearConstraint(Relation); z.coefficients = (Hashtable /*IVariable->Rational*/)this.coefficients.Clone(); z.rhs = this.rhs; return(z); }
public override void AddToConstraintSystem(ArrayList /*!*/ /*LinearConstraint*/ clist) { //Contract.Requires(clist != null); // make an unsatisfiable constraint LinearConstraint lc = new LinearConstraint(LinearConstraint.ConstraintRelation.EQ); lc.rhs = Rational.FromInt(1); clist.Add(lc); }
/// <summary> /// Returns a constraint like "this", but, conceptually, with the inequality relation >=. /// </summary> /// <returns></returns> public LinearConstraint /*!*/ ChangeRelationToAtLeast() { Contract.Ensures(Contract.Result <LinearConstraint>() != null); LinearConstraint z = new LinearConstraint(ConstraintRelation.LE); foreach (DictionaryEntry /*IVariable->Rational*/ entry in this.coefficients) { z.coefficients.Add(entry.Key, -(Rational)(cce.NonNull(entry.Value))); } z.rhs = -this.rhs; return(z); }
public LinearConstraint ToConstraint(LinearConstraint.ConstraintRelation rel) /* throws ArithmeticException */ { LinearConstraint constraint = new LinearConstraint(rel); for (Term t = terms; t != null; t = t.next) { constraint.SetCoefficient(t.var, t.coeff.ToRational); } BigNum rhs = -constant; constraint.rhs = rhs.ToRational; return(constraint); }
/// <summary> /// Returns a constraint like "this", but with the given relation "r". /// </summary> /// <returns></returns> public LinearConstraint /*!*/ ChangeRelation(ConstraintRelation rel) { Contract.Ensures(Contract.Result <LinearConstraint>() != null); if (Relation == rel) { return(this); } else { LinearConstraint z = new LinearConstraint(rel); z.coefficients = (Hashtable)this.coefficients.Clone(); z.rhs = this.rhs; return(z); } }
/// <summary> /// Splits an equality constraint into two inequality constraints, the conjunction of /// which equals the equality constraint. Assumes "this" is a equality constraint. /// </summary> /// <param name="a"></param> /// <param name="b"></param> public void GenerateInequalityConstraints(out LinearConstraint a, out LinearConstraint b) { System.Diagnostics.Debug.Assert(this.Relation == ConstraintRelation.EQ); a = new LinearConstraint(ConstraintRelation.LE); a.coefficients = (Hashtable)this.coefficients.Clone(); a.rhs = this.rhs; b = new LinearConstraint(ConstraintRelation.LE); b.coefficients = new Hashtable/*IVariable->Rational*/ (); foreach (DictionaryEntry entry in this.coefficients) { b.coefficients[entry.Key] = -(Rational)(cce.NonNull(entry.Value)); } b.rhs = -this.rhs; }
/// <summary> /// Changes the current constraint A*X <= B into (A + m*aa)*X <= B + m*bb, /// where "cc" is the constraint aa*X <= bb. /// </summary> /// <param name="m"></param> /// <param name="cc"></param> /// <returns></returns> public void AddMultiple(Rational m, LinearConstraint /*!*/ cc) { Contract.Requires(cc != null); foreach (DictionaryEntry /*IVariable->Rational*/ entry in cc.coefficients) { IVariable dim = (IVariable)entry.Key; Rational d = m * (Rational)(cce.NonNull(entry.Value)); if (d.IsNonZero) { object prev = coefficients[dim]; if (prev == null) { coefficients[dim] = d; } else { coefficients[dim] = (Rational)prev + d; } } } rhs += m * cc.rhs; }
public LinearConstraint Rename(IVariable /*!*/ oldName, IVariable /*!*/ newName) { Contract.Requires(newName != null); Contract.Requires(oldName != null); object /*Rational*/ z = coefficients[oldName]; if (z == null) { return(this); } else { System.Diagnostics.Debug.Assert(z is Rational); Hashtable /*IVariable->Rational*/ newCoeffs = (Hashtable /*!*/ /*IVariable->Rational*/)cce.NonNull(coefficients.Clone()); newCoeffs.Remove(oldName); newCoeffs.Add(newName, z); LinearConstraint lc = new LinearConstraint(this.Relation); lc.coefficients = newCoeffs; lc.rhs = this.rhs; return(lc); } }
/// <summary> /// Precondition: positive || constraint.Relation == LinearConstraint.ConstraintRelation.EQ /// </summary> /// <param name="positive"></param> /// <param name="constraint"></param> public LinearConditionLiteral(bool positive, LinearConstraint/*!*/ constraint) { Contract.Requires(constraint != null); Contract.Requires(positive || constraint.Relation == LinearConstraint.ConstraintRelation.EQ); this.positive = positive; this.constraint = constraint; }
static /*maybe null*/ LinearCondition GetCond(IExpr e, bool positive) /* throws ArithmeticException */ { IFunApp funapp = e as IFunApp; if (funapp == null) { return(null); } IFunctionSymbol /*!*/ s = funapp.FunctionSymbol; Contract.Assert(s != null); if ((positive && s.Equals(Prop.False)) || (!positive && s.Equals(Prop.True))) { return(new LCBottom()); } else if (s.Equals(Prop.Not)) { Contract.Assert(funapp.Arguments.Count == 1); return(GetCond((IExpr /*!*/)cce.NonNull(funapp.Arguments[0]), !positive)); } else if (funapp.Arguments.Count == 2) { IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(funapp.Arguments[0]); IExpr /*!*/ arg1 = (IExpr /*!*/)cce.NonNull(funapp.Arguments[1]); LinearExpr le0 = AsExpr(arg0); if (le0 == null) { return(null); } LinearExpr le1 = AsExpr(arg1); if (le1 == null) { return(null); } LinearConstraint constraint = null; bool sense = true; if ((positive && s.Equals(Int.Less)) || (!positive && s.Equals(Int.AtLeast))) { constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.LE, BigNum.ONE); } else if ((positive && s.Equals(Int.AtMost)) || (!positive && s.Equals(Int.Greater))) { constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.LE, BigNum.ZERO); } else if ((positive && s.Equals(Int.AtLeast)) || (!positive && s.Equals(Int.Less))) { constraint = MakeConstraint(le1, le0, LinearConstraint.ConstraintRelation.LE, BigNum.ZERO); } else if ((positive && s.Equals(Int.Greater)) || (!positive && s.Equals(Int.AtMost))) { constraint = MakeConstraint(le1, le0, LinearConstraint.ConstraintRelation.LE, BigNum.ONE); } else if (s.Equals(Int.Eq)) { constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.EQ, BigNum.ZERO); sense = positive; } else if (s.Equals(Int.Neq)) { constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.EQ, BigNum.ZERO); sense = !positive; } if (constraint != null) { if (constraint.coefficients.Count != 0) { return(new LinearConditionLiteral(sense, constraint)); } else if (constraint.IsConstantSatisfiable()) { return(null); } else { return(new LCBottom()); } } } return(null); }
public static LinearConstraint MakeConstraint(LinearExpr/*!*/ le0, LinearExpr/*!*/ le1, LinearConstraint.ConstraintRelation rel, BigNum constantOffset) /* throws ArithmeticException */ { Contract.Requires(le0 != null); Contract.Requires(le1 != null); le1.Negate(); le0.Add(le1); le0.AddConstant(constantOffset); return le0.ToConstraint(rel); }
public LinearConstraint ToConstraint(LinearConstraint.ConstraintRelation rel) /* throws ArithmeticException */ { LinearConstraint constraint = new LinearConstraint(rel); for (Term t = terms; t != null; t = t.next) { constraint.SetCoefficient(t.var, t.coeff.ToRational); } BigNum rhs = -constant; constraint.rhs = rhs.ToRational; return constraint; }
// -------------------------------------------------------------------------------------------------------- // ------------------ support routines -------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------- /// <summary> /// Returns a set of constraints that is the given set of constraints with dimension "dim" /// projected out. See Cousot and Halbwachs, section 3.3.1.1. /// </summary> /// <param name="dim"></param> /// <param name="constraints"></param> /// <returns></returns> static ArrayList /*LinearConstraint!*//*!*/ Project(IVariable/*!*/ dim, ArrayList /*LinearConstraint!*//*!*/ constraints) { Contract.Requires(constraints != null); Contract.Requires(dim != null); Contract.Ensures(Contract.Result<ArrayList>() != null); // Sort the inequality constaints into ones where dimension "dim" is 0, negative, and // positive, respectively. Put equality constraints with a non-0 "dim" into "eq". ArrayList /*LinearConstraint!*//*!*/ final = new ArrayList /*LinearConstraint!*/ (); ArrayList /*LinearConstraint!*//*!*/ negative = new ArrayList /*LinearConstraint!*/ (); ArrayList /*LinearConstraint!*//*!*/ positive = new ArrayList /*LinearConstraint!*/ (); ArrayList /*LinearConstraint!*//*!*/ eq = new ArrayList /*LinearConstraint!*/ (); foreach (LinearConstraint/*!*/ cc in constraints) { Contract.Assert(cc != null); Rational coeff = cc[dim]; if (coeff.IsZero) { LinearConstraint lc = cce.NonNull(cc.Clone()); if (!lc.IsConstant()) { lc.RemoveDimension(dim); final.Add(lc); } } else if (cc.Relation == LinearConstraint.ConstraintRelation.EQ) { eq.Add(cc); } else if (coeff.IsNegative) { negative.Add(cc); } else { System.Diagnostics.Debug.Assert(coeff.IsPositive); positive.Add(cc); } } if (eq.Count != 0) { LinearConstraint eqConstraint = (LinearConstraint/*!*/)cce.NonNull(eq[eq.Count - 1]); eq.RemoveAt(eq.Count - 1); Rational eqC = -eqConstraint[dim]; foreach (ArrayList /*LinearConstraint!*/ list in new ArrayList[] { eq, negative, positive }) { Contract.Assert(list != null); foreach (LinearConstraint/*!*/ lcX in list) { Contract.Assert(lcX != null); LinearConstraint lc = cce.NonNull(lcX.Clone()); lc.AddMultiple(lc[dim] / eqC, eqConstraint); System.Diagnostics.Debug.Assert(lc[dim].IsZero); if (!lc.IsConstant()) { lc.RemoveDimension(dim); final.Add(lc); } else { System.Diagnostics.Debug.Assert(lc.IsConstantSatisfiable()); } } } } else { // Consider all pairs of constraints with (negative,positive) coefficients of "dim". foreach (LinearConstraint/*!*/ cn in negative) { Contract.Assert(cn != null); Rational dn = -cn[dim]; System.Diagnostics.Debug.Assert(dn.IsNonNegative); foreach (LinearConstraint/*!*/ cp in positive) { Contract.Assert(cp != null); Rational dp = cp[dim]; LinearConstraint lc = new LinearConstraint(LinearConstraint.ConstraintRelation.LE); lc.AddMultiple(dn, cp); lc.AddMultiple(dp, cn); System.Diagnostics.Debug.Assert(lc[dim].IsZero); if (!lc.IsConstant()) { lc.RemoveDimension(dim); final.Add(lc); } else { System.Diagnostics.Debug.Assert(lc.IsConstantSatisfiable()); } } } } return final; }
/// <summary> /// Returns a constraint like "this", but with the given relation "r". /// </summary> /// <returns></returns> public LinearConstraint/*!*/ ChangeRelation(ConstraintRelation rel) { Contract.Ensures(Contract.Result<LinearConstraint>() != null); if (Relation == rel) { return this; } else { LinearConstraint z = new LinearConstraint(rel); z.coefficients = (Hashtable)this.coefficients.Clone(); z.rhs = this.rhs; return z; } }
public LinearConstraint Rename(IVariable/*!*/ oldName, IVariable/*!*/ newName) { Contract.Requires(newName != null); Contract.Requires(oldName != null); object /*Rational*/ z = coefficients[oldName]; if (z == null) { return this; } else { System.Diagnostics.Debug.Assert(z is Rational); Hashtable /*IVariable->Rational*/ newCoeffs = (Hashtable/*!*/ /*IVariable->Rational*/)cce.NonNull(coefficients.Clone()); newCoeffs.Remove(oldName); newCoeffs.Add(newName, z); LinearConstraint lc = new LinearConstraint(this.Relation); lc.coefficients = newCoeffs; lc.rhs = this.rhs; return lc; } }
public override void AddToConstraintSystem(ArrayList/*!*/ /*LinearConstraint*/ clist) { //Contract.Requires(clist != null); // make an unsatisfiable constraint LinearConstraint lc = new LinearConstraint(LinearConstraint.ConstraintRelation.EQ); lc.rhs = Rational.FromInt(1); clist.Add(lc); }
/// <summary> /// Changes the current constraint A*X <= B into (A + m*aa)*X <= B + m*bb, /// where "cc" is the constraint aa*X <= bb. /// </summary> /// <param name="m"></param> /// <param name="cc"></param> /// <returns></returns> public void AddMultiple(Rational m, LinearConstraint/*!*/ cc) { Contract.Requires(cc != null); foreach (DictionaryEntry /*IVariable->Rational*/ entry in cc.coefficients) { IVariable dim = (IVariable)entry.Key; Rational d = m * (Rational)(cce.NonNull(entry.Value)); if (d.IsNonZero) { object prev = coefficients[dim]; if (prev == null) { coefficients[dim] = d; } else { coefficients[dim] = (Rational)prev + d; } } } rhs += m * cc.rhs; }
/// <summary> /// Returns 0 if "this" and "c" are not equivalent constraints. If "this" and "c" /// are equivalent constraints, the non-0 return value "m" satisfies "this == m*c". /// </summary> /// <param name="c"></param> /// <returns></returns> public Rational IsEquivalent(LinearConstraint /*!*/ c) { Contract.Requires(c != null); // "m" is the scale factor. If it is 0, it hasn't been used yet. If it // is non-0, it will remain that value throughout, and it then says that // for every dimension "d", "this[d] == m * c[d]". Rational m = Rational.ZERO; ArrayList /*IVariable*/ dd = new ArrayList/*IVariable*/ (); foreach (IVariable /*!*/ d in this.GetDefinedDimensions()) { Contract.Assert(d != null); if (!dd.Contains(d)) { dd.Add(d); } } foreach (IVariable /*!*/ d in c.GetDefinedDimensions()) { Contract.Assert(d != null); if (!dd.Contains(d)) { dd.Add(d); } } foreach (IVariable /*!*/ d in dd) { Contract.Assert(d != null); Rational a = this[d]; Rational b = c[d]; if (a.IsZero || b.IsZero) { if (a.IsNonZero || b.IsNonZero) { return(Rational.ZERO); // not equivalent } } else if (m.IsZero) { m = a / b; } else if (a != m * b) { return(Rational.ZERO); // not equivalent } } // we expect there to have been some non-zero coefficient, so "m" should have been used by now System.Diagnostics.Debug.Assert(m.IsNonZero); // finally, check the rhs if (this.rhs == m * c.rhs) { return(m); // equivalent } else { return(Rational.ZERO); // not equivalent } }
LinearConstraintSystem(FrameElement/*!*/ v) { Contract.Requires(v != null); IMutableSet/*!*/ frameDims = v.GetDefinedDimensions(); Contract.Assert(frameDims != null); ArrayList /*LinearConstraint!*/ constraints = new ArrayList /*LinearConstraint!*/ (); foreach (IVariable/*!*/ dim in frameDims) { Contract.Assert(dim != null); LinearConstraint lc = new LinearConstraint(LinearConstraint.ConstraintRelation.EQ); lc.SetCoefficient(dim, Rational.ONE); lc.rhs = v[dim]; constraints.Add(lc); } FrameDimensions = frameDims; Constraints = constraints; ArrayList /*FrameElement*/ frameVertices = new ArrayList /*FrameElement*/ (); frameVertices.Add(v); FrameVertices = frameVertices; FrameRays = new ArrayList /*FrameElement*/ (); FrameLines = new ArrayList /*FrameElement*/ (); //:base(); CheckInvariant(); }
/// <summary> /// Returns 0 if "this" and "c" are not equivalent constraints. If "this" and "c" /// are equivalent constraints, the non-0 return value "m" satisfies "this == m*c". /// </summary> /// <param name="c"></param> /// <returns></returns> public Rational IsEquivalent(LinearConstraint/*!*/ c) { Contract.Requires(c != null); // "m" is the scale factor. If it is 0, it hasn't been used yet. If it // is non-0, it will remain that value throughout, and it then says that // for every dimension "d", "this[d] == m * c[d]". Rational m = Rational.ZERO; ArrayList /*IVariable*/ dd = new ArrayList /*IVariable*/ (); foreach (IVariable/*!*/ d in this.GetDefinedDimensions()) { Contract.Assert(d != null); if (!dd.Contains(d)) { dd.Add(d); } } foreach (IVariable/*!*/ d in c.GetDefinedDimensions()) { Contract.Assert(d != null); if (!dd.Contains(d)) { dd.Add(d); } } foreach (IVariable/*!*/ d in dd) { Contract.Assert(d != null); Rational a = this[d]; Rational b = c[d]; if (a.IsZero || b.IsZero) { if (a.IsNonZero || b.IsNonZero) { return Rational.ZERO; // not equivalent } } else if (m.IsZero) { m = a / b; } else if (a != m * b) { return Rational.ZERO; // not equivalent } } // we expect there to have been some non-zero coefficient, so "m" should have been used by now System.Diagnostics.Debug.Assert(m.IsNonZero); // finally, check the rhs if (this.rhs == m * c.rhs) { return m; // equivalent } else { return Rational.ZERO; // not equivalent } }
/// <summary> /// Splits an equality constraint into two inequality constraints, the conjunction of /// which equals the equality constraint. Assumes "this" is a equality constraint. /// </summary> /// <param name="a"></param> /// <param name="b"></param> public void GenerateInequalityConstraints(out LinearConstraint a, out LinearConstraint b) { System.Diagnostics.Debug.Assert(this.Relation == ConstraintRelation.EQ); a = new LinearConstraint(ConstraintRelation.LE); a.coefficients = (Hashtable)this.coefficients.Clone(); a.rhs = this.rhs; b = new LinearConstraint(ConstraintRelation.LE); b.coefficients = new Hashtable /*IVariable->Rational*/ (); foreach (DictionaryEntry entry in this.coefficients) { b.coefficients[entry.Key] = -(Rational)(cce.NonNull(entry.Value)); } b.rhs = -this.rhs; }
/// <summary> /// Adds a ray to the frame of "this" and updates Constraints accordingly, see /// Cousot and Halbwachs, section 3.3.1.1. However, this method does not simplify /// Constraints after the operation; that remains the caller's responsibility (which /// gives the caller the opportunity to make multiple calls to AddVertex, AddRay, /// and AddLine before calling SimplifyConstraints). /// Assumes Constraints (and the frame fields) to be non-null. /// </summary> /// <param name="ray"></param> void AddRay(FrameElement/*!*/ ray) { Contract.Requires(ray != null); Contract.Requires(this.FrameRays != null); #if DEBUG_PRINT Console.WriteLine("DEBUG: AddRay called on {0}", ray); Console.WriteLine(" Initial constraints:"); foreach (LinearConstraint cc in Constraints) { Console.WriteLine(" {0}", cc); } #endif FrameRays.Add(ray.Clone()); #if FIXED_DESERIALIZER Contract.Assert(Contract.ForAll(ray.GetDefinedDimensions() , var=> FrameDimensions.Contains(var))); #endif // We use a new temporary dimension. IVariable/*!*/ lambda = new LambdaDimension(); // We change the constraints A*X <= B into // A*X - (A*ray)*lambda <= B. // That means that each row k in A (which corresponds to one LinearConstraint // in Constraints) is changed by subtracting // (A*ray)[k] * lambda // from row k. // Note: // (A*ray)[k] // = { A*ray is a row vector whose every row i is the dot-product of // row i of A with the column vector "ray" } // A[k]*ray foreach (LinearConstraint/*!*/ cc in cce.NonNull(Constraints)) { Contract.Assert(cc != null); Rational d = cc.EvaluateLhs(ray); cc.SetCoefficient(lambda, -d); } // We also add the constraints that lambda is at least 0. LinearConstraint la = new LinearConstraint(LinearConstraint.ConstraintRelation.LE); la.SetCoefficient(lambda, Rational.MINUS_ONE); la.rhs = Rational.ZERO; Constraints.Add(la); #if DEBUG_PRINT Console.WriteLine(" Constraints after addition:"); foreach (LinearConstraint cc in Constraints) { Console.WriteLine(" {0}", cc); } #endif // Finally, project out the dummy dimension. Constraints = Project(lambda, Constraints); #if DEBUG_PRINT Console.WriteLine(" Resulting constraints:"); foreach (LinearConstraint cc in Constraints) { Console.WriteLine(" {0}", cc); } #endif }
public LinearConstraint Clone() { LinearConstraint z = new LinearConstraint(Relation); z.coefficients = (Hashtable /*IVariable->Rational*/)this.coefficients.Clone(); z.rhs = this.rhs; return z; }
/// <summary> /// Adds a vertex to the frame of "this" and updates Constraints accordingly, see /// Cousot and Halbwachs, section 3.3.1.1. However, this method does not simplify /// Constraints after the operation; that remains the caller's responsibility (which /// gives the caller the opportunity to make multiple calls to AddVertex, AddRay, /// and AddLine before calling SimplifyConstraints). /// Assumes Constraints (and the frame fields) to be non-null. /// </summary> /// <param name="vertex"></param> void AddVertex(FrameElement/*!*/ vertex) { Contract.Requires(vertex != null); Contract.Requires(this.FrameVertices != null); #if DEBUG_PRINT Console.WriteLine("DEBUG: AddVertex called on {0}", vertex); Console.WriteLine(" Initial constraints:"); foreach (LinearConstraint cc in Constraints) { Console.WriteLine(" {0}", cc); } #endif FrameVertices.Add(vertex.Clone()); #if FIXED_DESERIALIZER Contract.Assert(Contract.ForAll(vertex.GetDefinedDimensions() , var=> FrameDimensions.Contains(var))); #endif // We use a new temporary dimension. IVariable/*!*/ lambda = new LambdaDimension(); // We change the constraints A*X <= B into // A*X + (A*vector - B)*lambda <= A*vector. // That means that each row k in A (which corresponds to one LinearConstraint // in Constraints) is changed by adding // (A*vector - B)[k] * lambda // to row k and changing the right-hand side of row k to // (A*vector)[k] // Note: // (A*vector - B)[k] // = { vector subtraction is pointwise } // (A*vector)[k] - B[k] // = { A*vector is a row vector whose every row i is the dot-product of // row i of A with the column vector "vector" } // A[k]*vector - B[k] foreach (LinearConstraint/*!*/ cc in cce.NonNull(Constraints)) { Contract.Assert(cc != null); Rational d = cc.EvaluateLhs(vertex); cc.SetCoefficient(lambda, d - cc.rhs); cc.rhs = d; } // We also add the constraints that lambda lies between 0 ... LinearConstraint la = new LinearConstraint(LinearConstraint.ConstraintRelation.LE); la.SetCoefficient(lambda, Rational.MINUS_ONE); la.rhs = Rational.ZERO; Constraints.Add(la); // ... and 1. la = new LinearConstraint(LinearConstraint.ConstraintRelation.LE); la.SetCoefficient(lambda, Rational.ONE); la.rhs = Rational.ONE; Constraints.Add(la); #if DEBUG_PRINT Console.WriteLine(" Constraints after addition:"); foreach (LinearConstraint cc in Constraints) { Console.WriteLine(" {0}", cc); } #endif // Finally, project out the dummy dimension. Constraints = Project(lambda, Constraints); #if DEBUG_PRINT Console.WriteLine(" Resulting constraints:"); foreach (LinearConstraint cc in Constraints) { Console.WriteLine(" {0}", cc); } #endif }
/// <summary> /// Returns a constraint like "this", but, conceptually, with the inequality relation >=. /// </summary> /// <returns></returns> public LinearConstraint/*!*/ ChangeRelationToAtLeast() { Contract.Ensures(Contract.Result<LinearConstraint>() != null); LinearConstraint z = new LinearConstraint(ConstraintRelation.LE); foreach (DictionaryEntry /*IVariable->Rational*/ entry in this.coefficients) { z.coefficients.Add(entry.Key, -(Rational)(cce.NonNull(entry.Value))); } z.rhs = -this.rhs; return z; }
/// <summary> /// Tests the example in section 3.4.3 of Cousot and Halbwachs. /// </summary> public static void RunValidationB() { IVariable/*!*/ X = new TestVariable("X"); IVariable/*!*/ Y = new TestVariable("Y"); IVariable/*!*/ Z = new TestVariable("Z"); Contract.Assert(X != null); Contract.Assert(Y != null); Contract.Assert(Z != null); ArrayList /*LinearConstraint*/ cs = new ArrayList /*LinearConstraint*/ (); LinearConstraint c = new LinearConstraint(LinearConstraint.ConstraintRelation.LE); c.SetCoefficient(X, Rational.MINUS_ONE); c.SetCoefficient(Y, Rational.ONE); c.SetCoefficient(Z, Rational.MINUS_ONE); c.rhs = Rational.ZERO; cs.Add(c); c = new LinearConstraint(LinearConstraint.ConstraintRelation.LE); c.SetCoefficient(X, Rational.MINUS_ONE); c.rhs = Rational.MINUS_ONE; cs.Add(c); c = new LinearConstraint(LinearConstraint.ConstraintRelation.LE); c.SetCoefficient(X, Rational.MINUS_ONE); c.SetCoefficient(Y, Rational.MINUS_ONE); c.SetCoefficient(Z, Rational.ONE); c.rhs = Rational.ZERO; cs.Add(c); c = new LinearConstraint(LinearConstraint.ConstraintRelation.LE); c.SetCoefficient(Y, Rational.MINUS_ONE); c.SetCoefficient(Z, Rational.ONE); c.rhs = Rational.FromInt(3); cs.Add(c); LinearConstraintSystem lcs = new LinearConstraintSystem(cs); Console.WriteLine("==================== The final linear constraint system ===================="); lcs.Dump(); }
public override Answer CheckVariableDisequality(Element/*!*/ e, IVariable/*!*/ var1, IVariable/*!*/ var2) { //Contract.Requires(var2 != null); //Contract.Requires(var1 != null); //Contract.Requires(e != null); PolyhedraLatticeElement/*!*/ ple = (PolyhedraLatticeElement)cce.NonNull(e); Contract.Assume(ple.lcs.Constraints != null); ArrayList /*LinearConstraint!*//*!*/ clist = (ArrayList /*LinearConstraint!*/)cce.NonNull(ple.lcs.Constraints.Clone()); LinearConstraint/*!*/ lc = new LinearConstraint(LinearConstraint.ConstraintRelation.EQ); Contract.Assert(lc != null); lc.SetCoefficient(var1, Rational.ONE); lc.SetCoefficient(var2, Rational.MINUS_ONE); clist.Add(lc); LinearConstraintSystem newLcs = new LinearConstraintSystem(clist); if (newLcs.IsBottom()) { return Answer.Yes; } else { return Answer.Maybe; } }