Example #1
0
        /// <summary>
        /// Restrict top down wrt the path condition and strengthen the leaf predicates with psi
        /// </summary>
        BDG <T, S> Restrict(S path, T psi)
        {
            var        key = new Tuple <S, T, BDG <T, S> >(path, psi, this);
            BDG <T, S> val;

            if (!algebra.restrictCache.TryGetValue(key, out val))
            {
                if (this.IsLeaf)
                {
                    val = this.algebra.MkLeaf(this.algebra.leafAlgebra.MkAnd(this.LeafCondition, psi), true);
                }
                else
                {
                    #region restrict the children
                    var path_and_not_nodePred = algebra.nodeAlgebra.MkAnd(path, algebra.nodeAlgebra.MkNot(BranchCondition));
                    if (algebra.nodeAlgebra.IsSatisfiable(path_and_not_nodePred))
                    {
                        var f = this.FalseCase.Restrict(path_and_not_nodePred, psi);
                        var path_and_nodePred = algebra.nodeAlgebra.MkAnd(path, BranchCondition);
                        if (algebra.nodeAlgebra.IsSatisfiable(path_and_nodePred))
                        {
                            var t = this.TrueCase.Restrict(path_and_nodePred, psi);
                            if (f == this.FalseCase && t == this.TrueCase)
                            {
                                val = this; //nothing changed
                            }
                            else
                            {
                                val = this.algebra.MkNode(BranchCondition, t, f);
                            }
                        }
                        else //path implies not(nodePred)
                        {
                            val = f;
                        }
                    }
                    else //path implies nodePred
                    {
                        val = TrueCase.Restrict(path, psi);
                    }
                    #endregion
                }
                algebra.restrictCache[key] = val;
            }
            return(val);
        }
Example #2
0
        /// <summary>
        /// Maintains the node invariant: sat(path &amp; nodePred) and sat(path &amp; ~nodePred)
        /// </summary>
        BDG <T, S> MkAnd(S path, BDG <T, S> that)
        {
            var        key = new Tuple <S, BDG <T, S>, BDG <T, S> >(path, this, that);
            BDG <T, S> val;

            if (!algebra.MkAndCache.TryGetValue(key, out val))
            {
                if (this.IsLeaf)
                {
                    if (path.Equals(algebra.nodeAlgebra.True))
                    {
                        val = that.RestrictLeaves(this.LeafCondition);
                    }
                    else
                    {
                        val = that.Restrict(path, this.LeafCondition);
                    }
                }
                else if (that.IsLeaf)
                {
                    val = this.RestrictLeaves(that.LeafCondition); //path is not relevant
                }
                else
                {
                    var path_and_thatCond = algebra.nodeAlgebra.MkAnd(path, that.BranchCondition);
                    if (!algebra.nodeAlgebra.IsSatisfiable(path_and_thatCond))
                    {
                        //path implies ~that.BranchCondition
                        var t = this.TrueCase.MkAnd(algebra.nodeAlgebra.MkAnd(path, this.BranchCondition), that.FalseCase);
                        var f = this.FalseCase.MkAnd(algebra.nodeAlgebra.MkAnd(path, algebra.nodeAlgebra.MkNot(this.BranchCondition)), that.FalseCase);
                        if (t == this.TrueCase && f == this.FalseCase)
                        {
                            val = this;
                        }
                        else
                        {
                            val = this.algebra.MkNode(this.BranchCondition, t, f);
                        }
                    }
                    else
                    {
                        var path_and_not_thatCond = algebra.nodeAlgebra.MkAnd(path, algebra.nodeAlgebra.MkNot(that.BranchCondition));
                        if (!algebra.nodeAlgebra.IsSatisfiable(path_and_not_thatCond))
                        {
                            //path implies that.BranchCondition
                            var t = this.TrueCase.MkAnd(algebra.nodeAlgebra.MkAnd(path, this.BranchCondition), that.TrueCase);
                            var f = this.FalseCase.MkAnd(algebra.nodeAlgebra.MkAnd(path, algebra.nodeAlgebra.MkNot(this.BranchCondition)), that.TrueCase);
                            if (t == this.TrueCase && f == this.FalseCase)
                            {
                                val = this;
                            }
                            else
                            {
                                val = this.algebra.MkNode(this.BranchCondition, t, f);
                            }
                        }
                        else
                        {  //both cases are possible
                            var t = this.TrueCase.MkAnd(algebra.nodeAlgebra.MkAnd(path, this.BranchCondition), that);
                            var f = this.FalseCase.MkAnd(algebra.nodeAlgebra.MkAnd(path, algebra.nodeAlgebra.MkNot(this.BranchCondition)), that);
                            if (t == this.TrueCase && f == this.FalseCase)
                            {
                                val = this;
                            }
                            else
                            {
                                val = this.algebra.MkNode(this.BranchCondition, t, f);
                            }
                        }
                    }
                }
                algebra.MkAndCache[key] = val;
            }
            return(val);
        }