Beispiel #1
0
        protected virtual LBDDNode MakeOrReturn(int var, LBDDNode.Labeling lab, LBDDNode high, LBDDNode low)
        {
            var t = Tuple.Create(var, lab, high.GetId(), low.GetId());

            if (high.GetId() == low.GetId())
            {
                return(low);
            }
            if (_hashTable.ContainsKey(t))
            {
                return(_hashTable[t]);
            }
            LBDDNode node;

            if (lab == LBDDNode.Labeling.Double)
            {
                // ite(&x, 0, 1)=ite($x, 1, 0)
                // ite(&x, 0, K)=ite($x, K, 0)
                if (high.GetId() == Zero.GetId())
                {
                    t    = Tuple.Create(var, LBDDNode.Labeling.Negate, low.GetId(), Zero.GetId());
                    node = new LBDDNode(var, _id, Zero, low, LBDDNode.Labeling.Negate);
                }
                // ite(&x, 1, 0)=ite(x, 1, 0)
                // ite(&x, 1, K)=ite(x, 1, K)
                else if (high.GetId() == One.GetId())
                {
                    t    = Tuple.Create(var, LBDDNode.Labeling.Non, high.GetId(), low.GetId());
                    node = new LBDDNode(var, _id, low, high, LBDDNode.Labeling.Non);
                }
                // ite(&x, H, 0)=ite(x, H, 0)
                else if (low.GetId() == Zero.GetId())
                {
                    t    = Tuple.Create(var, LBDDNode.Labeling.Non, low.GetId(), Zero.GetId());
                    node = new LBDDNode(var, _id, Zero, high, LBDDNode.Labeling.Non);
                }
                // ite(&x, H, 1)=ite($x, 1, H)
                else if (low.GetId() == One.GetId())
                {
                    t    = Tuple.Create(var, LBDDNode.Labeling.Negate, One.GetId(), high.GetId());
                    node = new LBDDNode(var, _id, high, One, LBDDNode.Labeling.Negate);
                }
                else
                {
                    node = new LBDDNode(var, _id, low, high, lab);
                }

                if (_hashTable.ContainsKey(t))
                {
                    return(_hashTable[t]);
                }
            }
            else
            {
                node = new LBDDNode(var, _id, low, high, lab);
            }

            _id++;
            _hashTable.Add(t, node);
            return(node);
        }
Beispiel #2
0
        public virtual LBDDNode AND(LBDDNode H, LBDDNode K)
        {
            // h & 0 = 0 & k = 0
            if (H.GetId() == Zero.GetId() || K.GetId() == Zero.GetId())
            {
                return(Zero);
            }
            // 1 & k = k
            if (H.GetId() == One.GetId())
            {
                return(K);
            }
            // h & 1 = h
            if (K.GetId() == One.GetId())
            {
                return(H);
            }
            //h==k
            if (K.GetId() == H.GetId())
            {
                return(K);
            }
            //f&g == g&f, сначала с меньшим номером, потом с большим
            var t = H.GetId() > K.GetId()
                ? Tuple.Create(K.GetId(), H.GetId())
                : Tuple.Create(H.GetId(), K.GetId());

            // была ли такая операция раньше
            if (_andCache.ContainsKey(t))
            {
                return(_andCache[t]);
            }

            int      top = TopVar(H, K);
            LBDDNode low = null, high = null;

            LBDDNode.Labeling lab = LBDDNode.Labeling.Non;

            var h1 = Contraction(H, top, true);
            var h0 = Contraction(H, top, false);
            var k1 = Contraction(K, top, true);
            var k0 = Contraction(K, top, false);

            // постро построение bdd без гнс

            //Different variables, any label
            if (H.GetVarId() != K.GetVarId())
            {
                if (H.GetVarId() == top)
                {
                    low  = AND(h0, K);
                    high = AND(h1, K);
                    lab  = H.Label;
                }
                else     //if (k.GetVarId() == top)
                {
                    low  = AND(H, k0);
                    high = AND(H, k1);
                    lab  = K.Label;
                }
            }
            else
            {
                //Same variable, same label
                if (H.Label == K.Label)
                {
                    high = AND(h1, k1);
                    low  = AND(h0, k0);
                    lab  = H.Label;
                }
                //Same variable, diff labels
                // H = ite(&x, H1 , H0) and K = ite(x, K1 , K0) =>
                // H and K = ite(&x, (H1 and K1), (H0 and K0))
                else if (H.IsNormal() && K.IsDouble() || H.IsDouble() && K.IsNormal())
                {
                    lab  = LBDDNode.Labeling.Double;
                    high = AND(h1, k1);
                    low  = AND(h0, k0);
                }
                else
                {
                    lab = LBDDNode.Labeling.Double;
                    // H = ite (x, H1, H0) and K = ite($x, K1 , K0) ||
                    // H = ite (&x, H1, H0) and K = ite($x, K1 , K0) =>
                    // H and K = ite(&x, (H1 and K0), (H0 and K1))
                    if (K.IsNegate())
                    {
                        high = AND(h1, k0);
                        low  = AND(h0, k1);
                    }
                    else
                    {
                        high = AND(h0, k1);
                        low  = AND(h1, k0);
                    }
                }
            }

            var node = MakeOrReturn(top, lab, high, low);

            _andCache.Add(t, node);
            return(node);
        }
