// -------------------------------------------------------------------------------------------------------- // ------------------ 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; }
public LinearConstraintSystem(ArrayList /*LinearConstraint!*//*!*/ cs) { Contract.Requires(cs != null); #if BUG_159_HAS_BEEN_FIXED Contract.Requires(Contract.ForAll(cs) , cc=> cc.coefficients.Count != 0); #endif ArrayList constraints = new ArrayList /*LinearConstraint!*/ (cs.Count); foreach (LinearConstraint/*!*/ cc in cs) { Contract.Assert(cc != null); constraints.Add(cc); } Constraints = constraints; FrameDimensions = new HashSet /*IVariable!*/ (); // to please compiler; this value will be overridden in the call to GenerateFrameConstraints below //:base(); GenerateFrameFromConstraints(); SimplifyConstraints(); CheckInvariant(); #if DEBUG_PRINT Console.WriteLine("LinearConstraintSystem: constructor produced:"); Dump(); #endif }
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(); }