public SetDomain <T> Join(SetDomain <T> newState, out bool weaker, bool widen) { if (set == newState.set) { weaker = false; return(this); } if (this.IsBottom) { weaker = !newState.IsBottom; return(newState); } if (newState.IsBottom || this.IsTop) { weaker = false; return(this); } if (newState.IsTop) { weaker = !this.IsTop; return(newState); } Contract.Assert(set != null); IFunctionalSet <T> result = set.Intersect(newState.set); weaker = result.Count < set.Count; return(new SetDomain <T>(result)); }
public bool LessEqual(SetDomain <T> that) { if (this.IsBottom) { return(true); } if (that.IsBottom) { return(false); } Contract.Assert(set != null); return(that.set.Contained(set)); }
/// <summary> /// Here we actually add constraints to our state. /// </summary> private Domain ConstrainLessThan(Expression var, Expression bound, Domain domain) { // First, skip unary coercions on var and bound SkipConversionDecoder skipper = new SkipConversionDecoder(); var = this.context.Decode <Unit, Expression, SkipConversionDecoder>(var, skipper, Unit.Value); bound = this.context.Decode <Unit, Expression, SkipConversionDecoder>(bound, skipper, Unit.Value); Variable left = this.context.Unrefine(var); Variable right = this.context.Unrefine(bound); // add the bound to the set of bounds known SetDomain <Variable> currentBounds = (domain.Value.Contains(left)) ? domain.Value[left] : SetDomain <Variable> .TopValue; return(new Domain(domain.Value.Add(left, currentBounds.Add(right)))); }
/// <summary> /// Here's where the actual work is. We get passed a list of pairs (source,targets) representing /// the assignments t = source for each t in targets. /// /// For our domain, we thus add new mappings for all targets by looking up the bounds of the source and map the source bounds to new target bounds. /// </summary> public Domain ParallelAssign(Pair <Label, Label> edge, IFunctionalMap <Variable, FList <Variable> > sourceTargetMap, Domain state) { EnvironmentDomain <Variable, SetDomain <Variable> > originalState = state.Value; EnvironmentDomain <Variable, SetDomain <Variable> > newState = originalState; foreach (Variable source in sourceTargetMap.Keys) { FList <Variable> targets = sourceTargetMap[source]; // 1) for each target in this assignment, assign it the same bounds as source. // 2) since we also have to map the source bounds, we assign it actually the union of all targets of all bounds of the source. SetDomain <Variable> targetBounds = SetDomain <Variable> .TopValue; if (originalState.Contains(source)) { SetDomain <Variable> originalBounds = originalState[source]; foreach (Variable origBound in originalBounds.Elements) { FList <Variable> targetBoundNames = sourceTargetMap[origBound]; while (targetBoundNames != null) { targetBounds = targetBounds.Add(targetBoundNames.Head); targetBoundNames = targetBoundNames.Tail; } } } if (targetBounds.IsTop) { // have no bounds, so havoc all targets while (targets != null) { newState = newState.Remove(targets.Head); targets = targets.Tail; } } else { while (targets != null) { newState = newState.Add(targets.Head, targetBounds); targets = targets.Tail; } } } return(new Domain(newState)); }
public SetDomain <T> Meet(SetDomain <T> that) { if (set == that.set) { return(this); } if (this.IsBottom || that.IsTop) { return(this); } if (that.IsBottom || this.IsTop) { return(that); } Contract.Assert(set != null); IFunctionalSet <T> result = set.Union(that.set); return(new SetDomain <T>(result)); }
/// <summary> /// Here's one place where we want to check the bound. In principle, we want to only record the position and relevant /// parameters for a proof obligation and check it only after the fixpoint is computed. /// I'm lazy and checking it right away. /// </summary> public override Domain Ldelem(Label pc, Type type, Variable dest, Variable array, Variable index, Domain data) { if (data.Value.Contains(index)) { SetDomain <Variable> bounds = data.Value[index]; // lookup upper bound of index and array bound Variable bound; if (this.context.TryGetArrayLength(pc, array, out bound)) { if (Debug) { Console.WriteLine("bound for array {0} is {1}", array.ToString(), bound.ToString()); } // check that bound is in bounds of index if (!bounds.Contains(bound)) { Console.WriteLine("{0}: WARNING: Can't prove that array index is okay", this.context.SourceContext(pc)); } else { Console.WriteLine("{0}: INFO: Array index looks good.", this.context.SourceContext(pc)); } } else { Console.WriteLine("{0}: WARNING: Can't prove that array index is okay", this.context.SourceContext(pc)); } } else { Console.WriteLine("{0}: WARNING: Can't prove that array index is okay", this.context.SourceContext(pc)); } // TODO: might want to constrain index by bound of array to eliminate subsequent errors return(data); }