private void SaveCurrentParameters(IParametersCollection currentParameters) { if (currentParameters != null) { Sequence.UpdateParametersCollection(currentParameters); } }
public async Task <ExecutionResult> Execute(string yaml, IParametersCollection parameters) { await _parameters.ReadStateAsync(); var state = _parameters.State as IParametersCollection; var executionResult = new ExecutionResult(ref parameters) as IExecutionResult; var controller = new YamlScriptController(); controller.QuestionCallback = (sender, args) => { executionResult.Questions = args; }; var result = controller.Parse(yaml); executionResult = new ExecutionResult(ref parameters); try { controller.ExecuteWorkflow(ref state, ref executionResult); } catch (UnresolvedException) { } _parameters.State = executionResult.Parameters as ParametersCollection; await _parameters.WriteStateAsync(); return(executionResult as ExecutionResult); }
private void CheckForStopExecution(IParametersCollection parameters, IExecutionResult executionResult) { if (parameters.Any(p => p.Name == "recht" && bool.TryParse(p.Value.ToString(), out bool value) && value == false)) { executionResult.Stacktrace.Last().StopExecution(); } }
public void EvaluateFormulaWithoutQA(ref IParametersCollection parameters, IEnumerable <string> formulas) { foreach (var formula in formulas) { EvaluateFormulaWithoutQA(ref parameters, formula); } }
public IEnumerable <string> GetUnresolvedParameters(string semanticKey, IParametersCollection parameters) { Parameters = parameters; var texts = GetAllApplicableTexts(semanticKey); return(GetUnresolvedParameters(texts)); }
public FormulaExpressionContext(ref Model.Model model, ref IParametersCollection parameters, Formula formula, QuestionDelegate onQuestion, YamlScriptController controller) { _parameters = parameters as ParametersCollection ?? throw new ArgumentNullException(nameof(parameters)); _formula = formula ?? throw new ArgumentNullException(nameof(formula)); OnQuestion = onQuestion ?? throw new ArgumentNullException(nameof(onQuestion)); _model = model ?? throw new ArgumentNullException(nameof(model)); // Define the context of our expression _context = new ExpressionContext(controller); _context.Options.ParseCulture = CultureInfo.InvariantCulture; // Allow the expression to use all static public methods of System.Math _context.Imports.AddType(typeof(Math)); // Allow the expression to use all static overload public methods our CustomFunctions class _context.Imports.AddType(typeof(CustomFunctions)); // Financial formulas _context.Imports.AddType(typeof(BankingFormulas)); _context.Imports.AddType(typeof(CorporateFormulas)); _context.Imports.AddType(typeof(FinancialFormulas)); _context.Imports.AddType(typeof(FinancialMarketsFormulas)); _context.Imports.AddType(typeof(GeneralFinanceFormulas)); _context.Imports.AddType(typeof(StocksBondsFormulas)); // this will visit ResolveVariableType _context.Variables.ResolveVariableType += ResolveVariableType; // this will visit ResolveVariableValue _context.Variables.ResolveVariableValue += ResolveVariableValue; Map(ref _parameters, _context.Variables); }
public IExecuteRequest GetExecuteRequest(IParametersCollection parameters = null) { return(new ExecuteRequest { Config = Sequence.Yaml, Parameters = parameters }); }
public IEvaluateFormulaWithoutQARequest GetEvaluateFormulaWithoutQARequest(ref IParametersCollection parameters, IEnumerable <string> unresolvedParameters) { return(new EvaluateFormulaWithoutQARequest { Config = Sequence.Yaml, Parameters = parameters, UnresolvedParameters = unresolvedParameters ?? new List <string>() }); }
public void EvaluateFormulaWithoutQA(ref IParametersCollection parameters, string formula) { void callback(FormulaExpressionContext sender, QuestionArgs args) { throw new Exception($"Can't resolve formula {formula} without answering question {args.Parameters[0].Name} first."); }; var context = new FormulaExpressionContext(ref _model, ref parameters, GetFormula(formula), callback, this); context.Evaluate(); }
public void UpdateParametersCollection(IParametersCollection parameters) { foreach (var p in parameters.GetAll()) { if (p is IClientParameter && !((IClientParameter)p).IsCalculated) { Parameters.UpSert(p); } } ; }
public void ExecuteStep(IParametersCollection currentParameters) { SaveCurrentParameters(currentParameters); var requestParameters = Sequence.GetParametersToSend(RequestStep); var request = GetExecuteRequest(requestParameters); LastExecutionResult = _serviceController.Execute(request); //only save non-calculated parameters Sequence.UpdateParametersCollection(LastExecutionResult.Parameters); Sequence.AddStep(RequestStep, LastExecutionResult); CurrentStep = RequestStep; }
/// <summary> /// Execute Workflow /// </summary> /// <param name="parameters"></param> /// <returns></returns> public IExecutionResult ExecuteWorkflow(ref IParametersCollection parameters, ref IExecutionResult executionResult) { _parameters = parameters; executionResult.ContentNodes = _contentNodes; if (parameters is null) { throw new ArgumentNullException(nameof(parameters)); } if (executionResult is null) { throw new ArgumentNullException(nameof(executionResult)); } try { foreach (var step in _model.Steps) { // indicates if the step should be executed or skipped. bool match = false; if (!string.IsNullOrEmpty(step.Situation)) { match = EvaluateSituation(ref parameters, step, out IStep stepActiveSituation); executionResult.Step = stepActiveSituation; } // unconditional step else { executionResult.Step = step.Clone(); match = true; } // execute step. if (match) { ExecuteStep(ref executionResult, ref parameters, executionResult.Step); if (executionResult != null && executionResult.Stacktrace.Last().IsStopExecution) { break; } ; } } } catch (StepException ex) { executionResult.Stacktrace.Add(new FlowExecutionItem(ex.Step, ex)); } return(executionResult); }
public async Task <IExecutionResult> Execute(string yaml, IParametersCollection parameters) { IExecutionResult executionResult = null; var controller = new YamlScriptController(); controller.QuestionCallback = (FormulaExpressionContext sender, QuestionArgs args) => { executionResult.Questions = args; }; var result = controller.Parse(yaml); executionResult = new ExecutionResult(ref parameters) as IExecutionResult; try { controller.ExecuteWorkflow(ref parameters, ref executionResult); } catch (UnresolvedException) { } return(executionResult); }
public QuestionArgs(string sessionId, IParametersCollection parameters) { SessionId = sessionId ?? throw new System.ArgumentNullException(nameof(sessionId)); Parameters = parameters ?? throw new System.ArgumentNullException(nameof(parameters)); }
public Table Match(string tableName, ref IParametersCollection parameters) { int i = 0; int nonSituationalTables = 0; List <Table> matchedTables = new List <Table>(); var tables = _model.GetTablesByName(tableName); ISituation currentSituation = null; void callback(FormulaExpressionContext sender, QuestionArgs args) { throw new Exception($"{tableName} contains situational expression {currentSituation.Expression} that could not be resolved without answering a question: {args.Parameters[0].Name}. Situational tables should only contain resolveable parameters."); }; foreach (var table in _model.GetTablesByName(tableName)) { i++; if (!table.IsSituational) { nonSituationalTables++; if (nonSituationalTables > 1) { throw new Exception($"found multiple tables found for {tableName} that are non situational. Only one table is allowd to be non situational."); } if (!table.IsSituational && i != tables.Count()) { throw new Exception($"Default table {tableName} should be specified after all situational tables."); } matchedTables.Add(table); continue; } // evaluate situations for inclusivity (meaning one of the expressions should evaluate to true. foreach (var situation in table.Situations) { currentSituation = situation; var formula = new Formula(table.DebugInfo, "__temp__", new List <Function>() { new Function(table.DebugInfo, situation.Expression) }); var context = new FormulaExpressionContext(ref _model, ref parameters, formula, callback, this); var result = context.Evaluate(); if (result.Type != TypeEnum.Boolean) { throw new Exception($"{tableName} contains situational expression {currentSituation.Expression} and should evaluate to a boolean, instead it resolved to a: {result.TypeAsString}."); } if ((bool)result.Value) { matchedTables.Add(table); } } } if (matchedTables.Count == 0) { throw new Exception($"No table matches for {tableName}."); } if (matchedTables.Count > 1 && nonSituationalTables == 0) { throw new Exception($"Ambigous situation evaluation on tables named {tableName}."); } return(matchedTables[0]); }
public ExecutionResult(ref IParametersCollection parameters) { Parameters = parameters; Stacktrace = new List <FlowExecutionItem>(); }
private void ExecuteStep(ref IExecutionResult executionResult, ref IParametersCollection parameters, IStep step) { var questions = new ParametersCollection(); if (executionResult is null) { throw new ArgumentNullException(nameof(executionResult)); } if (parameters is null) { throw new ArgumentNullException(nameof(parameters)); } executionResult.Stacktrace.Add(new FlowExecutionItem(step, null)); // Prescedence is (correct order of evaluation) // #1 evaluate step variable (value Question) or evaluate situation (choice Question) // #2 evaluate formula // #3 evaluate break (recht) // Evaluate step variable if available // Ask a question for a direct input value from the client, if the parameter is unknown. // Note: in inference we assume the input value is of type double. // When used in combination with "recht", do not advance to the next step until recht is evaluated. // When used in combination with "formule", do not advance to the next step until the formule is evaluated. if (!string.IsNullOrEmpty(step.Value) && parameters.GetParameter(step.Value) == null) { if (QuestionCallback == null) { throw new Exception($"In order to evaluate step variable {step.Value}, you need to provide a delegate callback to the client for providing an answer"); } questions.UpSert(new Parameter(step.Value, 0, TypeEnum.Double, ref _model)); QuestionCallback(null, new QuestionArgs("", questions)); // step variable has to be formulated as an input parameter by the client. throw new UnresolvedException($"Can't evaluate step variable {step.Value}."); } if (step.Choices != null) { bool answered = false; foreach (var choice in step.Choices) { var situation = parameters.GetParameter(choice.Situation); if (situation == null) { questions.UpSert(new Parameter(choice.Situation, false, TypeEnum.Boolean, ref _model)); } else { if ((bool)situation.Value == true) { answered = true; } } } if (!answered) { QuestionCallback(null, new QuestionArgs("", questions)); throw new UnresolvedException($"Choices {string.Join(',', step.Choices.Select(p => p.Situation))} can not evaluate further, before these are answered by the client."); } } if (!string.IsNullOrEmpty(step.Formula)) { var context = new FormulaExpressionContext(ref _model, ref parameters, GetFormula(step.Formula), QuestionCallback, this); context.Evaluate(); } // Evaluate recht if available. if (step.Break != null && !string.IsNullOrEmpty(step.Break.Expression)) { var breakContext = new FormulaExpressionContext( ref _model, ref parameters, new Formula(step.DebugInfo, "recht", new List <Function>() { new Function(step.DebugInfo, step.Break.Expression) }), QuestionCallback, this); breakContext.Evaluate(); } CheckForStopExecution(parameters, executionResult); }
private bool EvaluateSituation(ref IParametersCollection parameters, IStep step, out IStep stepActiveSituation) { if (parameters is null) { throw new ArgumentNullException(nameof(parameters)); } stepActiveSituation = step.Clone(); var match = false; // evaluate if the situation (condition) is appropiate, otherwise skip it. // not in input parameters. Evaluate the var parameter = parameters.GetParameter(step.Situation); if (step.Situation.Contains(',')) { foreach (var inclusiveSituation in step.Situation.Split(',') .Select(x => x.Trim()) .Where(x => !string.IsNullOrWhiteSpace(x)) .ToArray()) { parameter = parameters.GetParameter(inclusiveSituation); if (parameter != null && parameter.Type == TypeEnum.Boolean) { if ((bool)parameter.Value == true) { stepActiveSituation = step.Clone(); stepActiveSituation.Situation = inclusiveSituation; stepActiveSituation.SemanticKey = string.Join('.', stepActiveSituation.SemanticKey.Split('.').Take(3).ToArray()) + "." + inclusiveSituation; // this is a hack, please refactor. } // seach in content nodes for this parameter in typenum steps //var s = ContentNodes.FindAll(p => p.Parameter.Type == TypeEnum.Step); return(true); } } throw new StepException($"Can't resolve any of the inclusive situations ${step.Situation}. One of these parameters must exist and be of boolean type.", step); } if (parameter == null) { // resolve parameter value from named formula. var formula = GetFormula(step.Situation); if (formula == null) { throw new StepException($"can't resolve parameter '${parameter.Name}' to formula", step); } // execute the formula which adds the outcome to parameters. var context = new FormulaExpressionContext(ref _model, ref parameters, formula, QuestionCallback, this); var result = context.Evaluate(); //var result = Execute(ref context, ref formula, ref parameters, ref executionResult); if (result.Value.GetType() != typeof(bool)) { throw new StepException($"Expected situation to evalute to boolean value in worflow step {step.Name} {step.Description} but got value: {result.Value} of type {result.Value.GetType().Name} instead.", step); } match = (bool)result.Value; } else { if ((bool)parameter.Value.Infer()) { // execute this step. match = true; } } return(match); }
public static ExecutionResult NotExecutedBecauseOfParseError(ref IParametersCollection parameters, ref IEnumerable <ContentNode> contentNodes) => new ExecutionResult(ref parameters) { IsError = true, Message = "Not Executed Because Of Parse Error" };
public Call() { this.Parameters = new ParametersCollection(); }
public void FillUnresolvedParameters(ref IParametersCollection parameters, IEnumerable <string> unresolvedParameters) { var evaluateFormulaWithoutQARequest = GetEvaluateFormulaWithoutQARequest(ref parameters, unresolvedParameters); _serviceController.GetExtraParameters(evaluateFormulaWithoutQARequest); }