public CsAutomaton(CsAlgebra <S> productAlgebra, Automaton <CsLabel <S> > aut, PowerSetStateBuilder stateBuilder, Dictionary <int, ICounter> countingStates, HashSet <int> origFinalStates) : base(aut)
 {
     this.stateBuilder    = stateBuilder;
     this.countingStates  = countingStates;
     this.origFinalStates = origFinalStates;
     activeCounterMap     = new Dictionary <int, HashSet <int> >();
     finalCounterSet      = new HashSet <int>();
     counters             = new ICounter[countingStates.Count];
     foreach (var q in aut.States)
     {
         var q_set = new HashSet <int>();
         activeCounterMap[q] = q_set;
         foreach (var mem in stateBuilder.GetMembers(q))
         {
             if (countingStates.ContainsKey(mem))
             {
                 var counterId = countingStates[mem].CounterId;
                 q_set.Add(counterId);
                 if (origFinalStates.Contains(mem))
                 {
                     finalCounterSet.Add(counterId);
                 }
                 counters[counterId] = countingStates[mem];
             }
         }
     }
     this.productAlgebra      = productAlgebra;
     stateDescr[InitialState] = SpecialCharacters.S(0);
 }
        public string ToString <S>(CsAlgebra <S> algebra)
        {
            string s = "";

            if (isAND)
            {
                for (int i = 0; i < Length; i++)
                {
                    if (this[i] != CsCondition.TRUE)
                    {
                        if (s != "")
                        {
                            s += SpecialCharacters.AND;
                        }
                        s += DescribeCondition <S>(algebra, this[i], i);
                    }
                }
                if (s == "")
                {
                    s = SpecialCharacters.TOP.ToString();
                }
            }
            else
            {
                for (int i = 0; i < Length; i++)
                {
                    if (this[i] != CsCondition.FALSE)
                    {
                        if (s != "")
                        {
                            s += SpecialCharacters.OR;
                        }
                        s += DescribeCondition <S>(algebra, this[i], i);
                    }
                }
                if (s == "")
                {
                    s = SpecialCharacters.BOT.ToString();
                }
            }
            return(s);
        }
