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);
        }
Example #3
0
 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();
     }
 }
Example #4
0
 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>()
     });
 }
Example #9
0
        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();
        }
Example #10
0
 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;
        }
Example #12
0
        /// <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);
        }
Example #13
0
        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);
        }
Example #14
0
 public QuestionArgs(string sessionId, IParametersCollection parameters)
 {
     SessionId  = sessionId ?? throw new System.ArgumentNullException(nameof(sessionId));
     Parameters = parameters ?? throw new System.ArgumentNullException(nameof(parameters));
 }
Example #15
0
        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]);
        }
Example #16
0
 public ExecutionResult(ref IParametersCollection parameters)
 {
     Parameters = parameters;
     Stacktrace = new List <FlowExecutionItem>();
 }
Example #17
0
        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);
        }
Example #18
0
        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);
        }
Example #19
0
 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);
        }