/// <summary> /// Returns true if the action is enabled in the current state. /// If the action is not enabled, provides a reason in <paramref name="failureReason"/>. /// </summary> /// <param name="action">action whose enabledness is being checked</param> /// <param name="failureReason">failure reason if the action is not enabled</param> /// <returns>true if the action is enabled, false otherwise</returns> public bool IsActionEnabled(CompoundTerm action, out string failureReason) { if (!AllActionSymbols.Contains(action.Symbol)) { failureReason = "Action symbol '" + action.Symbol.ToString() + "' not enabled in the model"; return(false); } else { bool isEnabled = modelProgram.IsEnabled(currState, action); if (!isEnabled) { failureReason = "Action '" + ConformanceTester.MakeQuotedString(action.ToString()) + "' not enabled in the model"; foreach (string s in modelProgram.GetEnablingConditionDescriptions(currState, action, true)) { failureReason += "\n"; failureReason += s; } return(false); } else { failureReason = ""; return(true); } } }
/// <summary> /// Computes the mapping from the parameter positions of the action label to the /// output parameter positions of the .NET method that implements the action. /// </summary> /// <param name="actionLabel">The finish action label</param> /// <param name="actionMethod">The action method</param> /// <returns>An array of integers where each entry is the index in the parameter list /// of the .NET method. The special value -1 is used to indicate the position of the the /// return value. The special value -2 is used to indicate an ignored argument.</returns> internal static int[] GetOutputParameterIndices(CompoundTerm actionLabel, MethodInfo actionMethod) { List <int> parameterIndices = new List <int>(); foreach (Term arg in actionLabel.Arguments) { if (Any.Value == arg) { parameterIndices.Add(-2); } else { Variable v = arg as Variable; if (null != v) { string name = v.ToString(); if ("result".Equals(name)) { parameterIndices.Add(-1); } else { int index = 0; bool foundMatch = false; foreach (ParameterInfo pInfo in actionMethod.GetParameters()) { if (pInfo.Name.Equals(name)) { parameterIndices.Add(index); foundMatch = true; break; } index += 1; } // this test is dead code (was previously checked). if (!foundMatch) { throw new ModelProgramUserException("action label " + actionLabel.ToString() + " includes unrecognized output argument " + name); } } } else { throw new ModelProgramUserException("action label " + actionLabel.ToString() + " may not include ground term " + arg.ToString()); } } } return(parameterIndices.ToArray()); }
static void CheckForDuplicateArgument(CompoundTerm action) { Set <Term> argsSoFar = Set <Term> .EmptySet; foreach (Term arg in action.Arguments) { if (argsSoFar.Contains(arg)) { throw new ModelProgramUserException("action label " + action.ToString() + " contains duplicate argument " + arg.ToString()); } else if (!Any.Value.Equals(arg)) { argsSoFar = argsSoFar.Add(arg); } } }
/// <summary/> public CompoundTerm DoAction(CompoundTerm action) { Config.init(); string s = action.ToString(); if (!c.isConnected()) { c.Socket(); if (Config.logEnabled) { Logger.log("connect to " + Config.host + ":" + Config.port); } c.Connect(Config.host, Config.port, Config.bufferSize); } if (resetDelayed) { if (Config.logEnabled) { Logger.log("delayed Reset on " + s); } reset(); } if (Config.logEnabled) { Logger.log("send " + s); } c.Send(s + "\n"); s = receive(); if (Config.logEnabled) { Logger.log("rcvd " + s); } if (s.Length == 0) { return(null); } else { return(CompoundTerm.Parse(s)); } }
/// <summary> /// Perform the action /// </summary> /// <param name="action">the given action</param> /// <returns>the returned action (or null)</returns> public CompoundTerm DoAction(CompoundTerm action) { switch (action.FunctionSymbol.ToString()) { case "Insert": { Coin coin = GetCoin(action.Arguments[0]); EmptyCoffeeMachineImpl.InsertACoin(coin); return(null); } case "Cancel": { Term coin = CompoundValue.GetTerm(EmptyCoffeeMachineImpl.Cancel()); return(new CompoundTerm(Symbol.Parse("Return"), coin)); } default: throw new InvalidOperationException("Unrecognized action: " + action.ToString()); } }
/// <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) { transitionProperties = new TransitionProperties(); FsmState fs = startState as FsmState; if (fs == null) { throw new ArgumentException("Invalid state"); } Set <Term> targetAutomatonStates = Set <Term> .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 (IsCompatibleTerm(action, ct)) //(Object.Equals(ct, action)) { targetAutomatonStates = targetAutomatonStates.Add(t.Third); } } } if (targetAutomatonStates.Equals(Set <Term> .EmptySet)) { throw new ArgumentException("Action not enabled: " + action.ToString()); } return(new FsmState(targetAutomatonStates)); }
/// <summary> /// Perform the action /// </summary> /// <param name="action">the given action</param> /// <returns>the returned action (or null)</returns> public CompoundTerm DoAction(CompoundTerm action) { switch (action.FunctionSymbol.ToString()) { case "SetPlayer1": wh.Set(); // Signal the waiting thread to proceed (test-cases continue, don't exit) Console.WriteLine("\nSetting Player1 to " + (string)action[0]); runner.setPlayer("Player1", (string)action[0]); return(null); case "SetPlayer2": Console.WriteLine("\nSetting Player2 to " + (string)action[0]); runner.setPlayer("Player2", (string)action[0]); return(null); case "ReadLastResult_Start": Console.WriteLine("\nChecking the results list-box"); Thread.Sleep(200); return(CompoundTerm.Create("ReadLastResult_Finish", runner.getLastResult())); default: throw new InvalidOperationException("Unrecognized action: " + action.ToString()); } }
static Set <string> GetUnusedArguments(Set <string> defaultArguments, CompoundTerm action) { Set <string> result = defaultArguments; foreach (Term arg in action.Arguments) { if (!arg.Equals(Any.Value)) { Variable v = arg as Variable; if (null == v) { throw new ModelProgramUserException("invalid argument for action " + action.ToString() + ": " + arg.ToString()); } string name = v.ToString(); if (!defaultArguments.Contains(name)) { throw new ModelProgramUserException("invalid (possibly misspelled) argument for action " + action.ToString() + ": " + arg.ToString() + ". Must be one of " + defaultArguments.ToString() + "."); } result = result.Remove(name); } } return(result); }
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); }