Exemple #3
0
 internal CsPred(CsAlgebra <T> alg, BDD <T> pred)
 {
     this.alg  = alg;
     this.pred = pred;
 }
        public static string DescribeCondition <S>(CsAlgebra <S> algebra, CsCondition cond, int i)
        {
            string c        = SpecialCharacters.c(i);
            string canExit  = SpecialCharacters.XI_LOWERCASE + SpecialCharacters.ToSubscript(i);
            string canIncr  = SpecialCharacters.IOTA_LOWERCASE + SpecialCharacters.ToSubscript(i);
            char   and      = SpecialCharacters.AND;
            char   or       = SpecialCharacters.OR;
            char   not      = SpecialCharacters.NOT;
            string empty    = string.Format("{0}={1}", c, SpecialCharacters.EMPTYSET);
            string nonempty = string.Format("{0}{1}{2}", c, SpecialCharacters.NEQ, SpecialCharacters.EMPTYSET);
            string _true    = SpecialCharacters.TOP.ToString();
            string _false   = SpecialCharacters.BOT.ToString();

            switch (cond)
            {
            case CsCondition.TRUE:
                return(_true);

            case CsCondition.FALSE:
                return(_false);

            case CsCondition.EMPTY:
                return(empty);

            case CsCondition.NONEMPTY:
                return(nonempty);

            case CsCondition.LOW:
                //return string.Format("{0}{2}{3}{4}max({0})<{1}", SpecialCharacters.Cntr(i), algebra.GetCounter(i).LowerBound, SpecialCharacters.NEQ, SpecialCharacters.EMPTYSET, SpecialCharacters.AND);
                //return canIncr + and + not + canExit;
                return(not + canExit);

            case CsCondition.HIGH:
                //return string.Format("{0}={{{1}}}", SpecialCharacters.Cntr(i), algebra.GetCounter(i).UpperBound);
                //return not + canIncr + and + canExit;
                return(not + canIncr);

            case CsCondition.CANEXIT:
                //return string.Format("{0}{1}{2}", SpecialCharacters.Cntr(i), SpecialCharacters.GEQ, algebra.GetCounter(i).LowerBound);
                return(canExit);

            case CsCondition.CANNOTEXIT:
                //return string.Format("{0}{1}{2}", SpecialCharacters.Cntr(i), SpecialCharacters.NOTGEQ, algebra.GetCounter(i).LowerBound);
                return(not + canExit);

            case CsCondition.CANLOOP:
                //return string.Format("{0}+1{1}{2}", SpecialCharacters.Cntr(i), SpecialCharacters.NEQ, SpecialCharacters.EMPTYSET);
                //return string.Format("{0}x{1}{2}(x<{3})", SpecialCharacters.EXISTS, SpecialCharacters.IN, SpecialCharacters.Cntr(i), algebra.GetCounter(i).UpperBound);
                return(canIncr);

            case CsCondition.CANNOTLOOP:
                //return string.Format("{0}+1{1}{2}", SpecialCharacters.Cntr(i), "=", SpecialCharacters.EMPTYSET);
                //return string.Format("{0}x{1}{2}(x<{3})", SpecialCharacters.NOTEXISTS, SpecialCharacters.IN, SpecialCharacters.Cntr(i), algebra.GetCounter(i).UpperBound);
                return(not + canIncr);

            case CsCondition.MIDDLE:
                //return string.Format("{2}{4}{5}{6}{0}{1}max({2})<{3}", algebra.GetCounter(i).LowerBound, SpecialCharacters.LEQ, SpecialCharacters.Cntr(i), algebra.GetCounter(i).UpperBound, SpecialCharacters.NEQ, SpecialCharacters.EMPTYSET, SpecialCharacters.AND);
                return(canIncr + and + canExit);

                #region these cases should not occur
            case CsCondition.LOWorHIGH:
                //return string.Format("({0}{1}{2})", DescribeCondition<S>(algebra, CsCondition.LOW, i), SpecialCharacters.OR, DescribeCondition<S>(algebra, CsCondition.HIGH, i));
                return("(" + not + canIncr + or + not + canExit + ")");

            case CsCondition.EMPTYorCANEXIT:
                return("(" + empty + or + canExit + ")");

            case CsCondition.EMPTYorCANLOOP:
                return("(" + empty + or + canIncr + ")");

            case CsCondition.EMPTYorHIGHorLOW:
                return("(" + empty + or + not + canIncr + or + not + canExit + ")");

            case CsCondition.EMPTYorMIDDLE:
                return("(" + empty + or + canIncr + and + canExit + ")");

            default:
                throw new AutomataException(AutomataExceptionKind.UndefinedEnum);
                #endregion
            }
        }
        public static CsAutomaton <S> CreateFrom(CountingAutomaton <S> ca)
        {
            var productmoves = new List <Move <CsPred <S> > >();
            var counters     = ca.counters;
            var alg          = new CsAlgebra <S>(((CABA <S>)ca.Algebra).builder.solver, counters);

            foreach (var move in ca.GetMoves())
            {
                var ccond = alg.TrueCsConditionSeq;
                if (ca.IsCountingState(move.SourceState))
                {
                    var counter = ca.GetCounter(move.SourceState);
                    var cid     = counter.CounterId;
                    if (move.Label.Item2.First.OperationKind == CounterOp.EXIT ||
                        move.Label.Item2.First.OperationKind == CounterOp.EXIT_SET0 ||
                        move.Label.Item2.First.OperationKind == CounterOp.EXIT_SET1)
                    {
                        if (counter.LowerBound == counter.UpperBound && !ca.HasMovesTo(move.SourceState, move.Label.Item1.Element))
                        {
                            ccond = ccond.And(cid, CsCondition.HIGH);
                        }
                        else if (counter.LowerBound > 0)
                        {
                            ccond = ccond.And(cid, CsCondition.CANEXIT);
                        }
                        else
                        {
                            ccond.And(cid, CsCondition.NONEMPTY);
                        }
                    }
                    else
                    {
                        if (move.Label.Item2.First.OperationKind != CounterOp.INCR)
                        {
                            throw new AutomataException(AutomataExceptionKind.InternalError);
                        }

                        if (counter.LowerBound == counter.UpperBound && !ca.HasMovesTo(move.SourceState, move.Label.Item1.Element))
                        {
                            ccond = ccond.And(cid, CsCondition.LOW);
                        }
                        else
                        {
                            ccond = ccond.And(cid, CsCondition.CANLOOP);
                        }
                    }
                }
                if (ccond.IsSatisfiable)
                {
                    var pmove = Move <CsPred <S> > .Create(move.SourceState, move.TargetState, alg.MkPredicate(move.Label.Item1.Element, ccond));

                    productmoves.Add(pmove);
                }
            }
            var prodaut = Automaton <CsPred <S> > .Create(alg, ca.InitialState, ca.GetFinalStates(), productmoves);

            PowerSetStateBuilder sb;
            var det = prodaut.Determinize(out sb);

            //add predicate that all counters associated with the state are nonempty
            var counterFilter = new Dictionary <int, CsConditionSeq>();

            foreach (var state in det.GetStates())
            {
                var stateCounterFilter = alg.TrueCsConditionSeq;
                foreach (var q in sb.GetMembers(state))
                {
                    if (ca.IsCountingState(q))
                    {
                        stateCounterFilter = stateCounterFilter.And(ca.GetCounter(q).CounterId, CsCondition.NONEMPTY);
                    }
                }
                counterFilter[state] = stateCounterFilter;
            }

            var csmoves = new List <Move <CsLabel <S> > >();

            //make disjunction of the guards of transitions with same update sequence
            var trans = new Dictionary <Tuple <int, int>, Dictionary <CsUpdateSeq, CsPred <S> > >();

            foreach (var dmove in det.GetMoves())
            {
                foreach (var prodcond in dmove.Label.GetSumOfProducts())
                {
                    var upd = CsUpdateSeq.MkNOOP(ca.NrOfCounters);
                    foreach (var q in sb.GetMembers(dmove.SourceState))
                    {
                        upd = upd | ca.GetCounterUpdate(q, prodcond.Item2, prodcond.Item1);
                    }
                    //make sure all counter guards are nonempty
                    //determinization may create EMPTY counter conditions that are unreachable
                    //while all counters associated with a state are always nonempty
                    var counterGuard = prodcond.Item1 & counterFilter[dmove.SourceState];
                    if (counterGuard.IsSatisfiable)
                    {
                        #region replace set with incr if possible
                        for (int i = 0; i < upd.Length; i++)
                        {
                            var guard_i = counterGuard[i];
                            if (guard_i == CsCondition.HIGH)
                            {
                                var upd_i = upd[i];
                                switch (upd_i)
                                {
                                case CsUpdate.SET0:
                                    upd = upd.Set(i, CsUpdate.INCR0);
                                    break;

                                case CsUpdate.SET1:
                                    upd = upd.Set(i, CsUpdate.INCR1);
                                    break;

                                case CsUpdate.SET01:
                                    upd = upd.Set(i, CsUpdate.INCR01);
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                        #endregion

                        var guard     = alg.MkPredicate(prodcond.Item2, counterGuard);
                        var statepair = new Tuple <int, int>(dmove.SourceState, dmove.TargetState);
                        Dictionary <CsUpdateSeq, CsPred <S> > labels;
                        if (!trans.TryGetValue(statepair, out labels))
                        {
                            labels           = new Dictionary <CsUpdateSeq, CsPred <S> >();
                            trans[statepair] = labels;
                        }
                        CsPred <S> pred;
                        if (!labels.TryGetValue(upd, out pred))
                        {
                            pred = guard;
                        }
                        else
                        {
                            pred = guard | pred;
                        }
                        labels[upd] = pred;
                    }
                    else
                    {
                        ;
                    }
                }
            }

            Func <S, string> pp = ((CABA <S>)ca.Algebra).builder.solver.PrettyPrint;
            foreach (var entry in trans)
            {
                var s = entry.Key.Item1;
                var t = entry.Key.Item2;
                foreach (var label in entry.Value)
                {
                    var upd = label.Key;
                    var psi = label.Value;
                    csmoves.Add(Move <CsLabel <S> > .Create(s, t, CsLabel <S> .MkTransitionLabel(psi, upd, pp)));
                }
            }

            var csa_aut = Automaton <CsLabel <S> > .Create(null, det.InitialState, det.GetFinalStates(), csmoves, true, true);

            var fs = new HashSet <int>(ca.GetFinalStates());

            var csa = new CsAutomaton <S>(alg, csa_aut, sb, ca.countingStates, fs);

            return(csa);
        }