private CompoundTerm ChooseAction(Sequence<Action> actions, IState iState) { TransitionProperties tp; int targetId = -1; List<double> MaxV = bdt.ReturnValue(true); List<double> MinV = bdt.ReturnValue(false); List<Set<int>> abstractMap = bdt.ReturnLeaves(); Sequence<Pair<int, Action>> cumulActSum = Sequence<Pair<int, Action>>.EmptySequence; double epsilon = 0.1; Dictionary<int, int> sumTarget = new Dictionary<int, int>(); Action maxAct = null; int targetAbsId = -1; int sum = 0; UpdateRequirementMaps(actions, iState); Set<Action> newStateActs = new Set<Action>(); Set<Action> oldActs = new Set<Action>(actions.Head); foreach (Action a in actions) { int tState = this.modelProgram.GetTargetState(iState, a, null, out tp).GetHashCode(); targetAbsId = findAbstractId(tState, abstractMap); if (targetAbsId == -1) { newStateActs = newStateActs.Add(a); } else { sum = sum + (int)(MaxV[targetAbsId] * Math.Pow(10.0, 9.0)); Pair<int, Action> np = new Pair<int, Action>(sum, a); sumTarget.Add(sum, targetAbsId); cumulActSum = cumulActSum.AddLast(np); } } if (!newStateActs.IsEmpty) { maxAct = newStateActs.Choose(); System.Console.WriteLine("new action in new state " + maxAct.ToString()); return maxAct; } else { Random rndNumbers = new Random(); int rndNumber = rndNumbers.Next(sum); System.Console.WriteLine(sum + " " + rndNumber); foreach (Pair<int, Action> np in cumulActSum) { System.Console.WriteLine(np.First + " " + np.Second.ToString()); if (rndNumber <= np.First) { maxAct = np.Second; targetId = sumTarget[np.First]; break; } targetId = sumTarget[np.First]; maxAct = np.Second; } System.Console.WriteLine("old action in old state " + maxAct.ToString()); } // Adaptive Refinement if (MaxV[targetId] - MinV[targetId] > epsilon) { if (i < requirementProperties.Count) { string s1 = requirementProperties[i++]; bdt = bdt.Refine(s1, requireEnabledStateMap[s1]); bdt.PrintTree(0); } } return maxAct; }
/// <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; }
private CompoundTerm ChooseAction(Sequence<Action> actions, IState iState) { Action maxAct = actions.Head; int sState = iState.GetHashCode(); int tState; IExtendedState iestate = (IExtendedState)iState; int c = iestate.LocationValuesCount; foreach (Action a in actions) foreach (string s in this.modelProgram.GetEnablingConditionDescriptions(iState, a, false)) { Term t = Term.Parse(s); Sequence<Term> vars = (t.Arguments[0].Arguments); Map<Variable, Term> subst = ConstructSubst(a,vars); System.Console.WriteLine(a.ToString() + sState + " enabled string " + t.Arguments[1].Substitute(subst)); } /* for (int i = 0; i < c; i++) { System.Console.WriteLine("name: "+iestate.GetLocationName(i) + " value : "+ iestate.GetLocationValue(i) + " hash" + iestate.GetLocationValue(i).GetHashCode()); CompoundValue t = (CompoundValue)iestate.GetLocationValue(i); foreach (CompoundValue t1 in t.FieldValues()) { System.Console.WriteLine(" field " + t1.ToString()); } } */ TransitionProperties tp; int sum = 0; Sequence<Pair<int, Action>> cumulActSum = Sequence<Pair<int,Action>>.EmptySequence; Set<int> coveredActs = findCoveredActs(sState,actions); if(!cov.ContainsKey(sState)) cov[sState] = 0.0; Set<Action> newStateActs = new Set<Action>(); Set<Action> newActs = new Set<Action>(); Set<Action> oldActs = new Set<Action>(actions.Head); foreach (Action a in actions) { tState = this.modelProgram.GetTargetState(iState, a, null, out tp).GetHashCode(); if (!v.ContainsKey(tState)) { newStateActs = newStateActs.Add(a); } else if (!coveredActs.Contains(a.GetHashCode())) { newActs = newActs.Add(a); } else { // one greedy approach /* if (v.ContainsKey(tState) && v[tState] > maxv) { maxv = v[tState]; oldActs = new Set<Action>(a); } else if (v.ContainsKey(tState) && v[tState] == maxv) { oldActs = oldActs.Add(a); }*/ // probabilistic greedy approach if (v.ContainsKey(tState)) { sum = sum + (int)(v[tState]* Math.Pow(10.0,9.0)); Pair<int, Action> np = new Pair<int, Action>(sum, a); cumulActSum = cumulActSum.AddLast(np); } } } if (!newStateActs.IsEmpty) { maxAct = newStateActs.Choose(); System.Console.WriteLine("new action in new state " + maxAct.ToString()); } else if (!newActs.IsEmpty) { maxAct = newActs.Choose(); System.Console.WriteLine("new action in old state " + maxAct.ToString()); } else { //maxAct = oldActs.Choose(); Random rndNumbers = new Random(); int rndNumber = rndNumbers.Next(sum); System.Console.WriteLine(sum + " " + rndNumber); foreach (Pair<int, Action> np in cumulActSum) { System.Console.WriteLine(np.First + " " + np.Second.ToString()); if (rndNumber <= np.First) { maxAct = np.Second; break; } maxAct = np.Second; } System.Console.WriteLine("old action in old state " + maxAct.ToString()); } coveredActs = coveredActs.Add(maxAct.GetHashCode()); cov[sState] = (double)coveredActs.Count / (double)actions.Count; return maxAct; }