Example #1
0
        /// <summary>
        /// Restrict the leaf predicates with psi
        /// </summary>
        BDG <T, S> RestrictLeaves(T psi)
        {
            var        key = new Tuple <T, BDG <T, S> >(psi, this);
            BDG <T, S> val;

            if (!algebra.restrictLeafCache.TryGetValue(key, out val))
            {
                if (this.IsLeaf)
                {
                    val = this.algebra.MkLeaf(this.algebra.leafAlgebra.MkAnd(this.LeafCondition, psi), true);
                }
                else
                {
                    var t = TrueCase.RestrictLeaves(psi);
                    var f = FalseCase.RestrictLeaves(psi);
                    if (t == TrueCase && f == FalseCase)
                    {
                        val = this;
                    }
                    else
                    {
                        val = this.algebra.MkNode(this.BranchCondition, t, f);
                    }
                }
                algebra.restrictLeafCache[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);
        }