Esempio n. 1
0
        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);
        }
Esempio n. 2
0
 public override string DescribeLabel(CsLabel <S> lab)
 {
     return(lab.ToString(__debugmode));
 }