Ejemplo n.º 1
0
        /// <summary>
        /// Add a guard to this collection.
        /// </summary>
        /// <param name="tg">The trigger guard to add.</param>
        public void AddGuard(IElementaryTriggerCondition c0, TriggerGuard tg)
        {
            var   name = tg.Guard.Name;
            Entry entry;

            if (!_map.TryGetValue(name, out entry))
            {
                _map[name] = entry = new Entry(tg.Guard);
            }

            // calculate effective conditions for the guard
            var c = new TriggerConditions(c0);

            switch (tg.Guard.Type)
            {
            case GuardType.LEAVE:
                c.PreCondition  = Gate.ComposeAND(c.PreCondition, tg.PreCondition);
                c.PostCondition = Gate.ComposeAND(c.PostCondition, tg.PostCondition);
                break;

            case GuardType.TRANSITION:
                c.PreCondition  = Gate.ComposeAND(c.PreCondition, tg.PreCondition);
                c.PostCondition = Gate.ComposeAND(c.PostCondition, tg.PostCondition);
                break;

            case GuardType.ENTER:
                c.PostCondition = Gate.ComposeAND(c.PostCondition, tg.PostCondition);
                break;

            default:
                throw new ArgumentException("invalid guard type.");
            }

            Log.TraceGuard(c.PreCondition, c.PostCondition, "before join");

            if (!TraceFlags.DisableTriggerJoin)
            {
                // express postconditions by preconditions
                c.JoinTrigger(tg.Trigger);
            }

            Log.TraceGuard(c.PreCondition, c.PostCondition, "add guard");

            // and add to entry
            entry.Add(c);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Associates a trigger with corresponding guards.
        /// </summary>
        /// <param name="trigger">The trigger to associate.</param>
        private void CalculateTriggerDependencies(ProductTrigger trigger)
        {
            var ct = trigger.PreCondition;
            var gtpost = trigger.PostCondition;
            var gtpre = ct;
            TraceDependencies("trigger '{0}' conditions [{1}, {2}] ...", trigger.Name, gtpre, gtpost);

            if (!trigger.ModifiedVariables.Any())
            {
                TraceDependencies("  does not modify state.");
                return;
            }

            foreach (var guard in Guards)
            {
                var gg = guard.PreCondition;
                TraceDependencies("  guard '{0}' precondition [{1}] ...", guard.Name, gg);

                var tg = new TriggerGuard(trigger, guard);

                if (guard.Transitions.Any())
                {
                    TraceDependencies("    state change guard ...");
                    if (!guard.ModifiedVariables.Intersect(trigger.ModifiedVariables).Any())
                    {
                        TraceDependencies("    no affected variable.");
                        continue;
                    }

                    var gatepre = Gate.ComposeAND(gtpre, gg);
                    if (gatepre.Type == GateType.Fixed)
                    {
                        TraceDependencies("    precondition does not match.");
                        continue;
                    }

                    var gatepost = Gate.ComposeAND(gtpost, guard.PostCondition);
                    if (gatepost.Type == GateType.Fixed)
                    {
                        TraceDependencies("    postcondition does not match.");
                        continue;
                    }

                    TraceDependencies("    combination ({0}, {1}) handler.", gatepre, gatepost);

                    tg.PreCondition = gatepre;
                    tg.PostCondition = gatepost;
                }
                else
                {
                    TraceDependencies("    static condition [{0}] ...", gg);

                    Debug.Assert(guard.PreCondition.ID == guard.PostCondition.ID);

                    IGate genter, gleave;

                    if (guard.Type == GuardType.ENTER)
                    {
                        // PRE[trigger] AND NOT POST[guard]
                        // trigger condition met, guard condition not met
                        genter = Gate.ComposeAND(trigger.PreCondition, Gate.Invert(guard.PreCondition));

                        // PRE[trigger] AND PRE[guard]
                        // trigger condition met, guard conditon not met
                        gleave = Gate.ComposeAND(trigger.PostCondition, guard.PostCondition);
                    }
                    else
                    {
                        genter = Gate.ComposeAND(trigger.PreCondition, guard.PreCondition);
                        gleave = Gate.ComposeAND(trigger.PostCondition, Gate.Invert(guard.PostCondition));
                    }

                    var tgenter = genter;
                    var tgleave = gleave;

                    Gate.TraceDependencies(genter, gleave, "guard product");

                    // set all factors not appearing in the trigger to 1
                    genter = ReplaceTransitionVariables(trigger.Transitions, genter, true);
                    gleave = ReplaceTransitionVariables(trigger.Transitions, gleave, true);

                    Gate.TraceDependencies(genter, gleave, "inter product");

                    // set all factors not appearing in the guard to 1
                    genter = ReplaceNonGuardVariables(genter, guard);
                    gleave = ReplaceNonGuardVariables(gleave, guard);
                    /*genter = ReplaceTransitionVariables(guard.Transitions, genter, true);
                    gleave = ReplaceTransitionVariables(guard.Transitions, gleave, true);*/

                    Gate.TraceDependencies(genter, gleave, "guard match");

                    //if (genter is FalseGate || gleave is FalseGate)
                    if (genter.Type.IsFixed() || gleave.Type.IsFixed())
                    {
                        TraceDependencies("    condition does not match.");
                        continue;
                    }

                    /*tg.PreCondition = guard.PreCondition;
                    tg.PostCondition = guard.PostCondition;*/
                    tg.PreCondition = tgenter;
                    tg.PostCondition = tgleave;

                    Gate.TraceDependencies(tgenter, tgleave, "guard conditions");

                    // see if the transition set is non-empty
                    var transx = trigger.Transitions.Match(genter, gleave).ToArray();
                    if (transx.Length > 0)
                    {
                        if (guard.Type == GuardType.ENTER)
                        {
                            TraceDependencies("    entry handler.");
                        }
                        else if (guard.Type == GuardType.LEAVE)
                        {
                            TraceDependencies("    exit handler.");
                        }
                        else
                        {
                            throw new InvalidOperationException("unexpected guard type.");
                        }
                    }
                    else
                    {
                        TraceDependencies("    transition does not match.");
                        continue;
                    }
                }

                // associate the trigger with the guard and vice versa
                trigger.AddGuard(tg);
            }
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Associates a guard object with this trigger.
 /// </summary>
 /// <param name="g"></param>
 public void AddGuard(TriggerGuard g)
 {
     _guards.Add(g);
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Associates a guard object with this trigger.
 /// </summary>
 /// <param name="g"></param>
 public void AddGuard(TriggerGuard g)
 {
     _guards.Add(g);
 }