Exemplo n.º 1
0
 CsLabel(bool isFinalCondition, CsPred <S> guard, CsUpdateSeq updates, Func <S, string> inputToString)
 {
     this.isFinalCondition = isFinalCondition;
     this.Guard            = guard;
     this.Updates          = updates;
     this.InputToString    = inputToString;
 }
Exemplo n.º 2
0
        public CsUpdateSeq Or(int i, CsUpdate upd)
        {
            ulong bit  = ((ulong)1) << i;
            ulong set0 = vals.Item2;
            ulong set1 = vals.Item3;
            ulong incr = vals.Item4;

            if (upd.HasFlag(CsUpdate.SET0))
            {
                set0 = set0 | bit;
            }
            if (upd.HasFlag(CsUpdate.SET1))
            {
                set1 = set1 | bit;
            }
            if (upd.HasFlag(CsUpdate.INCR))
            {
                incr = incr | bit;
            }
            CsUpdateSeq res = new CsUpdateSeq(vals.Item1, set0, set1, incr);

            return(res);
        }
Exemplo n.º 3
0
 public static CsLabel <S> MkTransitionLabel(CsPred <S> guard, CsUpdateSeq updates, Func <S, string> inputToString = null)
 {
     return(new CsLabel <S>(false, guard, updates, inputToString));
 }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
0
        internal CsUpdateSeq  GetCounterUpdate(int q, S input, CsConditionSeq guard)
        {
            var res = CsUpdateSeq.MkNOOP(countingStates.Count);

            foreach (var mv in delta[q])
            {
                if (mv.Label.Item1.IsSomething && solver.IsSatisfiable(solver.MkAnd(mv.Label.Item1.Element, input)))
                {
                    var p = mv.TargetState;
                    if (IsCountingState(p))
                    {
                        var p_counter = GetCounter(p);
                        if (p == q)
                        {
                            #region loop
                            if (mv.Label.Item2.Length != 1)
                            {
                                throw new AutomataException(AutomataExceptionKind.InternalError);
                            }
                            else
                            {
                                var op = mv.Label.Item2[0];
                                if (guard[p_counter.CounterId].HasFlag(CsCondition.LOW) ||
                                    guard[p_counter.CounterId].HasFlag(CsCondition.MIDDLE) ||
                                    guard[p_counter.CounterId].HasFlag(CsCondition.HIGH))
                                {
                                    if (op.OperationKind == CounterOp.INCR)
                                    {
                                        res = res.Or(op.Counter.CounterId, CsUpdate.INCR);
                                    }
                                    else if (op.OperationKind == CounterOp.EXIT_SET0)
                                    {
                                        res = res.Or(op.Counter.CounterId, CsUpdate.SET0);
                                    }
                                    else if (op.OperationKind == CounterOp.EXIT_SET1)
                                    {
                                        res = res.Or(op.Counter.CounterId, CsUpdate.SET1);
                                    }
                                    else
                                    {
                                        throw new AutomataException(AutomataExceptionKind.InternalError);
                                    }
                                }
                            }
                            #endregion
                        }
                        else if (IsCountingState(q))
                        {
                            #region q is counting state too
                            var q_counter = GetCounter(q);
                            if (mv.Label.Item2.Length != 2)
                            {
                                throw new AutomataException(AutomataExceptionKind.InternalError);
                            }
                            else
                            {
                                var q_exit = mv.Label.Item2[0];
                                var p_set  = mv.Label.Item2[1];
                                if (q_exit.Counter.CounterId != q_counter.CounterId || p_set.Counter.CounterId != p_counter.CounterId)
                                {
                                    throw new AutomataException(AutomataExceptionKind.InternalError);
                                }

                                if (guard[q_counter.CounterId].HasFlag(CsCondition.HIGH) ||
                                    guard[q_counter.CounterId].HasFlag(CsCondition.MIDDLE))
                                {
                                    if (p_set.OperationKind == CounterOp.SET0)
                                    {
                                        res = res.Or(p_set.Counter.CounterId, CsUpdate.SET0);
                                    }
                                    else if (p_set.OperationKind == CounterOp.SET1)
                                    {
                                        res = res.Or(p_set.Counter.CounterId, CsUpdate.SET1);
                                    }
                                    else
                                    {
                                        throw new AutomataException(AutomataExceptionKind.InternalError);
                                    }
                                }
                            }
                            #endregion
                        }
                        else
                        {
                            #region q is non-counting state
                            if (mv.Label.Item2.Length != 1)
                            {
                                throw new AutomataException(AutomataExceptionKind.InternalError);
                            }
                            else
                            {
                                var p_set = mv.Label.Item2[0];
                                if (p_set.Counter.CounterId != p_counter.CounterId)
                                {
                                    throw new AutomataException(AutomataExceptionKind.InternalError);
                                }


                                if (p_set.OperationKind == CounterOp.SET0)
                                {
                                    res = res.Or(p_set.Counter.CounterId, CsUpdate.SET0);
                                }
                                else if (p_set.OperationKind == CounterOp.SET1)
                                {
                                    res = res.Or(p_set.Counter.CounterId, CsUpdate.SET1);
                                }
                                else
                                {
                                    throw new AutomataException(AutomataExceptionKind.InternalError);
                                }
                            }
                            #endregion
                        }
                    }
                }
            }
            return(res);
        }