public AbstractValue this[ISymValue sym] { get { sym = Find(sym); AbstractValue v = (AbstractValue)this.absMap[sym]; if (v == null) { v = this.elementLattice.Top; } return(v); } set { SymbolicValue sv = Find(sym); AbstractValue old = this[sym]; if (old != value) { AddAValUpdate(sv); if (this.elementLattice.IsTop(value)) { this.absMap = this.absMap.Remove(sv); } else { this.absMap = this.absMap.Add(sv, value); } } } }
public override Element /*!*/ NontrivialJoin(Element /*!*/ first, Element /*!*/ second) { //Contract.Requires(second != null); //Contract.Requires(first != null); Contract.Ensures(Contract.Result <Element>() != null); Elt a = (Elt)first; Elt b = (Elt)second; IFunctionalMap newMap = FunctionalHashtable.Empty; foreach (IVariable /*!*/ key in a.Variables) { Contract.Assert(key != null); Element aValue = a[key]; Element bValue = b[key]; if (aValue != null && bValue != null) { // Keep only the variables known to both elements. Element newValue = this.microLattice.Join(aValue, bValue); newMap = newMap.Add(key, newValue); } } Elt /*!*/ join = new Elt(newMap); Contract.Assert(join != null); // System.Console.WriteLine("{0} join {1} = {2} ", this.ToString(a), ToString(b), ToString(join)); return(join); }
private Elt(bool top) { if (top) { this.constraints = FunctionalHashtable.Empty; } else { this.constraints = null; } }
public Preconditions Rename(APC from, APC to, Preconditions pre, IFunctionalMap <Variable, Variable> renaming) { BreakHere(to, pre, "rename"); Func <Variable, BoxedExpression> converter = ((Variable v) => BoxedExpression.Convert(this.Mdriver.Context.ExpressionContext.Refine(to, v), this.Mdriver.ExpressionDecoder)); var result = new List <BoxedExpression>(); foreach (var p in pre) { var newCondition = p.Rename(renaming, converter); if (newCondition != null) { var truth = facts.IsTrue(to, newCondition); switch (truth) { case ProofOutcome.Top: result.Add(newCondition); break; case ProofOutcome.True: continue; case ProofOutcome.Bottom: case ProofOutcome.False: return(null); } } } return(result.Count == 0 ? null : result); }
public EnvironmentDomain <Key, Val> Meet(EnvironmentDomain <Key, Val> that) { if (map == that.map) { return(this); } if (this.IsTop) { return(that); } if (that.IsTop) { return(this); } if (this.IsBottom) { return(this); } if (that.IsBottom) { return(that); } Contract.Assume(map != null); // compare pointwise IFunctionalMap <Key, Val> smaller; IFunctionalMap <Key, Val> larger; if (map.Count < that.map.Count) { smaller = map; larger = that.map; } else { smaller = that.map; larger = map; } IFunctionalMap <Key, Val> result = larger; foreach (Key k in smaller.Keys) { if (larger.Contains(k)) { // must meet the values Val meet = smaller[k].Meet(larger[k]); result = result.Add(k, meet); } else { // just add the value to the result result = result.Add(k, smaller[k]); } } return(new EnvironmentDomain <Key, Val>(result)); }
public Domain Rename(IFunctionalMap <SymbolicValue, SymbolicValue> substitution) { foreach (SymbolicValue v in NonNullValues.Elements) { if (substitution.Contains(v)) { NonNullValues = NonNullValues.Remove(v).Add(substitution[v]); } } return(this); }
public EGraph(MathematicalLattice elementLattice) { this.elementLattice = elementLattice; this.constRoot = FreshSymbolicValue(); this.termMap = DoubleFunctionalMap.Empty; this.absMap = FunctionalMap.Empty; this.forwMap = FunctionalMap.Empty; this.eqTermMap = DoubleFunctionalMap.Empty; this.constant = false; this.parent = null; this.root = this; this.historySize = 1; this.updates = null; }
public Dictionary <BoxedVariable <Variable>, FList <BoxedVariable <Variable> > > GetRefinedMap( APC from, APC to, IFunctionalMap <Variable, FList <Variable> > sourceTargetMap, Renamings <Variable> renamings, int maxVarsInOneRenaming = Int32.MaxValue) { Contract.Requires(sourceTargetMap != null); Dictionary <BoxedVariable <Variable>, FList <BoxedVariable <Variable> > > result; if (!this.RefinedMappingCache.TryGetValue(from, to, out result)) { result = sourceTargetMap.RefineMapToBoxedVariables(renamings, maxVarsInOneRenaming); this.RefinedMappingCache.Add(from, to, result); } return(result); }
/// <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)); }
private void DrainEqualityWorkList(WorkList wl) { while (!wl.IsEmpty()) { EqPair eqpair = (EqPair)wl.Pull(); SymbolicValue v1rep = Find(eqpair.v1); SymbolicValue v2rep = Find(eqpair.v2); if (v1rep == v2rep) { continue; } // always map new to older var if (v1rep.UniqueId < v2rep.UniqueId) { SymbolicValue temp = v1rep; v1rep = v2rep; v2rep = temp; } // perform congruence closure here: foreach (IUniqueKey f in this.Functions(v1rep)) { SymbolicValue target = this.LookupWithoutManifesting(v2rep, f); if (target == null) { this[v2rep, f] = this[v1rep, f]; } else { PushEquality(wl, this[v1rep, f], target); } } MathematicalLattice.Element av1 = this[v1rep]; MathematicalLattice.Element av2 = this[v2rep]; // merge term map of v1 into v2 foreach (IUniqueKey eterm in this.eqTermMap.Keys2(v1rep)) { this.eqTermMap = this.eqTermMap.Add(v2rep, eterm, null); } this.forwMap = this.forwMap.Add(v1rep, v2rep); this[v2rep] = this.elementLattice.Meet(av1, av2); } }
public Elt /*!*/ Rename(IVariable /*!*/ oldName, IVariable /*!*/ newName, MicroLattice /*!*/ microLattice) { Contract.Requires(microLattice != null); Contract.Requires(newName != null); Contract.Requires(oldName != null); Contract.Requires((!this.IsBottom)); Contract.Ensures(Contract.Result <Elt>() != null); Element value = this[oldName]; if (value == null) { return(this); } // 'oldName' isn't in the map, so neither will be 'newName' Contract.Assume(this.constraints != null); IFunctionalMap newMap = this.constraints.Remove(oldName); newMap = newMap.Add(newName, value); return(new Elt(newMap)); }
/// <summary> /// Copy constructor /// </summary> /// <param name="from"></param> private EGraph(EGraph from, CfgBlock at) { this.constRoot = from.constRoot; this.termMap = from.termMap; this.idCounter = from.idCounter; this.absMap = from.absMap; this.elementLattice = from.elementLattice; this.forwMap = from.forwMap; this.eqTermMap = from.eqTermMap; // keep history this.updates = from.updates; this.parent = from; this.root = from.root; this.historySize = from.historySize + 1; this.Block = at; // set from to constant from.constant = true; }
/// <summary> /// Perform the pointwise widening of the elements in the map /// </summary> public override Element /*!*/ Widen(Element /*!*/ first, Element /*!*/ second) { //Contract.Requires((second != null)); //Contract.Requires((first != null)); Contract.Ensures(Contract.Result <Element>() != null); Elt a = (Elt)first; Elt b = (Elt)second; // Note we have to add those cases as we do not have a "NonTrivialWiden" method if (a.IsBottom) { return(new Elt(b.Constraints)); } if (b.IsBottom) { return(new Elt(a.Constraints)); } IFunctionalMap newMap = FunctionalHashtable.Empty; foreach (IVariable /*!*/ key in a.Variables) { Contract.Assert(key != null); Element aValue = a[key]; Element bValue = b[key]; if (aValue != null && bValue != null) { // Keep only the variables known to both elements. Element newValue = this.microLattice.Widen(aValue, bValue); newMap = newMap.Add(key, newValue); } } Element /*!*/ widen = new Elt(newMap); Contract.Assert(widen != null); // System.Console.WriteLine("{0} widen {1} = {2} ", this.ToString(a), ToString(b), ToString(widen)); return(widen); }
protected BoxedExpression ReadInPostState(BoxedExpression candidate, IFunctionalMap <Variable, Variable> renaming) { Contract.Requires(candidate != null); Contract.Ensures(Contract.Result <BoxedExpression>() != null); if (candidate.IsVariable) { Variable v; if (candidate.TryGetFrameworkVariable(out v)) { // F: bad bad way of doing reverse lookup. This should be changed (by now it is balanced by the fact that we cache the reconstructed expressions) foreach (var key in renaming.Keys) { var val = renaming[key]; if (v.Equals(val)) { return(BoxedExpression.Var(key)); } } } return(candidate); } if (candidate.IsUnary) { return(BoxedExpression.Unary(candidate.UnaryOp, ReadInPostState(candidate.UnaryArgument, renaming))); } BinaryOperator bop; BoxedExpression left, right; if (candidate.IsBinaryExpression(out bop, out left, out right)) { return(BoxedExpression.Binary(bop, ReadInPostState(left, renaming), ReadInPostState(right, renaming))); } return(candidate); }
/// <summary> /// Set the value of the variable in the functional map /// If the variable is not already there, throws an exception /// </summary> public Elt /*!*/ Set(IVariable /*!*/ var, Element /*!*/ value, MicroLattice /*!*/ microLattice) { Contract.Requires(microLattice != null); Contract.Requires(value != null); Contract.Requires(var != null); Contract.Ensures(Contract.Result <Elt>() != null); if (microLattice.IsBottom(value)) { return(Bottom); } if (microLattice.IsTop(value)) { return(this.Remove(var, microLattice)); } Contract.Assume(this.constraints != null); Contract.Assert(this.constraints.Contains(var)); // this.constraints[var] = value; IFunctionalMap newMap = this.constraints.Set(var, value); return(new Elt(newMap)); }
public override Element /*!*/ NontrivialMeet(Element /*!*/ first, Element /*!*/ second) { //Contract.Requires(second != null); //Contract.Requires(first != null); Contract.Ensures(Contract.Result <Element>() != null); Elt a = (Elt)first; Elt b = (Elt)second; IFunctionalMap newMap = FunctionalHashtable.Empty; foreach (IVariable /*!*/ key in a.Variables) { Contract.Assert(key != null); Element /*!*/ aValue = cce.NonNull(a[key]); Element bValue = b[key]; Element newValue = bValue == null ? aValue : this.microLattice.Meet(aValue, bValue); newMap = newMap.Add(key, newValue); } foreach (IVariable /*!*/ key in b.Variables) { Contract.Assert(key != null); Element aValue = a[key]; Element bValue = b[key]; Debug.Assert(bValue != null); if (aValue == null) { // It's a variable we didn't cover in the last loop. newMap = newMap.Add(key, bValue); } } return(new Elt(newMap)); }
MyDomain GetReturnState <MyDomain>(IFixpointInfo <APC, MyDomain> fixpoint, IAbstractAnalysis <Local, Parameter, Method, Field, Property, Type, Expression, Attribute, Assembly, MyDomain, Variable> analysis, int state, out bool isBottom, MyDomain defaultValue) { MyDomain returnState = defaultValue; var fakeEdge = new Pair <APC, APC>(driver.CFG.NormalExit, driver.CFG.Entry); if (stateInfo.StateReturnPoints == null || !stateInfo.StateReturnPoints.ContainsKey(state)) { isBottom = true; } else { bool first = true; isBottom = true; foreach (APC returnPoint in stateInfo.StateReturnPoints[state]) { MyDomain tmp; if (fixpoint.PostState(returnPoint, out tmp) && !analysis.IsBottom(returnPoint, tmp)) { isBottom = false; var edge = new Pair <APC, APC>(returnPoint, driver.CFG.Entry.Post()); IFunctionalMap <Variable, FList <Variable> > mapping = GetFieldMapping(driver, returnPoint, driver.CFG.Entry.Post()); MyDomain newState = analysis.EdgeConversion(fakeEdge.One, fakeEdge.Two, true, mapping, tmp); bool ignore; if (first) { returnState = newState; first = false; } else { returnState = analysis.Join(edge, newState, returnState, out ignore, false); } } } } return(returnState); }
/// <summary> /// Evaluate the predicate passed as input according the semantics of intervals and the given state. /// Right now just basic arithmetic operations are supported. A future extension may consider an implementation of boolean predicates /// </summary> public override Element /*!*/ EvaluatePredicateWithState(IExpr /*!*/ pred, IFunctionalMap /* Var -> Element */ state) { //Contract.Requires(pred != null); Contract.Ensures(Contract.Result <Element>() != null); if (pred is IFunApp) { IFunApp fun = (IFunApp)pred; if (fun.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Eq)) // if it is a symbol of equality { IExpr /*!*/ leftArg = (IExpr /*!*/)cce.NonNull(fun.Arguments[0]); IExpr /*!*/ rightArg = (IExpr /*!*/)cce.NonNull(fun.Arguments[1]); if (leftArg is IVariable) { return(Eval(rightArg, state)); } else if (rightArg is IVariable) { return(Eval(leftArg, state)); } } } // otherwise we simply return Top return(IntervalElement.Top); }
public BoxedExpression Rename(APC from, APC to, BoxedExpression state, IFunctionalMap <Variable, Variable> renaming) { if (state != null) { Variable v; if (state.TryGetFrameworkVariable(out v)) { if (renaming.Contains(v)) { var newVar = renaming[v]; var result = BoxedExpression.Convert(this.mdriver.Context.ExpressionContext.Refine(to, newVar), this.mdriver.ExpressionDecoder); Log("Renaming {0} to {1}", state.ToString(), result != null? result.ToString(): "<null>"); // We use the heuristic of reading variables in the prestate, to get their name at the point we are interested in. // We may lose information because of it, and unable to decompile more complex expressions if (result != null && !result.IsVariable) { return(ReadInPostState(result, renaming)); } return(result); } } int k; if (state.IsConstantInt(out k)) { return(state); } } return(null); }
public Elt(IFunctionalMap constraints) { this.constraints = constraints; }
private void DrainEqualityWorkList(WorkList wl) { while ( ! wl.IsEmpty() ) { EqPair eqpair = (EqPair)wl.Pull(); SymbolicValue v1rep = Find(eqpair.v1); SymbolicValue v2rep = Find(eqpair.v2); if (v1rep == v2rep) continue; // always map new to older var if (v1rep.UniqueId < v2rep.UniqueId) { SymbolicValue temp = v1rep; v1rep = v2rep; v2rep = temp; } // perform congruence closure here: foreach(IUniqueKey f in this.Functions(v1rep)) { SymbolicValue target = this.LookupWithoutManifesting(v2rep, f); if (target == null) { this[v2rep, f] = this[v1rep,f]; } else { PushEquality(wl, this[v1rep,f], target); } } MathematicalLattice.Element av1 = this[v1rep]; MathematicalLattice.Element av2 = this[v2rep]; // merge term map of v1 into v2 foreach(IUniqueKey eterm in this.eqTermMap.Keys2(v1rep)) { this.eqTermMap = this.eqTermMap.Add(v2rep, eterm, null); } this.forwMap = this.forwMap.Add(v1rep, v2rep); this[v2rep] = this.elementLattice.Meet(av1,av2); } }
/// <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, if the source is in the non-null set, then we add all the targets to the non-null set. /// </summary> public Domain EdgeConversion(APC from, APC to, bool isJoin, IFunctionalMap <Variable, FList <Variable> > sourceTargetMap, Domain state) { return(state); }
/// <summary> /// Copy constructor /// </summary> /// <param name="from"></param> private EGraph(EGraph from, CfgBlock at) { this.constRoot = from.constRoot; this.termMap = from.termMap; this.idCounter = from.idCounter; this.absMap = from.absMap; this.elementLattice = from.elementLattice; this.forwMap = from.forwMap; this.eqTermMap = from.eqTermMap; // keep history this.updates = from.updates; this.parent = from; this.root = from.root; this.historySize = from.historySize+1; this.Block = at; // set from to constant from.constant = true; }
public AbstractValue this[ISymValue sym] { get { sym = Find(sym); AbstractValue v = (AbstractValue)this.absMap[sym]; if (v == null) { v = this.elementLattice.Top; } return v; } set { SymbolicValue sv = Find(sym); AbstractValue old = this[sym]; if (old != value) { AddAValUpdate(sv); if (this.elementLattice.IsTop(value)) { this.absMap = this.absMap.Remove(sv); } else { this.absMap = this.absMap.Add(sv, value); } } } }
public AbstractValue EdgeConversion(APC from, APC next, bool joinPoint, IFunctionalMap <Variable, FList <Variable> > edgeData, AbstractValue newState) { // Wrong, just for the moment return(newState); }
/// <summary> /// Evaluate the expression (that is assured to be an arithmetic expression, in the state passed as a parameter /// </summary> private IntervalElement/*!*/ Eval(IExpr/*!*/ exp, IFunctionalMap/* Var -> Element */ state) { Contract.Requires((exp != null)); Contract.Ensures(Contract.Result<IntervalElement>() != null); IntervalElement/*!*/ retVal = (IntervalElement/*!*/)cce.NonNull(Top); // Eval the expression by structural induction if (exp is IVariable && state != null) // A variable { object lookup = state[exp]; if (lookup is IntervalElement) retVal = (IntervalElement)lookup; else { retVal = (IntervalElement)Top; } } else if (exp is IFunApp) { IFunApp fun = (IFunApp)exp; if (fun.FunctionSymbol is IntSymbol) // An integer { IntSymbol intSymb = (IntSymbol)fun.FunctionSymbol; BigNum val = intSymb.Value; retVal = IntervalElement.Factory(val); } else if (fun.FunctionSymbol.Equals(Int.Negate)) // An unary minus { IExpr/*!*/ arg = (IExpr/*!*/)cce.NonNull(fun.Arguments[0]); IntervalElement/*!*/ argEval = Eval(arg, state); Contract.Assert(argEval != null); IntervalElement/*!*/ zero = IntervalElement.Factory(BigNum.ZERO); Contract.Assert(zero != null); retVal = zero - argEval; } else if (fun.Arguments.Count == 2) { IExpr/*!*/ left = (IExpr/*!*/)cce.NonNull(fun.Arguments[0]); IExpr/*!*/ right = (IExpr/*!*/)cce.NonNull(fun.Arguments[1]); IntervalElement/*!*/ leftVal = Eval(left, state); Contract.Assert(leftVal != null); IntervalElement/*!*/ rightVal = Eval(right, state); Contract.Assert(rightVal != null); if (fun.FunctionSymbol.Equals(Int.Add)) retVal = leftVal + rightVal; else if (fun.FunctionSymbol.Equals(Int.Sub)) retVal = leftVal - rightVal; else if (fun.FunctionSymbol.Equals(Int.Mul)) retVal = leftVal * rightVal; else if (fun.FunctionSymbol.Equals(Int.Div)) retVal = leftVal / rightVal; else if (fun.FunctionSymbol.Equals(Int.Mod)) retVal = leftVal % rightVal; } } return retVal; }
abstract public AElement Rename(APC from, APC to, AElement pre, IFunctionalMap <Variable, Variable> renaming);
/// <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, if the source is in the non-null set, then we add all the targets to the non-null set. /// </summary> public Domain ParallelAssign(Pair <APC, APC> edge, IFunctionalMap <Variable, FList <Variable> > sourceTargetMap, Domain state) { return(state); }
public EnvironmentDomain(IFunctionalMap <Key, Val> /*?*/ value) { map = value; }
/// <summary> /// Evaluate the predicate e and yield an overapproximation of the predicate under the state that is passed as a parameter /// Note that unless the subclass implement it, the default behavior is to evaluate the predicate stateless, that implies that it /// is evaluated in any possible context, i.e. it is an upper approximation /// </summary> public virtual Element/*!*/ EvaluatePredicateWithState(IExpr/*!*/ e, IFunctionalMap state){ Contract.Requires(e != null); Contract.Ensures(Contract.Result<Element>() != null); return EvaluatePredicate(e); }
/// <summary> /// Given an underlying analysis and generator for a bottom value, this method computes a mapping between a state of /// the iterator and fixpoint information computed by the underlying analysis for the slice that corresponds to that /// state. /// /// The analysis runs the underlying analyzer on state 0, the initial state, first. The state from the return point /// of this state will be the current value of the invariant candidate. /// Then for every continuing state (the state from which a new item is generated for the ienumerable result), we map /// the current invariant candidate and map it to the entry of the method, and run the underlying analysis for that /// state. Running the underlying analysis for a particular state requires a set of program points, which are the entry /// points of other slices. The underlying analysis will mark those program points as unreachable. The exit abstract /// state will become the current invariant candidate. This process finishes when a fixedpoint is reached. /// </summary> /// <typeparam name="MyDomain">The domain of the underlying analysis.</typeparam> /// <param name="analysis">The underlying analysis.</param> /// <param name="bv">A delegate that generates a bottom value for MyDomain.</param> /// <returns></returns> public FunctionalMap <int, IMethodAnalysisFixPoint <Variable> > Analyze <MyDomain>( IMoveNextOnePassAnalysis <Local, Parameter, Method, Field, Property, Type, Expression, Attribute, Assembly, MyDomain, Variable> analysis, StateGenerator <MyDomain> bv) { // Use a pre-analysis to collect information regarding the state machine. MoveNextStateAnalyzer preAnalyzer = new MoveNextStateAnalyzer(); StateMachineInformation <Local> stateInfo = preAnalyzer.AnalyzeMoveNext("MoveNext", driver); // If we are not able if (stateInfo.OrderedVisibleStates == null || stateInfo.OrderedVisibleStates.Count() == 0) { throw new ArgumentException("Argument error with MoveNext method: Cannot analyze the state machine."); } // Fix point computation: fixpoint of the iterator analysis is a mapping: answers. bool fixedpointReached = false; MyDomain d = default(MyDomain), oldd = default(MyDomain); FunctionalMap <int, IMethodAnalysisFixPoint <Variable> > answers = FunctionalMap <int, IMethodAnalysisFixPoint <Variable> > .Empty; MyDomain invariantCandidate = default(MyDomain); Converter <Variable, int> key = driver.KeyNumber; int pass = 0; while (!fixedpointReached) { fixedpointReached = true; // Going through every state of the state machine, if the final states changes at least once // then fixpoint is not reached. foreach (int state in stateInfo.OrderedVisibleStates) { // The initial state is only analyzed once. if (state < 0) { continue; } if (state == 0 && pass > 0) { continue; } // Initial value for one pass, either TOP, if we analyze it for the first time // or the invariantCandidate. if (invariantCandidate == null || invariantCandidate.Equals(default(MyDomain))) { d = analysis.GetInitialValue(key); } else { d = analysis.MutableVersion(invariantCandidate); } // Call the underlying analysis for one pass Set <APC> cutOffPCs = GetStateEntriesOtherThan(stateInfo, state); driver.CreateForwardForIterator(analysis, bv, cutOffPCs)(d); // Getting the state from the return point of the most recent pass, map it // to the entry point, and join it with the current invariant candidate IFunctionalMap <Variable, FList <Variable> > mapping = GetFieldMapping(driver); var fakeEdge = new Pair <APC, APC>(driver.CFG.NormalExit, driver.CFG.Entry); MyDomain returnState = analysis.ReturnState; MyDomain newState = analysis.ParallelAssign(fakeEdge, mapping, returnState); bool changed = false; if (invariantCandidate != null && !invariantCandidate.Equals(default(MyDomain))) { oldd = invariantCandidate; // TODO: use a more sophisticated widenning strategy. bool toWiden = (pass > 2) ? true : false; d = analysis.Join(fakeEdge, newState, oldd, out changed, toWiden); if (changed) { invariantCandidate = d; } } else { changed = true; invariantCandidate = newState; } if (changed) { fixedpointReached = false; } // Fill the result table with the most recent fixpoint information. answers = (FunctionalMap <int, IMethodAnalysisFixPoint <Variable> >)answers.Add(state, analysis.ExtractResult()); analysis = analysis.Duplicate(); } pass++; } return(answers); }
public EnvironmentDomain <Key, Val> Join(EnvironmentDomain <Key, Val> newState, out bool weaker, bool widen) { if (map == newState.map) { weaker = false; return(this); } bool resultWeaker = false; if (this.IsTop) { weaker = false; return(this); } if (newState.IsTop) { weaker = !this.IsTop; return(newState); } if (this.IsBottom) { weaker = !newState.IsBottom; return(newState); } if (newState.IsBottom) { weaker = false; return(this); } // compare pointwise IFunctionalMap <Key, Val> smaller; IFunctionalMap <Key, Val> larger; if (map.Count < newState.map.Count) { smaller = map; larger = newState.map; } else { smaller = newState.map; larger = map; } IFunctionalMap <Key, Val> result = smaller; foreach (Key k in smaller.Keys) { if (!larger.Contains(k)) { result = result.Remove(k); } else { bool joinWeaker; Val join = smaller[k].Join(larger[k], out joinWeaker, widen); if (joinWeaker) { resultWeaker = true; if (join.IsTop) { result = result.Remove(k); } else { result = result.Add(k, join); } } } } weaker = resultWeaker || (result.Count < map.Count); return(new EnvironmentDomain <Key, Val>(result)); }
/// <summary> /// Evaluate the predicate passed as input according the semantics of intervals and the given state. /// Right now just basic arithmetic operations are supported. A future extension may consider an implementation of boolean predicates /// </summary> public override Element/*!*/ EvaluatePredicateWithState(IExpr/*!*/ pred, IFunctionalMap/* Var -> Element */ state) { //Contract.Requires(pred != null); Contract.Ensures(Contract.Result<Element>() != null); if (pred is IFunApp) { IFunApp fun = (IFunApp)pred; if (fun.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Eq)) // if it is a symbol of equality { IExpr/*!*/ leftArg = (IExpr/*!*/)cce.NonNull(fun.Arguments[0]); IExpr/*!*/ rightArg = (IExpr/*!*/)cce.NonNull(fun.Arguments[1]); if (leftArg is IVariable) { return Eval(rightArg, state); } else if (rightArg is IVariable) { return Eval(leftArg, state); } } } // otherwise we simply return Top return IntervalElement.Top; }
/// <summary> /// Evaluate the expression (that is assured to be an arithmetic expression, in the state passed as a parameter /// </summary> private IntervalElement /*!*/ Eval(IExpr /*!*/ exp, IFunctionalMap /* Var -> Element */ state) { Contract.Requires((exp != null)); Contract.Ensures(Contract.Result <IntervalElement>() != null); IntervalElement /*!*/ retVal = (IntervalElement /*!*/)cce.NonNull(Top); // Eval the expression by structural induction if (exp is IVariable && state != null) // A variable { object lookup = state[exp]; if (lookup is IntervalElement) { retVal = (IntervalElement)lookup; } else { retVal = (IntervalElement)Top; } } else if (exp is IFunApp) { IFunApp fun = (IFunApp)exp; if (fun.FunctionSymbol is IntSymbol) // An integer { IntSymbol intSymb = (IntSymbol)fun.FunctionSymbol; BigNum val = intSymb.Value; retVal = IntervalElement.Factory(val); } else if (fun.FunctionSymbol.Equals(Int.Negate)) // An unary minus { IExpr /*!*/ arg = (IExpr /*!*/)cce.NonNull(fun.Arguments[0]); IntervalElement /*!*/ argEval = Eval(arg, state); Contract.Assert(argEval != null); IntervalElement /*!*/ zero = IntervalElement.Factory(BigNum.ZERO); Contract.Assert(zero != null); retVal = zero - argEval; } else if (fun.Arguments.Count == 2) { IExpr /*!*/ left = (IExpr /*!*/)cce.NonNull(fun.Arguments[0]); IExpr /*!*/ right = (IExpr /*!*/)cce.NonNull(fun.Arguments[1]); IntervalElement /*!*/ leftVal = Eval(left, state); Contract.Assert(leftVal != null); IntervalElement /*!*/ rightVal = Eval(right, state); Contract.Assert(rightVal != null); if (fun.FunctionSymbol.Equals(Int.Add)) { retVal = leftVal + rightVal; } else if (fun.FunctionSymbol.Equals(Int.Sub)) { retVal = leftVal - rightVal; } else if (fun.FunctionSymbol.Equals(Int.Mul)) { retVal = leftVal * rightVal; } else if (fun.FunctionSymbol.Equals(Int.Div)) { retVal = leftVal / rightVal; } else if (fun.FunctionSymbol.Equals(Int.Mod)) { retVal = leftVal % rightVal; } } } return(retVal); }
public Data <Variable> EdgeConversion(APC from, APC next, bool joinPoint, IFunctionalMap <Variable, FList <Variable> > edgeData, Data <Variable> newState) { // We do not want to convert the variables! return(newState); }
private DoubleFunctionalMap(IFunctionalMap map) { this.map = map; }
public EquationBody(EquationBlock parent, EquationBlock to, IFunctionalMap <string, string> renamings) { this.parent = parent; this.to = to; this.renamings = renamings; }