internal BinaryRelationship GetNormalizedRelationship(BoolConstraint boolConstraint, SymbolicValue leftOperand, SymbolicValue rightOperand) { var invertCount = 0; var leftOp = leftOperand; var logicalNotLeftOp = leftOp as LogicalNotSymbolicValue; while (logicalNotLeftOp != null) { leftOp = logicalNotLeftOp.Operand; logicalNotLeftOp = leftOp as LogicalNotSymbolicValue; invertCount++; } var rightOp = rightOperand; var logicalNotRightOp = rightOp as LogicalNotSymbolicValue; while (logicalNotRightOp != null) { rightOp = logicalNotRightOp.Operand; logicalNotRightOp = rightOp as LogicalNotSymbolicValue; invertCount++; } var relationship = GetRelationship(boolConstraint, leftOp, rightOp); return invertCount % 2 == 0 ? relationship : relationship.Negate(); }
internal BinaryRelationship GetRelationship(BoolConstraint boolConstraint, SymbolicValue left, SymbolicValue right) { var equalsRelationship = GetRelationship(left, right); return boolConstraint == BoolConstraint.True ? equalsRelationship : equalsRelationship.Negate(); }
public void ProgramState_Equivalence() { var ps1 = new ProgramState(); var ps2 = new ProgramState(); var sv = new SymbolicValue(); var constraint = new FakeConstraint(); var symbol = GetSymbol(); ps1 = ps1.SetSymbolicValue(symbol, sv); ps1 = sv.SetConstraint(constraint, ps1); ps2 = ps2.SetSymbolicValue(symbol, sv); ps2 = sv.SetConstraint(constraint, ps2); Assert.AreEqual(ps1, ps2); Assert.AreEqual(ps1.GetHashCode(), ps2.GetHashCode()); }
protected EqualsRelationship(SymbolicValue leftOperand, SymbolicValue rightOperand) : base(leftOperand, rightOperand) { }
public ReferenceNotEqualsRelationship(SymbolicValue leftOperand, SymbolicValue rightOperand) : base(leftOperand, rightOperand) { }
public EqualityUpdate(SymbolicValue sv1, SymbolicValue sv2) { this.sv1 = sv1; this.sv2 = sv2; }
public void AddMapping(SymbolicValue v1, SymbolicValue v2, SymbolicValue result) { this.Map = this.Map.Add(v1, v2, result); }
public void JoinSymbolicValue(SymbolicValue v1, SymbolicValue v2, SymbolicValue r) { if (Analyzer.Debug) { Console.WriteLine("JoinSymbolicValue: [{0},{1}] -> {2}", v1, v2, r); } IEnumerable keys; if (G1.termMap.Keys2Count(v1) <= G2.termMap.Keys2Count(v2)) { keys = G1.termMap.Keys2(v1); } else { keys = G2.termMap.Keys2(v2); this.changed = true; // since we have fewer keys in output } foreach (IUniqueKey function in keys) { SymbolicValue v1target = G1.LookupWithoutManifesting(v1,function); SymbolicValue v2target = G2.LookupWithoutManifesting(v2,function); if (v1target == null) { // no change in output over G1 continue; } if (v2target == null) { // absence considered Top. this.changed |= !(G1.elementLattice.IsTop(G1[v1target])); continue; } SymbolicValue rtarget = AddJointEdge(v1target, v2target, function, r); if (rtarget != null) { JoinSymbolicValue(v1target, v2target, rtarget); } } }
/// <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 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; }
private SymbolicValue Find(SymbolicValue v) { SymbolicValue result = (SymbolicValue)this.forwMap[v]; if (result == null) return v; return Find(result); }
private SymbolicValue FreshSymbolicValue() { if (this.IsConstant) { Debug.Assert(false, "modifying a locked down egraph"); } SymbolicValue v = new SymbolicValue(++idCounter); return v; }
protected EqualsRelationship(SymbolicValue leftOperand, SymbolicValue rightOperand) : base(leftOperand, rightOperand) { }
public ReferenceEqualsSymbolicValue(SymbolicValue leftOperand, SymbolicValue rightOperand) : base(leftOperand, rightOperand) { }
private bool IsOldSymbol(SymbolicValue sv) { EGraph parent = this.parent; if (parent == null) return false; return (sv.UniqueId <= parent.LastSymbolId); }
public HasValueAccessSymbolicValue(SymbolicValue nullable) : base(nullable, HasValueLiteral) { }
private void AddAValUpdate(SymbolicValue sv) { if (IsOldSymbol(sv)) { AddUpdate(new MergeState.AValUpdate(sv)); } }
private SymbolicValue AddJointEdge(SymbolicValue v1target, SymbolicValue v2target, IUniqueKey function, SymbolicValue resultRoot) { SymbolicValue rtarget = (SymbolicValue)Map[v1target, v2target]; bool newBinding = false; if (rtarget == null) { // if we have visited v1target before, then the result graph is not isomorphic to G1 if (Map.ContainsKey1(v1target) || IsCommon(v1target) && v1target != v2target) { this.changed = true; } newBinding = true; if (v1target.UniqueId <= lastCommonVariable && v1target == v2target) { rtarget = v1target; // reuse old symbol } else { rtarget = Result.FreshSymbolicValue(); } this.Map = this.Map.Add(v1target,v2target,rtarget); } else { // See if info is already present SymbolicValue oldTarget = Result.LookupWithoutManifesting(resultRoot, function); if (oldTarget == rtarget) { // no change, don't record or change anything return null; } } Result[resultRoot, function] = rtarget; AbstractValue aval1 = G1[v1target]; AbstractValue aval2 = G2[v2target]; AbstractValue aresult = G1.elementLattice.Join(aval1, aval2); Result[rtarget] = aresult; if ( ! G1.elementLattice.LowerThanOrEqual(aresult, aval1)) { this.changed = true; } if (Analyzer.Debug) { Console.WriteLine("AddJointEdge: {0} -{1}-> [{2},{3},{4}]", resultRoot, EGraph.Function2String(function), v1target, v2target, rtarget); } return (newBinding)?rtarget:null; }
private void AddEqualityUpdate(SymbolicValue sv1, SymbolicValue sv2) { if (IsOldSymbol(sv1) && IsOldSymbol(sv2)) { AddUpdate(new MergeState.EqualityUpdate(sv1, sv2)); } }
public AValUpdate(SymbolicValue sv) { this.sv = sv; }
private void AddEliminateEdgeUpdate(SymbolicValue from, IUniqueKey function) { if (IsOldSymbol(from)) { AddUpdate(new MergeState.EliminateEdgeUpdate(from, function)); } }
public EliminateEdgeUpdate(SymbolicValue from, IUniqueKey function) { this.from = from; this.function = function; }
private void AddEliminateAllUpdate(SymbolicValue from) { if (IsOldSymbol(from)) { foreach (IUniqueKey function in this.termMap.Keys2(from)) { AddUpdate(new MergeState.EliminateEdgeUpdate(from, function)); } } }
protected EqualityLikeSymbolicValue(SymbolicValue leftOperand, SymbolicValue rightOperand) : base(leftOperand, rightOperand) { }
private SymbolicValue LookupWithoutManifesting(SymbolicValue arg, IUniqueKey function) { arg = Find(arg); SymbolicValue v = (SymbolicValue)this.termMap[arg, function]; if (v == null) return v; return Find(v); }
protected abstract BinaryRelationship GetRelationship(SymbolicValue left, SymbolicValue right);
private SymbolicValue this[SymbolicValue arg, IUniqueKey function] { get { arg = Find(arg); SymbolicValue v = (SymbolicValue)this.termMap[arg, function]; if (v == null) { v = FreshSymbolicValue(); this.termMap = this.termMap.Add(arg, function, v); this.eqTermMap = this.eqTermMap.Add(v, new EGraphTerm(function, arg), null); this.AddEdgeUpdate(arg, function); } else { v = Find(v); } return v; } set { arg = Find(arg); value = Find(value); this.termMap = this.termMap.Add(arg, function, value); this.eqTermMap = this.eqTermMap.Add(value, new EGraphTerm(function, arg), null); this.AddEdgeUpdate(arg, function); } }
public BinarySymbolicValue(SymbolicValue leftOperand, SymbolicValue rightOperand) { this.leftOperand = leftOperand; this.rightOperand = rightOperand; }
public EqPair(SymbolicValue v1, SymbolicValue v2) { this.v1 = v1; this.v2 = v2; }
public ComparisonSymbolicValue(ComparisonKind comparisonKind, SymbolicValue leftOperand, SymbolicValue rightOperand) : base(leftOperand, rightOperand) { this.comparisonKind = comparisonKind; }
private void PushEquality(WorkList wl, SymbolicValue v1, SymbolicValue v2) { if (v1 == v2) return; wl.Add(new EqPair(v1, v2)); }
protected override BinaryRelationship GetRelationship(SymbolicValue left, SymbolicValue right) { return new ReferenceEqualsRelationship(left, right); }
private static bool IsValueNotNull(SymbolicValue arg, ITypeSymbol type, ProgramState programState) { return(programState.HasConstraint(arg, ObjectConstraint.NotNull) && type.IsValueType); }