protected override void OnBeforePathStepExtended(FlowEdge edge)
        {
            this.smtSolver.Push();
            this.Heap.PushState();

            if (edge is OuterFlowEdge outerEdge)
            {
                if (outerEdge.Kind == OuterFlowEdgeKind.MethodCall &&
                    outerEdge.To is EnterFlowNode enterNode)
                {
                    var callNode = (CallFlowNode)outerEdge.From;
                    if (callNode.IsObjectCreation)
                    {
                        // This is needed in the case when the exploration itself started from a constructor (or from a
                        // method called by it). We need to let the heap know that this object is not a part of the input
                        // heap.
                        var newVar       = enterNode.Parameters[0];
                        var versionedVar = new VersionedVariable(newVar, this.GetVariableVersion(newVar));
                        this.Heap.AllocateNew(versionedVar);
                    }
                    else if (callNode.IsInstanceCall)
                    {
                        var thisVar          = enterNode.Parameters[0];
                        var versionedThisVar = new VersionedVariable(thisVar, this.GetVariableVersion(thisVar));
                        this.Heap.AssertEquality(false, versionedThisVar, VersionedVariable.Null);
                    }
                }
            }
        }
 protected override void OnFieldReadAsserted(
     VersionedVariable result,
     VersionedVariable reference,
     IFieldDefinition field)
 {
     this.Heap.ReadField(result, reference, field);
 }
 protected override void OnFieldWriteAsserted(
     VersionedVariable reference,
     IFieldDefinition field,
     Expression value)
 {
     this.Heap.WriteField(reference, field, value);
 }
 protected override void OnReferenceEqualityAsserted(
     bool areEqual,
     VersionedVariable left,
     VersionedVariable right)
 {
     this.Heap.AssertEquality(areEqual, left, right);
 }
 protected override void OnFieldReadRetracted(
     VersionedVariable result,
     VersionedVariable reference,
     IFieldDefinition field)
 {
     this.heapModelRecorder.ReadField(reference, field);
     this.AddVariableValue(result);
 }
 private void AddVariableValue(VersionedVariable variable)
 {
     if (variable.Variable.IsReference)
     {
         this.AddVariableHeapLocation(variable);
     }
     else
     {
         this.AddVariableInterpretation(variable);
     }
 }
            protected override void OnReferenceEqualityRetracted(
                bool areEqual,
                VersionedVariable left,
                VersionedVariable right)
            {
                // TODO: Store the comparison result to the interpretation stack when expected in ViewModel

                // Only let the heap model know that we are interested in them
                // so that it displays them later
                this.heapModelRecorder.GetLocation(left);
                this.heapModelRecorder.GetLocation(right);
            }
            private void AddVariableHeapLocation(VersionedVariable variable)
            {
                Contract.Requires(variable.Variable.IsReference);

                var heapLocation = this.heapModelRecorder.GetLocation(variable);

                if (this.areAssignmentsPostponedToNextNode)
                {
                    this.nextNodeHeapLocations.Add(heapLocation);
                }
                else
                {
                    this.currentNodeHeapLocations.Add(heapLocation);
                }
            }
            private void AddVariableInterpretation(VersionedVariable variable)
            {
                Contract.Requires(!variable.Variable.IsReference);

                var symbolName = this.smtContextHandler.GetVariableVersionSymbol(
                    variable.Variable,
                    variable.Version);
                var interpretation = this.smtModel.GetInterpretation(symbolName);

                if (this.areAssignmentsPostponedToNextNode)
                {
                    this.nextNodeInterpretations.Add(interpretation);
                }
                else
                {
                    this.currentNodeInterpretations.Add(interpretation);
                }
            }
            protected override void OnAfterPathStepRetracted(FlowEdge edge)
            {
                // Identify the creation of new objects on the heap
                if (edge is OuterFlowEdge outerEdge &&
                    outerEdge.Kind == OuterFlowEdgeKind.MethodCall &&
                    outerEdge.From is CallFlowNode callNode &&
                    callNode.IsObjectCreation)
                {
                    // "this" must be the first variable in the constructor by convention
                    var thisVar = edge.To.Graph.LocalVariables[0];

                    Contract.Assert(thisVar.IsReference);

                    var versionedVar = new VersionedVariable(thisVar, this.GetVariableVersion(thisVar));
                    this.heapModelRecorder.AllocateNew(versionedVar);
                }

                this.AddNodeValues();
            }
            protected override void OnFieldWriteRetracted(
                VersionedVariable reference,
                IFieldDefinition field,
                Expression value)
            {
                if (value.Sort == References.Sort)
                {
                    if (!(value is FlowVariable valVar))
                    {
                        throw new NotSupportedException("Only versioned flow variables supported as references");
                    }

                    this.heapModelRecorder.WriteReferenceField(reference, field, this.GetVersioned(valVar));
                }
                else
                {
                    var valueInterpretation = this.smtModel.GetInterpretation(this.NameProvider, value);
                    this.heapModelRecorder.WriteValueField(reference, field, valueInterpretation);
                }

                this.AddVariableHeapLocation(reference);
            }
        protected override void OnVariableAssigned(
            FlowVariable variable,
            int lastVersion,
            Expression value)
        {
            if (variable.IsReference)
            {
                var leftRef  = new VersionedVariable(variable, lastVersion);
                var rightRef = this.GetVersioned((FlowVariable)value);

                this.Heap.AssignReference(leftRef, rightRef);
            }
            else if (References.IsReferenceComparison(value, out bool areEqual, out var left, out var right))
            {
                var varLeft  = this.GetVersioned(left);
                var varRight = this.GetVersioned(right);
                value = this.Heap.GetEqualityExpression(areEqual, varLeft, varRight);
            }

            if (!variable.IsReference)
            {
                this.AssertEquals(variable, lastVersion, value);
            }
        }
            public NamedVariable GetNamedVariable(VersionedVariable variable)
            {
                var name = this.owner.contextHandler.GetVariableVersionSymbol(variable.Variable, variable.Version);

                return(ExpressionFactory.NamedVariable(variable.Variable.Sort, name));
            }