/// <summary> /// Pops this context. Must have been preceded by a <see cref="SetAsActive"/> call. /// </summary> public void ClearAsActive() { if (InterpretationContext.currentContext == this && InterpretationContext.contextStack.Count > 0) { InterpretationContext.currentContext = InterpretationContext.contextStack.First.Value; InterpretationContext.contextStack.RemoveFirst(); } else { throw new InvalidOperationException("Mismatched SetAsActive()/ClearAsActive() invocations"); } }
/// <summary> /// Increment the instance counter for this sort. /// </summary> /// <returns>The incremented count</returns> public static int GetNextId(Symbol sort) { if (sort == null) { throw new ArgumentNullException("sort"); } int newId = PeekNextId(sort); InterpretationContext.GetCurrentContext().ResetId(sort, newId); return(newId); }
/// <summary> /// Return the next available instance counter for this type and sort (without changing state). /// </summary> /// <note>This is used by parameter generation when a new instance may appear as an action argument.</note> /// <returns>The incremented count</returns> public static int PeekNextId(Symbol sort) { if (sort == null) { throw new ArgumentNullException("sort"); } int newId; return((InterpretationContext.GetCurrentContext().IdPool.TryGetValue(sort, out newId)) ? newId + 1 : 1); }
public override CompoundTerm DoStep(InterpretationContext c, CompoundTerm action) { // Result of invocation must be a value term (must support IComparable) IComparable/*?*/ thisArg; IComparable/*?*/[] methodArgs = this.ConvertTermArgumentsToMethodArguments(c, action.Arguments, out thisArg); foreach (IComparable/*?*/ o in methodArgs) AbstractValue.FinalizeImport(o); object/*?*/ resultObj = this.method.methodInfo.Invoke(thisArg, methodArgs); CompoundTerm/*?*/ finishAction = null; // Handle output args and return value if (null != this.finishActionMethod) { int nOutputs = this.finishActionMethod.actionLabel.Arguments.Count; Sequence<Term> outputs = Sequence<Term>.EmptySequence; for (int i = 0; i < nOutputs; i += 1) { int outputArgIndex = this.finishActionMethod.outputArgumentIndices[i]; if (-2 == outputArgIndex) // "any" placeholder outputs = outputs.AddLast(Any.Value); else { object output = (-1 == outputArgIndex ? resultObj : methodArgs[outputArgIndex]); IComparable outputAsComparable; if (null == output) outputAsComparable = null; else { outputAsComparable = output as IComparable; if (null == outputAsComparable) throw new InvalidOperationException(MessageStrings.LocalizedFormat(MessageStrings.ComparableResultRequired, action.ToString(), output.ToString())); } outputs = outputs.AddLast(AbstractValue.GetTerm(outputAsComparable)); } } finishAction = new CompoundTerm(this.FinishAction, outputs); } return finishAction; }
internal override IEnumerable<string> GetEnablingConditionDescriptions(InterpretationContext c, Sequence<Term> args, bool returnFailures) { IComparable/*?*/ thisArg = null; IComparable[] methodArgs = ConvertTermArgumentsToMethodArguments(c, args, out thisArg); return this.method.GetEnablingConditionDescriptions(c, thisArg, methodArgs, returnFailures); }
internal bool Holds(InterpretationContext c, Set<IComparable> domain) { c.SetAsActive(); try { //check each predicate foreach (Predicate pred in predicates) { if (pred.isStatic) { if (!((bool)pred.method.Invoke(null, new object[0]))) return false; } else { // if instance-based, check predicate for each instance in domain foreach (IComparable obj in domain) { if (!((bool)pred.method.Invoke(obj, new object[0]))) return false; } } } return true; } finally { c.ClearAsActive(); } }
/// <summary> /// Called internally to distinguish between reserve elements that are part of state and /// those in the background set of values. Not used directly in models. /// </summary> public override void FinalizeImport() { InterpretationContext.GetCurrentContext().EnsureId(this.objectId); }
/// <summary> /// Pushes this context as the active context for LabeledInstance creation. Must be paired with a /// <see cref="ClearAsActive"/> call. /// </summary> public void SetAsActive() { InterpretationContext.contextStack.AddFirst(InterpretationContext.currentContext); InterpretationContext.currentContext = this; this.coveragePoints = Bag<Term>.EmptyBag; }
internal abstract bool IsPotentiallyEnabled(InterpretationContext c);
internal abstract IEnumerable<string> GetEnablingConditionDescriptions(InterpretationContext c, Sequence<Term> args, bool returnFailures);
/*?*/ IComparable[] ConvertTermArgumentsToMethodArguments(InterpretationContext c, Sequence<Term> termArguments, out IComparable thisArg) { int nMethodArgs = this.method.parameterInfos.Length; IComparable/*?*/[] methodArgs = new IComparable[nMethodArgs]; thisArg = null; int k = 0; int nParametersUsed = this.inputArgumentIndices.Length; foreach (Term arg in termArguments) { if (k >= nParametersUsed) break; int methodArgIndex = this.inputArgumentIndices[k++]; IComparable argInterpretation = c.InterpretTerm(arg); // convert from term to .NET runtime object if (-1 == methodArgIndex) thisArg = argInterpretation; else if (methodArgIndex >= 0) methodArgs[methodArgIndex] = argInterpretation; } return methodArgs; }
internal IEnumerable<string> GetEnablingConditionDescriptions(InterpretationContext c, IComparable/*?*/ thisArg, IComparable[]/*?*/ arguments, bool returnFailures) { foreach (string s in parameterlessEnablingCondition.GetEnablingConditionDescriptions(c, null, null, returnFailures)) yield return s; foreach (string s in enablingCondition.GetEnablingConditionDescriptions(c, thisArg, arguments, returnFailures)) yield return s; }
public bool IsEnabled(InterpretationContext c, Sequence<Term> args) { foreach (ActionMethod am in this.actionMethods) if (!am.IsEnabled(c, args)) return false; return true; }
public IEnumerable<string> GetEnablingConditionDescriptions(InterpretationContext c, Sequence<Term> args, bool returnFailures) { foreach (ActionMethod am in this.actionMethods) foreach (string s in am.GetEnablingConditionDescriptions(c, args, returnFailures)) yield return s; }
public bool IsPotentiallyEnabled(InterpretationContext c) { foreach (ActionMethod am in this.actionMethods) if (!am.IsPotentiallyEnabled(c)) return false; return true; }
/// <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; }
static void RegisterModelTypeSorts(InterpretationContext context) { // TODO: implement throw new NotImplementedException(context.ToString()); //// Only include sorts for types attributed with a matching model program //// name, or not attributed with any model program name. (Some types are private //// to a particular model program; some types are shared by all model programs in the assembly.) //if ((modelClassName != null || !hasName) && !ReflectionHelper.IsCompilerGenerated(t)) //{ // Symbol sort = AbstractValue.TypeSort(t); // context.RegisterSortType(sort, t); //} }
internal override bool IsEnabled(InterpretationContext c, Sequence<Term> args) { IComparable/*?*/ thisArg = null; IComparable[] methodArgs = ConvertTermArgumentsToMethodArguments(c, args, out thisArg); return this.method.IsEnabled(c, thisArg, methodArgs); }
internal override bool IsPotentiallyEnabled(InterpretationContext c) { return this.method.IsPotentiallyEnabled(c); }
internal bool IsEnabled(InterpretationContext c, IComparable/*?*/ thisArg, IComparable[] args) { return enablingCondition.Holds(c, thisArg, args); }
internal bool IsPotentiallyEnabled(InterpretationContext c) { bool res = parameterlessEnablingCondition.Holds(c, null, null); return res; }
internal IEnumerable<string> GetEnablingConditionDescriptions(InterpretationContext c, IComparable/*?*/ thisArg, IComparable[]/*?*/ arguments, bool returnFailures) { foreach (Predicate pred in predicates) { c.SetAsActive(); try { bool holds = pred.Holds(thisArg, arguments); if ((returnFailures && !holds) || (!returnFailures && holds)) foreach (string s in pred.description) yield return s; } finally { c.ClearAsActive(); } } }
internal abstract bool IsEnabled(InterpretationContext c, Sequence<Term> args);
/// <summary> /// Pushes this context as the active context for LabeledInstance creation. Must be paired with a /// <see cref="ClearAsActive"/> call. /// </summary> public void SetAsActive() { InterpretationContext.contextStack.AddFirst(InterpretationContext.currentContext); InterpretationContext.currentContext = this; this.coveragePoints = Bag <Term> .EmptyBag; }
public abstract CompoundTerm DoStep(InterpretationContext c, CompoundTerm action);
//static private bool ContainsAnyValue(object/*?*/[] arguments) //{ // for (int i = 0; i < arguments.Length; i++) // { // if (arguments[i] == Any.Value) return true; // } // return false; //} internal bool Holds(InterpretationContext c, IComparable/*?*/ thisArg, IComparable[]/*?*/ arguments) { c.SetAsActive(); try { //check each predicate foreach (Predicate pred in predicates) if (!pred.Holds(thisArg, arguments)) return false; return true; } finally { c.ClearAsActive(); } }
/// <summary> /// Returns the interpretation of the term <paramref name="t"/> in the current context. /// </summary> /// <param name="t"></param> /// <returns></returns> public static IComparable InterpretTerm(Term t) { return(InterpretationContext.GetCurrentContext().InterpretTerm(t)); }