Esempio n. 1
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);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Combines this trigger condition with the preconditions of a product trigger.
        /// </summary>
        /// <param name="trigger"></param>
        /// <remarks>
        /// <para>This eliminates the post-condition.</para></remarks>
        public void JoinTrigger(ProductTrigger trigger)
        {
            var tset = trigger.Transitions;

            Log.TraceGuard("join trigger: " + tset.ToDebugString());

            // express the postcondition by precondition factors
            var postfrompre = PostCondition.Replace(e =>
            {
                var vc = e as IVariableCondition;
                if (null != vc)
                {
                    if (tset.Contains(vc.Variable))
                    {
                        // express variable by preconditions
                        e = tset.InferPostState(vc.Variable, vc.StateIndex);

                        Log.TraceGuard(vc.Decompose(), e, "ss");
                    }
                    else if (trigger.Event.Transitions.Contains(vc.Variable))
                    {
                        // variable unchanged but affected by trigger, keep post condition
                        e = Gate.Constant(true);
                    }
                    else
                    {
                        // if not in event tset, move to precondition
                    }
                }

                return e;
            }).Simplify();

            var postreduced = PostCondition.Replace(e =>
            {
                var vc = e as IVariableCondition;
                if (null != vc)
                {
                    if (tset.Contains(vc.Variable))
                    {
                        // express variable by preconditions
                        e = Gate.Constant(true);
                    }
                    else if (trigger.Event.Transitions.Contains(vc.Variable))
                    {
                        // keep
                    }
                    else
                    {
                        // move before
                        e = Gate.Constant(true);
                    }
                }

                return e;
            }).Simplify();

            Log.TraceGuard(PostCondition, postfrompre, "post from pre");

            // move post condition into precondition for evalulation
            PreCondition = Gate.ComposeAND(PreCondition, postfrompre);

            Log.TraceGuard(PostCondition, postreduced, "reduced post");

            // post condition void
            PostCondition = postreduced;
        }
Esempio n. 3
0
 public TriggerGuard(ProductTrigger t, Guard g)
 {
     Trigger = t;
     Guard = g;
 }
Esempio n. 4
0
 public TriggerGuard(ProductTrigger t, Guard g)
 {
     Trigger = t;
     Guard   = g;
 }