/// <summary> /// Produces the target state that results from invoking <paramref name="action"/> /// in the context of <paramref name="startState"/>. /// </summary> /// <param name="startState">The state in which the action is invoked</param> /// <param name="action">The action to be invoked</param> /// <param name="transitionPropertyNames">The names of meta-properties to be collected /// during the calculation of the step.</param> /// <param name="transitionProperties">Output parameter that will contain a /// map of property names to property values. Each property value multiset of /// terms. For example, the property value might be the value of a Boolean function /// that controls state filtering. Or, it might correspond to the "coverage" of the model that results from this /// step. In this case, the value might denote the line numbers or blocks of the /// model program that were exercised in this step, or a projection of the state /// space or a reference to section numbers of a requirements document to indicate /// that the functionality defined by that section was exercised.</param> /// <returns>The state that results from the invocation of <paramref name="action"/> /// in <paramref name="startState"/>.</returns> /// <seealso cref="GetTransitionPropertyNames"/> public override IState GetTargetState(IState startState, CompoundTerm action, Set <string> transitionPropertyNames, out TransitionProperties transitionProperties) { // it is assumed that the action is enabled in the given state PairState ps = startState as PairState; if (ps == null) { throw new ArgumentException("Unexpected type-- expected PairState"); } Symbol actionSymbol = action.Symbol; if (!this.signature.Contains(actionSymbol)) { throw new ArgumentException("Invalid argument-- action symbol " + actionSymbol.ToString() + " not in signature."); } bool doM1 = this.signature.IsShared(actionSymbol) || this.signature.IsOnlyInM1(actionSymbol); bool doM2 = this.signature.IsShared(actionSymbol) || this.signature.IsOnlyInM2(actionSymbol); TransitionProperties m1TransitionProperties = new TransitionProperties(); TransitionProperties m2TransitionProperties = new TransitionProperties(); IState targetState1 = doM1 ? m1.GetTargetState(M1Reduct(ps), action, transitionPropertyNames, out m1TransitionProperties) : M1Reduct(ps); IState targetState2 = doM2 ? m2.GetTargetState(M2Reduct(ps), action, transitionPropertyNames, out m2TransitionProperties) : M2Reduct(ps); transitionProperties = m1TransitionProperties.Union(m2TransitionProperties); return(PairState.CreateState(targetState1, targetState2)); }
/// <summary> /// Gets string descriptions of the enabling conditions /// </summary> /// <param name="state">The state in which the </param> /// <param name="action">The action whose enabling conditions will queried</param> /// <param name="returnFailures">If <c>true</c>, enabling conditions that fail in state /// <paramref name="state"/> will be returned. If <c>false</c>, all enabling conditions /// that are satisfied will be returned.</param> /// <returns>An array of description strings for the enabling conditions of action <paramref name="action"/></returns> public override IEnumerable <string> GetEnablingConditionDescriptions(IState state, CompoundTerm action, bool returnFailures) { PairState ps = state as PairState; if (ps == null) { throw new ArgumentException("Unexpected type-- expected PairState"); } Symbol actionSymbol = action.Symbol; if (m1.ActionSymbols().Contains(actionSymbol)) { foreach (string s in m1.GetEnablingConditionDescriptions(M1Reduct(ps), action, returnFailures)) { yield return(s); } } if (m2.ActionSymbols().Contains(actionSymbol)) { foreach (string s in m2.GetEnablingConditionDescriptions(M2Reduct(ps), action, returnFailures)) { yield return(s); } } }
/// <summary> /// Returns true if the action is enabled in the given state /// </summary> public override bool IsEnabled(IState state, CompoundTerm action) //^ requires IsPotentiallyEnabled(state, action.FunctionSymbol1); { PairState ps = state as PairState; if (ps == null) { throw new ArgumentException("Unexpected type-- expected PairState"); } if (action == null) { throw new ArgumentNullException("action"); } Symbol actionSymbol = action.Symbol; if (this.signature.IsShared(actionSymbol)) { return(m1.IsEnabled(M1Reduct(ps), action) && m2.IsEnabled(M2Reduct(ps), action)); } else if (this.signature.IsOnlyInM1(actionSymbol)) { return(m1.IsEnabled(M1Reduct(ps), action)); } else if (this.signature.IsOnlyInM2(actionSymbol)) { return(m2.IsEnabled(M2Reduct(ps), action)); } else { throw new ArgumentException("Invalid argument-- action symbol " + actionSymbol.ToString() + " not in signature."); } }
/// <summary> /// Checks whether a given action is potentially enabled /// in this state. /// <br><c>requires state != null;</c></br> /// <br>requires state.ModelProgram == this; </br> /// <br>requires actionSymbol != null;</br> /// </summary> public override bool IsPotentiallyEnabled(IState state, Symbol actionSymbol) { PairState ps = state as PairState; if (ps == null) { throw new ArgumentException("Unexpected type-- expected PairState"); } if (!this.signature.Contains(actionSymbol)) { return(false); } IState m1State = M1Reduct(ps); IState m2State = M2Reduct(ps); if (this.signature.IsShared(actionSymbol)) { return (m1.IsPotentiallyEnabled(m1State, actionSymbol) && m2.IsPotentiallyEnabled(m2State, actionSymbol)); } else if (this.signature.IsOnlyInM1(actionSymbol)) { return(m1.IsPotentiallyEnabled(m1State, actionSymbol)); } else { return(m2.IsPotentiallyEnabled(m2State, actionSymbol)); } }
/// <summary> /// Boolean value indicating whether all state filter predicates /// defined by this model program are satisfied by <paramref name="state"/>. /// States not satisfying a state filter are excluded during exploration. /// </summary> /// <param name="state">The state</param> /// <returns>True if <paramref name="state"/>satisfies all state filters of /// this model program; false otherwise.</returns> public override bool SatisfiesStateFilter(IState state) { PairState ps = state as PairState; if (ps == null) { throw new ArgumentException("Unexpected type-- expected PairState"); } return(m1.SatisfiesStateFilter(ps.First) && m2.SatisfiesStateFilter(ps.Second)); }
//public IEnumerable<Step> GetAllSteps(IState state) //{ // PairState ps = state as PairState; // if (ps == null) // throw new ArgumentException("Unexpected type-- expected PairState"); // foreach (Symbol actionSymbol in this.ActionSymbols()) // { // if (IsPotentiallyEnabled(state, actionSymbol)) // foreach(CompoundTerm action in this.GetActions(state, actionSymbol)) // foreach (Step step in this.GetSteps(state, action)) // yield return step; // } //} /// <summary> /// Returns true if all the component states are accepting states /// </summary> public override bool IsAccepting(IState state) { PairState ps = state as PairState; if (ps == null) { throw new ArgumentException("Unexpected type-- expected PairState"); } return(m1.IsAccepting(ps.First) && m2.IsAccepting(ps.Second)); }
/// <summary> /// Does this model program have an interface to parameter generation for this parameter? /// </summary> /// <param name="state"></param> /// <param name="actionSymbol"></param> /// <param name="parameterIndex"></param> /// <returns>A set of terms representing the possible values</returns> public override bool HasActionParameterDomain(IState state, Symbol actionSymbol, int parameterIndex) { PairState ps = state as PairState; if (ps == null) { throw new ArgumentException("Unexpected type-- expected PairState"); } if (!this.signature.Contains(actionSymbol)) { throw new ArgumentException("Unexpected action symbol-- must be in signature"); } bool m1HasDomain = (this.signature.IsShared(actionSymbol) || this.signature.IsOnlyInM1(actionSymbol)); bool m2HasDomain = (this.signature.IsShared(actionSymbol) || this.signature.IsOnlyInM2(actionSymbol)); return((m1HasDomain ? m1.HasActionParameterDomain(M1Reduct(ps), actionSymbol, parameterIndex) : false) || (m2HasDomain ? m2.HasActionParameterDomain(M2Reduct(ps), actionSymbol, parameterIndex) : false)); }
/// <summary> /// Enumerates the action symbols that are potentially enabled with respect to this /// control point and data state. /// </summary> /// <param name="state"></param> /// <returns></returns> public override Set <Symbol> PotentiallyEnabledActionSymbols(IState state) { PairState ps = state as PairState; if (ps == null) { throw new ArgumentException("Unexpected type-- expected PairState"); } Set <Symbol> res = Set <Symbol> .EmptySet; foreach (Symbol actionSymbol in this.signature.actionSymbols) { if (this.IsPotentiallyEnabled(ps, actionSymbol)) { res = res.Add(actionSymbol); } } return(res); }
/// <summary> /// Get the value domain of the given action parameter in the given state /// </summary> public override Set <Term> ActionParameterDomain(IState state, Symbol actionSymbol, int parameterIndex) { PairState ps = state as PairState; if (ps == null) { throw new ArgumentException("Unexpected type-- expected PairState"); } if (!this.signature.Contains(actionSymbol)) { throw new ArgumentException("Unexpected action symbol-- must be in signature"); } // TO DO: include case where no parameter domain is present (as opposed to case where Any is specified) bool m1HasDomain = (this.signature.IsShared(actionSymbol) || this.signature.IsOnlyInM1(actionSymbol)); bool m2HasDomain = (this.signature.IsShared(actionSymbol) || this.signature.IsOnlyInM2(actionSymbol)); m1HasDomain = m1HasDomain && (m1.ActionArity(actionSymbol) > parameterIndex) && m1.HasActionParameterDomain(M1Reduct(ps), actionSymbol, parameterIndex); m2HasDomain = m2HasDomain && (m2.ActionArity(actionSymbol) > parameterIndex) && m2.HasActionParameterDomain(M2Reduct(ps), actionSymbol, parameterIndex); Set <Term> d1 = m1HasDomain ? m1.ActionParameterDomain(M1Reduct(ps), actionSymbol, parameterIndex) : AnyDomain; Set <Term> d2 = m2HasDomain ? m2.ActionParameterDomain(M2Reduct(ps), actionSymbol, parameterIndex) : AnyDomain; if (d1.Equals(AnyDomain)) { return(d2); } else if (d2.Equals(AnyDomain)) { return(d1); } else { return(d1.Intersect(d2)); } }
static IState M2Reduct(PairState productState) { return(productState.Second); }
static IState M1Reduct(PairState productState) { return(productState.First); }
/// <summary> /// Gets all enabled actions in the given state that have the given action symbol /// </summary> /// <param name="state"></param> /// <param name="actionSymbol"></param> /// <returns></returns> public override IEnumerable <CompoundTerm> GetActions(IState state, Symbol actionSymbol) { PairState ps = state as PairState; if (ps == null) { throw new ArgumentException("Unexpected type-- expected PairState"); } if (actionSymbol == null) { throw new ArgumentNullException("actionSymbol"); } if (this.signature.IsOnlyInM1(actionSymbol)) { IState M1State = M1Reduct(ps); foreach (CompoundTerm a in m1.GetActions(M1State, actionSymbol)) { yield return(a); } } else if (this.signature.IsOnlyInM2(actionSymbol)) { IState M2State = M2Reduct(ps); foreach (CompoundTerm a in m2.GetActions(M2State, actionSymbol)) { yield return(a); } } else if (this.signature.IsShared(actionSymbol)) { IState m1State = M1Reduct(ps); IState m2State = M2Reduct(ps); int arity = this.ActionArity(actionSymbol); if (arity > 0) { Sequence <Set <Term> > args = Sequence <Set <Term> > .EmptySequence; for (int i = 0; i < arity; i++) { args = args.AddLast(this.ActionParameterDomain(state, actionSymbol, i)); } IEnumerable <Sequence <Term> > cartesianProduct = CartesianProduct(args); foreach (Sequence <Term> arglist in cartesianProduct) { CompoundTerm action = new CompoundTerm(actionSymbol, arglist); if (m1.IsEnabled(m1State, action) && m2.IsEnabled(m2State, action)) { yield return(action); } } } else { CompoundTerm action = new CompoundTerm(actionSymbol, Sequence <Term> .EmptySequence); if (m1.IsEnabled(m1State, action) && m2.IsEnabled(m2State, action)) { yield return(action); } } } else { throw new ArgumentException("Invalid argument-- action symbol " + actionSymbol.ToString() + " not in signature."); } }