Beispiel #3
0
        public virtual LBDDNode OR(LBDDNode H, LBDDNode K)
        {
            // (h||1) = (1||k) = 1
            if (H.GetId() == One.GetId() || K.GetId() == One.GetId())
            {
                return(One);
            }
            // (0||k) = k
            if (H.GetId() == Zero.GetId())
            {
                return(K);
            }
            // (h||0) = h
            if (K.GetId() == Zero.GetId())
            {
                return(H);
            }


            //f||g == g||f, сначала с меньшим номером, потом с большим
            var t = H.GetId() > K.GetId()
                ? Tuple.Create(K.GetId(), H.GetId())
                : Tuple.Create(H.GetId(), K.GetId());

            if (_orCache.ContainsKey(t))
            {
                return(_orCache[t]);
            }

            int      top = TopVar(H, K);
            LBDDNode low = null, high = null;

            LBDDNode.Labeling lab = LBDDNode.Labeling.Non;

            var h1 = Contraction(H, top, true);
            var h0 = Contraction(H, top, false);
            var k1 = Contraction(K, top, true);
            var k0 = Contraction(K, top, false);

            //Different variables, any label
            if (H.GetVarId() != K.GetVarId())
            {
                if (H.GetVarId() == top)
                {
                    low  = OR(h0, K);
                    high = OR(h1, K);
                    lab  = H.Label;
                }
                else //if (k.GetVarId() == top)
                {
                    low  = OR(H, k0);
                    high = OR(H, k1);
                    lab  = K.Label;
                }
            }
            else
            {
                //Same variable, same label
                if (H.Label == K.Label)
                {
                    high = OR(h1, k1);
                    low  = OR(h0, k0);
                    lab  = H.Label;
                }
                //Same variable, diff labels
                // H = ite(&x, H1 , H0) OR K = ite(x, K1 , K0) =>
                // H OR K = ite(&x, (H1 OR K1), (H0 OR K0))
                else if (H.IsNormal() && K.IsDouble() || H.IsDouble() && K.IsNormal())
                {
                    lab  = LBDDNode.Labeling.Double;
                    high = OR(h1, k1);
                    low  = OR(h0, k0);
                }
                else
                {
                    lab = LBDDNode.Labeling.Double;
                    // H = ite (x, H1, H0) OR K = ite($x, K1 , K0) ||
                    // H = ite (&x, H1, H0) OR K = ite($x, K1 , K0) =>
                    // H OR K = ite(&x, (H1 OR K0), (H0 OR K1))
                    if (K.IsNegate())
                    {
                        high = OR(h1, k0);
                        low  = OR(h0, k1);
                    }
                    else
                    {
                        high = OR(h0, k1);
                        low  = OR(h1, k0);
                    }
                }
            }


            var node = MakeOrReturn(top, lab, high, low);

            _orCache.Add(t, node);
            return(node);
        }