readonly Symbol[] parameterSorts; // the "sort" (abstract type) of each parameter #endregion Fields #region Constructors public ActionInfo(int arity, Symbol[] parameterSorts, ActionKind kind, List<ActionMethod> actionMethods) { this.arity = arity; this.parameterSorts = parameterSorts; this.kind = kind; this.actionMethods = actionMethods; }
public static FSM GenerateTestSequenceAutomaton(string testcaseName, Sequence<Sequence<CompoundTerm>> testseqs, Set<Symbol> actionSymbols) { Set<Term> acceptingStates = Set<Term>.EmptySet; Set<Term> states = Set<Term>.EmptySet; Symbol testCaseActionSymbol = new Symbol(testcaseName); Literal initialState = new Literal(0); states = states.Add(initialState); #region generate transitions and accepting states Set<Triple<Term, CompoundTerm, Term>> transitions = Set<Triple<Term, CompoundTerm, Term>>.EmptySet; for (int i = 0; i < testseqs.Count; i++) { //the i'th test sequence start action CompoundTerm startTestAction = new CompoundTerm(testCaseActionSymbol, new Sequence<Term>(new Literal(i))); transitions = transitions.Add(new Triple<Term, CompoundTerm, Term>( initialState,startTestAction, IntermediateState.State(i,0))); Sequence<CompoundTerm> testseq = testseqs[i]; //the final step state of the i'th test sequence is an accepting state acceptingStates = acceptingStates.Add(IntermediateState.State(i, testseq.Count)); states = states.Add(IntermediateState.State(i, testseq.Count)); for (int j = 0; j < testseq.Count; j++) { if (!actionSymbols.Contains(testseq[j].Symbol)) throw new ArgumentException("Not all action symbols in test sequences appear in actionSymbols", "actionSymbols"); states = states.Add(IntermediateState.State(i, j)); transitions = transitions.Add(new Triple<Term, CompoundTerm, Term>( IntermediateState.State(i, j), testseq[j], IntermediateState.State(i, j + 1))); } } #endregion return new FSM(initialState, states, transitions, acceptingStates, actionSymbols.Add(testCaseActionSymbol)); }
///// <summary> ///// Accesses the mapping of .NET types to sorts (abstract types used to connect model programs). This ///// is part of runtime context because two model programs may choose different .NET types for the same sort. ///// This mapping is used when printing the term representation of a runtime value. ///// </summary> ///// <param name="t">The .NET type</param> ///// <param name="sort">The associated sort, if found</param> ///// <returns>True if an association of type-to-sort was found. See also <see cref="RegisterSortType"/>.</returns> //public bool TypeSortTryGetValue(Type t, out Symbol/*?*/ sort) //{ // return typeSort.TryGetValue(t, out sort); //} /// <summary> /// Initializes this context with a (sort, type) pair. /// </summary> /// <param name="sort">The sort associated with <paramref name="t"/></param> /// <param name="t">The .NET type associated with <paramref name="sort"/></param> public void RegisterSortType(Symbol sort, Type t) { if (sortType.ContainsKey(sort)) { if (!sortType[sort].Equals(t)) throw new InvalidOperationException("Sort " + sort.ToString() + " has already been registered in this context with a different type: " + t.ToString()+"."); } else { sortType.Add(sort, t); Console.Out.WriteLine("Added sort: " + t.ToString()); } }
internal IEnumerable<CompoundTerm> GetEnabledActions(Node node, Symbol actionSymbol) { IState istate = stateMap[node]; return modelProgram.GetActions(istate, actionSymbol); }
public Parameter(FsmState state, Symbol actionSymbol, int index) { this.state = state; this.actionSymbol = actionSymbol; this.index = index; }
/// <summary> /// Checks whether a sort is an abstract type. The corresponding set is created once in the constructor. /// </summary> /// <param name="s">A symbol denoting a sort (i.e. abstract type)</param> /// <returns>Returns always false for <see cref="FsmModelProgram"/></returns> public override bool IsSortAbstract(Symbol s) { return false; }
/// <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) { FsmState fs = state as FsmState; if (fs == null) throw new ArgumentException("Invalid state"); if (!this.ActionSymbols().Contains(actionSymbol)) throw new ArithmeticException("Symbol " + actionSymbol.ToString() + "not in signature."); if (parameterIndex >= ActionArity(actionSymbol)) return false; Parameter p = new Parameter(fs, actionSymbol, parameterIndex); Set<Term> domain; if (!parameterDomains.TryGetValue(p, out domain)) { domain = Set<Term>.EmptySet; foreach (Term automatonState in fs.AutomatonStates) domain = domain.Union(GetAutomatonParameterDomain(automatonState, actionSymbol, parameterIndex)); this.parameterDomains[p] = domain; } // return parameterDomains.ContainsKey(p); return !domain.IsEmpty; }
/// <summary> /// Gets the sort (i.e., abstract type) of the ith parameter of action <paramref name="actionSymbol"/> /// <br><c>requires actionSymbol != null;</c></br> /// <br><c>requires this.ActionSymbols.Contains(actionSymbol);</c></br> /// </summary> /// <param name="actionSymbol">A symbol naming an action of this model program.</param> /// <param name="parameterIndex">An integer in the interval [0, this.ActionArity(actionSymbol))</param> /// <returns>The sort (abstract type) of the ith parameter of action <paramref name="actionSymbol"/></returns> public override Symbol ActionParameterSort(Symbol actionSymbol, int parameterIndex) { return AnySort; }
/// <summary> /// Constructs an action for a given action symbol and a params array of arguments. /// </summary> /// <param name="f">action symbol</param> /// <param name="args">arguments of the action</param> public Action(Symbol f, params Term[] args) : base(f, args) { }
/// <summary> /// Create an instance of LibraryModelProgram for a given assembly /// </summary> /// <param name="modAssembly">Loaded assembly</param> /// <param name="modelName">Name of the model namespace to be loaded. /// Only classes in the model namespace will be loaded.</param> /// <param name="featureNames">The names of features to be loaded. If null, all /// features will be loaded for the given modelName. See <see cref="FeatureAttribute"/>.</param> /// <exception cref="ModelProgramUserException">Thrown if there is a usage error in the given assembly.</exception> public LibraryModelProgram(Assembly modAssembly, string modelName, Set<string>/*?*/ featureNames) { if (string.IsNullOrEmpty(modelName)) throw new ArgumentNullException("modelName"); InterpretationContext context = (null == featureNames ? new InterpretationContext() : new InterpretationContext(featureNames)); Type/*?*/[]/*?*/ allTypes = modAssembly.GetTypes(); List<Field> stateVars = new List<Field>(); Dictionary<Symbol, ActionInfo> aInfoMap = new Dictionary<Symbol, ActionInfo>(); Dictionary<Type, StatePredicate> acceptingStateConditions = new Dictionary<Type, StatePredicate>(); Dictionary<Type, StatePredicate> stateInvariants = new Dictionary<Type, StatePredicate>(); Dictionary<Type, StatePredicate> stateFilters = new Dictionary<Type, StatePredicate>(); //Dictionary<Type, TransitionPropertyGenerator> transitionPropertyGenerators = new Dictionary<Type, TransitionPropertyGenerator>(); bool modelIsEmpty = true; #region Get state variables, actions, invariants, accepting state conditions, and state filters abstractSorts = new Set<Symbol>(); foreach (Type t in allTypes) { try { // ignore any compiler-generated types, such as iterators. if (ReflectionHelper.IsCompilerGenerated(t)) continue; // Collect state variables, actions, invariants and accepting state conditions. if (ReflectionHelper.IsInModel(t, modelName, featureNames)) { // Register the sort for this type context.RegisterSortType(AbstractValue.TypeSort(t), t); // Check if the sort is abstract if (AbstractValue.IsTypeAbstractSort(t)) abstractSorts=abstractSorts.Add(AbstractValue.TypeSort(t)); // Only extract variables and actions from class types. if (!t.IsClass) continue; // clear flag that detects model namespace spelling errors modelIsEmpty = false; // Collect state variables foreach (FieldInfo field in ReflectionHelper.GetModelVariables(t)) stateVars.Add(new Field(field)); Set<string> actionMethodNames = Set<string>.EmptySet; // used to detect duplicates // Collect actions foreach (MethodInfo methodInfo in ReflectionHelper.GetMethodsForActions(t)) { try { if (actionMethodNames.Contains(methodInfo.Name)) throw new ModelProgramUserException("Duplicate action method name '" + methodInfo.Name + "' found. Action methods may not use overloaded names."); if (!methodInfo.IsStatic) { //check that the the declaring class is a labeled instance //or else say that probably the static keyword is missing if (methodInfo.DeclaringType.BaseType == null || methodInfo.DeclaringType.BaseType.Name != "LabeledInstance`1" || methodInfo.DeclaringType.BaseType.GetGenericArguments()[0] != methodInfo.DeclaringType) throw new ModelProgramUserException("Since the action method '" + methodInfo.Name + "' is non-static, the class '" + methodInfo.DeclaringType.Name + "' must directly inherit from 'LabeledInstance<" + methodInfo.DeclaringType.Name + ">'." + "\nDid you perhaps forget to declare the method 'static'?"); } //check that the action parameter types are valid modeling types foreach (ParameterInfo pInfo in methodInfo.GetParameters()) if (!(pInfo.ParameterType.IsPrimitive || pInfo.ParameterType.IsEnum || pInfo.ParameterType == typeof(string) || ReflectionHelper.ImplementsIAbstractValue(pInfo.ParameterType))) throw new ModelProgramUserException( "\nThe parameter '" + pInfo.Name + "' of '" + methodInfo.Name + "' does not a have valid modeling type. " + "\nA valid modeling type is either: a primitive type, an enum, a string, or a type that implements 'NModel.Internals.IAbstractValue'." + "\nIn particular, collection types in 'System.Collections' and 'System.Collections.Generic' are not valid modeling types." + "\nValid modeling types are collection types like 'Set' and 'Map' defined in the 'NModel' namespace, " + "\nas well as user defined types that derive from 'CompoundValue'."); actionMethodNames = actionMethodNames.Add(methodInfo.Name); Method method = new Method(methodInfo); #region RequirementsMetrics2 // Requirements metrics // methodInfo is only actions // Collect the requirements from the enabling-actions below (after this loop) if (!allModeledRequirements.ContainsKey(methodInfo.Name)) allModeledRequirements = allModeledRequirements.Add(methodInfo.Name, ReflectionHelper.GetRequirementsInMethod(methodInfo)); // Collect the requirements from the enabling-actions foreach (MethodInfo enablingMethodInfo in ReflectionHelper.GetEnablingMethods(methodInfo)) { if (!allModeledRequirements.ContainsKey(enablingMethodInfo.Name)) { Set<Pair<string, string>> requirements = new Set<Pair<string, string>> (ReflectionHelper.GetEnablingMethodsRequirements(enablingMethodInfo)); allModeledRequirements = allModeledRequirements.Add(enablingMethodInfo.Name, requirements); } } #endregion foreach (ActionAttribute actionAttribute in ReflectionHelper.GetModelActionAttributes(methodInfo)) { CompoundTerm/*?*/ startActionLabel; CompoundTerm/*?*/ finishActionLabel; ReflectionHelper.GetActionLabel(methodInfo, actionAttribute, out startActionLabel, out finishActionLabel); ActionMethodFinish/*?*/ finishActionMethod = null; if (finishActionLabel != null) { finishActionMethod = InsertActionMethodFinish(method, finishActionLabel, aInfoMap); } if (startActionLabel != null) { InsertActionMethodStart(method, startActionLabel, finishActionMethod, aInfoMap); } } } catch (ModelProgramUserException e) { string msg = "method " + methodInfo.Name + ", " + e.Message; throw new ModelProgramUserException(msg); } } // to do: collect transition properties // Collect state invariants //StatePredicate sp1 = StatePredicate.GetPredicates(t, GetStateInvariantMethodNames(t)); //if (null != sp1) // stateInvariants.Add(t, sp1); // Collect accepting state conditions StatePredicate sp2 = StatePredicate.GetAcceptingStateCondition(t); if (null != sp2) acceptingStateConditions.Add(t, sp2); // Collect state invariants StatePredicate sp3 = StatePredicate.GetStateInvariant(t); if (null != sp3) stateInvariants.Add(t, sp3); //collect state filters StatePredicate sp4 = StatePredicate.GetStateFilter(t); if (null != sp4) stateFilters.Add(t, sp4); } } catch (ModelProgramUserException e) { string msg = "In class " + t.Name + ", " + e.Message; throw new ModelProgramUserException(msg); } } if (modelIsEmpty) throw new ModelProgramUserException("No classes found in model namespace " + modelName + ". Did you misspell?"); #endregion // todo: Collect "sorts" for each type. Walk type tree of state variables and // action arguments to do this. Symbol[] aSymbols = new Symbol[aInfoMap.Keys.Count]; int j = 0; foreach (Symbol a in aInfoMap.Keys) aSymbols[j++] = a; Field[] sFields = stateVars.ToArray(); StateVariable[] sVars = new StateVariable[sFields.Length]; string[] lNames = new string[sVars.Length]; ValueArray<string> locNames; for (int i = 0; i < sVars.Length; i++) { sVars[i] = sFields[i].stateVariable; lNames[i] = sFields[i].stateVariable.Name; } locNames = new ValueArray<string>(lNames); string nameExt = ""; if (featureNames != null && featureNames.Count > 0) { nameExt += "["; for (int i = 0; i < featureNames.Count; i++) { nameExt += featureNames.Choose(i); if (i < featureNames.Count - 1) nameExt += ","; } nameExt += "]"; } this.name = modelName + nameExt; // this.generator = generator; this.stateFields = sFields; this.locationNames = locNames; this.stateVariables = sVars; this.actionSymbols = new Set<Symbol>(aSymbols); this.actionInfoMap = aInfoMap; this.finishActionSymbols = LibraryModelProgram.CreateStartFinishMap(aInfoMap); this.modelAssembly = modAssembly; this.context = context; this.currentState = GetInitialState(); this.stateChangedPredicate = false; this.acceptingStateConditions = acceptingStateConditions; this.stateInvariants = stateInvariants; this.stateFilters = stateFilters; }
IEnumerable<Sequence<Term>> AllParameterCombinations(IState state, Symbol actionSymbol) { 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)); } return CartesianProduct(args); //} // return Set<Sequence<Term>>.EmptySet; }
//assumes that state has been set internal bool IsPotentiallyEnabled_Internal(IState state, Symbol actionSymbol) { // to do: check to see if current state has continuations; otherwise eval. if (ActionSymbolKind(actionSymbol) == ActionKind.Finish) return false; ActionInfo/*?*/ a; if (this.actionInfoMap.TryGetValue(actionSymbol, out a)) { SetState(state); this.context.SetAsActive(); try { return a.IsPotentiallyEnabled(this.context); } finally { this.context.ClearAsActive(); } } return false; }
/// <summary> /// Checks whether a sort is an abstract type. The corresponding set is created once in the constructor. /// </summary> /// <param name="s">A symbol denoting a sort (i.e. abstract type)</param> /// <returns>true if the sort is abstract, false otherwise.</returns> public override bool IsSortAbstract(Symbol s) { return abstractSorts.Contains(s); }
ValueConstructor GetValueConstructor(Symbol sort, int arity) { ValueConstructor ctor; if (!valueConstructors.TryGetValue(sort, out ctor)) { Type type = this.DefaultSortType(sort); if (type.IsSubclassOf(typeof(LabeledInstance))) { // assert arity == 1; ctor = LabeledInstanceConstructor(type); } else if (type.IsSubclassOf(typeof(System.Enum))) { ctor = delegate(Sequence<IComparable> args1) { return (IComparable)System.Enum.Parse(type, (string) args1.Head); }; } else if (collectionValueType.IsAssignableFrom(type)) { MethodInfo m = type.GetMethod("ConstructValue", BindingFlags.NonPublic | BindingFlags.Static); ctor = delegate(Sequence<IComparable> args1) { object o = m.Invoke(null, new object[] { args1 }); return (IComparable)o; }; return ctor; } else // if (type.IsSubclassOf(typeof(CompoundValue))) { // look for constructor with same number of arguments. ConstructorInfo[] ctorInfos = type.GetConstructors(); if (ctorInfos != null) { foreach (ConstructorInfo ctorInfo in ctorInfos) { ParameterInfo[] paramInfos = ctorInfo.GetParameters(); if ((paramInfos == null && arity == 0) || (paramInfos != null && paramInfos.Length == arity)) { ctor = delegate(Sequence<IComparable> args1) { IComparable[] args = new IComparable[args1.Count]; args1.CopyTo(args, 0); object o = ctorInfo.Invoke(args); return (IComparable)o; }; break; } } } } if (ctor == null) throw new InvalidOperationException("No constructors with arity " +arity+ " found for type " + type.ToString()); valueConstructors[sort] = ctor; } return ctor; }
public bool SortTypeTryGetValue(Symbol sort, out Type/*?*/ t) { return sortType.TryGetValue(sort, out t); }
/// <summary> /// Modifies the current context so that the next object id for <paramref name="sort"/> /// is equal <paramref name="maxIdValue"/> plus 1. This method modifies the current /// model state. /// </summary> /// <param name="sort">The sort (abstract type) to modify</param> /// <param name="maxIdValue">The id of the maximum element</param> public void ResetId(Symbol sort, int maxIdValue) { if (maxIdValue > 0) idPool = idPool.Override(sort, maxIdValue); else if (maxIdValue == 0) idPool = idPool.RemoveKey(sort); else throw new ArgumentOutOfRangeException("maxIdValue"); }
/// <summary> /// Constructs an action for a given action symbol and sequence of arguments. /// </summary> /// <param name="f">action symbol</param> /// <param name="args">arguments of the action</param> public Action(Symbol f, Sequence<Term> args) : base(f, args) { }
/// <summary> /// Number of arguments taken by the action symbol /// </summary> public override int ActionArity(Symbol actionSymbol) { if (null == actionSymbol) throw new ArgumentNullException("actionSymbol"); ActionInfo info; if (actionInfoMap.TryGetValue(actionSymbol, out info)) { return info.Arity; } else { throw new ArgumentException("actionSymbol"); } }
/// <summary> /// Number of arguments associated with action symbol <paramref name="actionSymbol"/> /// <br><c>requires actionSymbol != null;</c></br> /// <br><c>requires this.ActionSymbols.Contains(actionSymbol);</c></br> /// <br><c>ensures result >= 0</c></br> /// </summary> /// <param name="actionSymbol">A symbol naming an action of this model program.</param> /// <returns>The number of arguments required in a <see cref="Term"/> invoking this <paramref name="actionSymbol"/></returns> public override int ActionArity(Symbol actionSymbol) { int arity; if (this.actionArities.TryGetValue(actionSymbol, out arity)) return arity; else throw new ArgumentException("Action symbol " + actionSymbol.ToString() + " not in signature of this model program."); }
/// <summary> /// /// </summary> /// <param name="state"></param> /// <param name="actionSymbol"></param> /// <param name="parameterIndex"></param> /// <returns></returns> public override Set<Term> ActionParameterDomain(IState state, Symbol actionSymbol, int parameterIndex) { // 1- get domain from attr ActionInfo actionInfo; if (!actionInfoMap.TryGetValue(actionSymbol, out actionInfo)) throw new InvalidOperationException(); if (ActionSymbolKind(actionSymbol) == ActionKind.Start || ActionSymbolKind(actionSymbol) == ActionKind.Atomic) { // merge parameter generators of each action method if (0 <= parameterIndex && parameterIndex < actionInfo.Arity) { Set<Term>/*?*/ values = null; SetState(state); this.context.SetAsActive(); try { foreach(ActionMethod am in actionInfo.ActionMethods) { ParameterGenerator/*?*/ parameterGenerator = am.GetParameterGenerator(parameterIndex); if (null != parameterGenerator) { Set<Term> newValues = parameterGenerator(); values = (null == values) ? newValues : IntersectWithAny(values ,newValues); } } } finally { this.context.ClearAsActive(); } if (null == values) throw new ModelProgramUserException("Parameter "+ parameterIndex + " of action '" + actionSymbol + "' does not have a parameter generator." + "\nFor instance based actions, parameter 0 is the implicit 'this' parameter;" + "\nthe generator is added to the class using [Domain(\"new\")] or [Domain(M)] attribute where M is a custom parameter generator."); return values; } else { throw new ArgumentOutOfRangeException("parameterIndex"); } } else { Set<Term> result = Set<Term>.EmptySet; Dictionary<CompoundTerm, IState> stateContinuations; if (this.continuations.TryGetValue(state, out stateContinuations)) { foreach (CompoundTerm action in stateContinuations.Keys) { if (0 <= parameterIndex && parameterIndex < action.Arguments.Count) { result = result.Add(action.Arguments[parameterIndex]); } } } return result; } }
/// <summary> /// Enumerate all the enabled actions with the given symbol in the given state /// </summary> public override IEnumerable<CompoundTerm> GetActions(IState state, Symbol actionSymbol) { FsmState fs = state as FsmState; if (fs == null) throw new ArgumentException("Invalid state"); Set<CompoundTerm> result = Set<CompoundTerm>.EmptySet; foreach (Term automatonState in fs.AutomatonStates) { Set<Transition> outgoing = this.automaton.OutgoingTransitions(automatonState); foreach (Transition t in outgoing) { CompoundTerm ct = t.Second as CompoundTerm; if (ct == null) throw new InvalidOperationException("Internal error"); if (Object.Equals(ct.Symbol, actionSymbol)) result = result.Add(ct); } } return result; }
/// <summary> /// Parameter sort of the given parameter index and given action symbol /// </summary> public override Symbol ActionParameterSort(Symbol actionSymbol, int parameterIndex) { if (null == actionSymbol) throw new ArgumentNullException("actionSymbol"); ActionInfo info; if (actionInfoMap.TryGetValue(actionSymbol, out info)) { if (info.ParameterSorts.Length > parameterIndex) { // TODO: make sure parameterSorts is initialized in the constructor return info.ParameterSorts[parameterIndex]; } else { throw new ArgumentException("parameterIndex"); } } else { throw new ArgumentException("actionSymbol"); } }
/// <summary> /// Returns true if the action symbol is potentially enabled in the given state /// </summary> public override bool IsPotentiallyEnabled(IState state, Symbol actionSymbol) { FsmState fs = state as FsmState; if (fs == null) throw new ArgumentException("Invalid state"); if (!this.ActionSymbols().Contains(actionSymbol)) throw new ArgumentException("Action symbol " + actionSymbol.ToString() + " not in signature."); Set<Symbol> stateActionSymbols; foreach (Term automatonState in fs.AutomatonStates) if (this.potentiallyEnabled.TryGetValue(automatonState, out stateActionSymbols) && stateActionSymbols.Contains(actionSymbol)) return true; return false; }
/// <summary> /// Returns the kind of the action symbol /// </summary> public ActionKind ActionSymbolKind(Symbol actionSymbol) { if (null == actionSymbol) throw new ArgumentNullException("actionSymbol"); if (!this.ActionSymbols().Contains(actionSymbol)) throw new ArgumentException("symbol " + actionSymbol.ToString() + "not found."); ActionInfo aInfo; if (this.actionInfoMap.TryGetValue(actionSymbol, out aInfo)) { return aInfo.Kind; } else throw new ArgumentException("symbol " + actionSymbol.ToString() + " not found."); }
Set<Term> GetAutomatonParameterDomain(Term startState, Symbol actionSymbol, int parameterIndex) { Set<Term> result = Set<Term>.EmptySet; Set<Transition> outgoing = this.automaton.OutgoingTransitions(startState); foreach (Transition transition in outgoing) { CompoundTerm ct = transition.Second as CompoundTerm; if (ct == null || parameterIndex >= ActionArity(actionSymbol)) throw new InvalidOperationException("Internal error"); if (actionSymbol.Equals(ct.Symbol)) result = result.Add(ct.Arguments[parameterIndex]); } return result; }
/// <summary> /// Enumerates all the enabled actions in the given state with the given action symbol. /// </summary> public override IEnumerable<CompoundTerm> GetActions(IState state, Symbol actionSymbol) { // Case 1: ready mode if (state.ControlMode.Equals(readyControlMode)) { if (ActionSymbolKind(actionSymbol) == ActionKind.Finish) yield break; //enumerate over the parameter domains, check //enabling conditions and yield the actions ActionInfo/*?*/ actionMethod; // SetState(state); if (this.IsPotentiallyEnabled_Internal(state, actionSymbol)) // CODE REVIEW: Is this call redundant? Appears to be. { if (this.actionInfoMap.TryGetValue(actionSymbol, out actionMethod)) { //BOOGIE: actionMethod is known to be nonnull at this point if ((/*^(ActionInfo)^*/actionMethod).IsPotentiallyEnabled(this.context)) { foreach (Sequence<Term> args in AllParameterCombinations(state, actionSymbol)) { // State may need to be reset if someone calls GetActions recursively. SetState(state); this.context.SetAsActive(); try { if ((/*^(ActionInfo)^*/actionMethod).IsEnabled(this.context, args)) yield return new CompoundTerm(actionSymbol, args); } finally { this.context.ClearAsActive(); } } } } } } // Case 2: intermediate step. else { Dictionary<CompoundTerm, IState> stateContinuations; if (this.continuations.TryGetValue(state, out stateContinuations)) { foreach (CompoundTerm action in stateContinuations.Keys) yield return action; } else throw new InvalidOperationException("Expected continuation not found"); } }
/// <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) { ActionInfo actionInfo; if (!actionInfoMap.TryGetValue(actionSymbol, out actionInfo)) throw new ArgumentException(); if (ActionSymbolKind(actionSymbol) == ActionKind.Start || ActionSymbolKind(actionSymbol) == ActionKind.Atomic) { if (!(0 <= parameterIndex && parameterIndex < actionInfo.Arity)) return false; // throw new ArgumentOutOfRangeException("parameterIndex"); foreach(ActionMethod am in actionInfo.ActionMethods) if (am.HasActionParameterDomain(parameterIndex)) return true; return false; } else { return true; } }
/// <summary> /// Returns true if the given action symbol is possibly enabled in the given state /// </summary> /// <param name="state"></param> /// <param name="actionSymbol"></param> /// <returns></returns> public override bool IsPotentiallyEnabled(IState state, Symbol actionSymbol) { // Case 1: ready mode if (state.ControlMode.Equals(readyControlMode)) { return IsPotentiallyEnabled_Internal(state, actionSymbol); } // Case 2: intermediate step. else { // to do: handle multiple continuations by checking if actionSymbol // is found in dictionary of continuations. // Temp: just handle start/finish idiom for now if (ActionSymbolKind(actionSymbol) != ActionKind.Finish) return false; CompoundTerm startAction = CurrentStackFrame(state); Symbol startActionSymbol = startAction.Symbol; return ActionSymbolKind(startActionSymbol) == ActionKind.Start && // must be in the middle of an action actionSymbol.Equals(this.finishActionSymbols[startActionSymbol]); // start and finish symbols must match names } }
/// <summary> /// Hide all previously shown transitions with te given action symbol from the given node /// </summary> internal void HideAll(Node node, Symbol actionSymbol) { this.hiddenTransitions = this.hiddenTransitions.Union(this.transitions.Select(delegate(Transition t) { return t.First.Equals(node) && ((CompoundTerm)t.Second).Symbol.Equals(actionSymbol); })); this.transitions = this.transitions.Difference(this.hiddenTransitions); }
/// <summary> /// Returns all of the objects of this instance pool that are relevant in the current context /// </summary> /// <param name="sort"></param> /// <returns></returns> public IEnumerable<IComparable> InstancePoolValues(Symbol sort) { int maxId; if (!idPool.TryGetValue(sort, out maxId)) maxId = -1; Dictionary<ObjectId, LabeledInstance> objPool; if (pool.TryGetValue(sort, out objPool)) foreach (LabeledInstance obj in objPool.Values) if (obj.Label.Id <= maxId) yield return obj; }