public void AddConstraint(Constraint c) { if (ExprUtil.IsFalse(c.Condition)) { throw new Exception("Cannot add false to constraint set"); } Debug.Assert(c.Condition.ShallowType.IsBool, "constraint must be boolean"); InternalConstraints.Add(c); UpdateHashCode(c); }
private bool AreConcrete(IList <Expr> indices) { foreach (var index in indices) { var asLiteral = ExprUtil.AsLiteral(index); if (asLiteral == null) { return(false); } } return(true); }
public override Expr VisitNAryExpr(NAryExpr node) { // Try to do direct map indexing // FIXME: If there are nested mapselects but they don't end on a variable // then we'll do a lot of unnecessary work every time we traverse into a map select down. var asMapSelect = ExprUtil.AsMapSelect(node); if (asMapSelect != null) { // Gather the indices. They will be backwards as we traversing top down so have to // reverse at the end. // // Here's an example showing this: // // var m:[int][int]bool; // y:= m[0][1] // // The indicies we want are [0][1], but when traverse we will visit them backwards as // we start at the root of the expression tree. // // The structure of this is // // mapselect // / \ // mapselect 1 // / \ // m 0 var indices = new List <Expr>(); Expr firstArg = null; do { // Traverse multi-arity arguments in reverse because later on we reverse them. for (int index = asMapSelect.Args.Count - 1; index >= 1; --index) { // Don't do index variable mapping here because we might // need to throw away what we've done indices.Add(asMapSelect.Args[index]); } firstArg = asMapSelect.Args[0]; asMapSelect = ExprUtil.AsMapSelect(firstArg); } while (asMapSelect != null); // Hopefully a map variable we can write to var asId = ExprUtil.AsIdentifer(firstArg); if (asId != null && asId.Decl.TypedIdent.Type.IsMap) { // Do a remapping if necessary // FIXME: This sucks. Fix boogie instead! Variable V = null; if (preReplacementReMap.ContainsKey(asId.Decl)) { V = preReplacementReMap[asId.Decl]; } else { V = asId.Decl; } // We need to make sure that the map variable isn't bound and that // Note: that map is being fully indexed into and not partially if ((!BoundVariables.Contains(V)) && indices.Count == MapProxy.ComputeIndicesRequireToDirectlyIndex(asId.Decl.TypedIdent.Type)) { // Put indices in correct order indices.Reverse(); // Expand the indices so variables are mapped var expandedIndices = new List <Expr>(); foreach (var index in indices) { expandedIndices.Add((Expr)this.Visit(index)); } var valueFromMap = State.ReadMapVariableInScopeAt(V, expandedIndices); return(valueFromMap); } } } // Handle all other NAryExpr and fall back when we encounter a mapselect we can't support // (e.g. the map variable being used is not known). return(base.VisitNAryExpr(node)); }
// Only returns true if the indices definitely only alias up to one indice stored // in StoresAtSymbolicNonAliasingIndices. i.e. // // returns true iff // // the indices do not alias anything in StoresAtSymbolicNonAliasingIndices // OR // the indices alias a single element in StoresAtSymbolicNonAliasingIndices // which ok because this tells us which element to overwrite. // // Note that if this method returns false it means that the indices "might" alias. private bool AliasesZeroOrOneSymbolicNonAliasingIndices(IList <Expr> indices) { if (indices.Count > 1) { // Our alias analysis is very primitive and we only allow a single index return(false); } var indexExpr = indices[0]; // Analysis: We consider the follow expressions to not alias // <sym_var> // <constant> + <sym_var> // // Note sym_var must be the same // Try single variable var asId = ExprUtil.AsIdentifer(indexExpr); if (asId != null) { if (SymVariable == null) { // We haven't picked a variable for use in our non aliasing symbolci expressions yet // use this one Debug.Assert(StoresAtSymbolicNonAliasingIndices.Count == 0); SymVariable = asId.Decl; return(true); } else { // We have an existing symbolic variable that we are using if (SymVariable.Equals(asId.Decl)) { return(true); } return(false); } } // We are relying on the expression simplification of the expression builder to always // but the constant on the left child // <constant> + <sym_var> var asAdd = ExprUtil.AsAdd(indexExpr); if (asAdd != null) { var lhsAsLit = ExprUtil.AsLiteral(asAdd.Args[0]); if (lhsAsLit != null) { var rhsAsId = ExprUtil.AsIdentifer(asAdd.Args[1]); if (rhsAsId != null) { if (SymVariable == null) { // We haven't picked a variable for use in our non aliasing symbolci expressions yet // use this one Debug.Assert(StoresAtSymbolicNonAliasingIndices.Count == 0); SymVariable = rhsAsId.Decl; return(true); } else { // We have an existing symbolic variable that we are using if (SymVariable.Equals(rhsAsId.Decl)) { return(true); } return(false); } } } } // The indicies might alias something we already have stored. return(false); }