private Parameter NonSituationalEvaluate(out IDynamicExpression e)
 {
     try
     {
         e = _context.CompileDynamic(_formula.Functions[0].Expression);
         var       result = e.Evaluate().Infer();
         Parameter parameter;
         parameter = new Parameter(_formula.Name, result.Infer(), null, ref _model);
         parameter.IsCalculated = true;
         _parameters.Add(parameter);
         if (_context.Variables.ContainsKey(parameter.Name))
         {
             _context.Variables.Remove(parameter.Name);
         }
         _context.Variables.Add(parameter.Name, parameter.Value.Infer());
         return(parameter);
     }
     catch (ExpressionCompileException)
     {
         // Function can not evaluate further, before a Question/Answer sequence is fullfilled by the client.
         throw new UnresolvedException($"Function {_formula.Functions[0].Expression} can not evaluate further, before a Question/Answer sequence is fullfilled by the client.");
     }
 }
Example #2
0
        public ParametersCollection GetFunctionTree(YamlScriptController controller, string expression = null)
        {
            localContext = new ExpressionContext(controller);
            localContext.Options.ParseCulture = CultureInfo.InvariantCulture;
            // Allow the expression to use all static public methods of System.Math
            localContext.Imports.AddType(typeof(Math));
            // Allow the expression to use all static overload public methods our CustomFunctions class
            localContext.Imports.AddType(typeof(CustomFunctions));
            var variables  = new System.Collections.Generic.Dictionary <string, Type>();
            var parameters = new ParametersCollection();

            localContext.Variables.ResolveVariableType += (object sender, ResolveVariableTypeEventArgs e) =>
            {
                parameters.Add(new Parameter(e.VariableName, 0, null, ref _model));
                variables.Add(e.VariableName, typeof(object));
                e.VariableType = typeof(object);
            };

            if (expression != null)
            {
                try
                {
                    IGenericExpression <object> eDynamic = localContext.CompileGeneric <object>(expression);
                }
                catch
                {
                }
                return(parameters);
            }

            foreach (var formula in _model.Formulas)
            {
                try
                {
                    IGenericExpression <object> eDynamic = localContext.CompileGeneric <object>(formula.Functions[0].Expression);
                }
                catch
                {
                }
            }
            return(parameters);
        }
        private static Parameter Evaluate(FormulaExpressionContext caller, ref ExpressionContext context, ref Formula formula, ref ParametersCollection parameters1, QuestionDelegate onQuestion, ref Model.Model model)
        {
            if (parameters1 is null)
            {
                throw new ArgumentNullException(nameof(parameters1));
            }

            IDynamicExpression e = null;

            if (!formula.IsSituational)
            {
                try
                {
                    e = context.CompileDynamic(formula.Functions[0].Expression);
                    var       result = e.Evaluate().Infer();
                    Parameter parameter;
                    parameter = new Parameter(formula.Name, result.Infer(), null, ref model);
                    parameter.IsCalculated = true;
                    parameters1.Add(parameter);
                    if (context.Variables.ContainsKey(parameter.Name))
                    {
                        context.Variables.Remove(parameter.Name);
                    }
                    context.Variables.Add(parameter.Name, parameter.Value.Infer());
                    return(parameter);
                }
                catch (ExpressionCompileException)
                {
                    // Function can not evaluate further, before a Question/Answer sequence is fullfilled by the client.
                    throw new UnresolvedException($"Function {formula.Functions[0].Expression} can not evaluate further, before a Question/Answer sequence is fullfilled by the client.");
                }
            }
            else
            {
                foreach (var function in formula.Functions)
                {
                    foreach (var item in parameters1)
                    {
                        if (item.Name == function.Situation && (bool)item.Value == true)
                        {
                            try
                            {
                                e = context.CompileDynamic(function.Expression);
                                var parameter = new Parameter(formula.Name, e.Evaluate().Infer(), null, ref model);
                                parameter.IsCalculated = true;
                                parameters1.Add(parameter);
                                if (context.Variables.ContainsKey(parameter.Name))
                                {
                                    context.Variables.Remove(parameter.Name);
                                }
                                context.Variables.Add(parameter.Name, parameter.Value.Infer());
                                return(parameter);
                            }
                            catch (ExpressionCompileException)
                            {
                                // Function can not evaluate further, before a Question/Answer sequence is fullfilled by the client.
                                throw new UnresolvedException($"Function {function.Expression} can not evaluate further, before a Question/Answer sequence is fullfilled by the client.");
                            }
                        }
                    }
                }
                StringBuilder situations = new StringBuilder();
                var           parameters = new ParametersCollection();
                foreach (var function in formula.Functions)
                {
                    situations.Append(function.Situation + ",");
                    var parameter = new Parameter(function.Situation, TypeInference.Infer(function).Type, null, ref model);
                    parameters.Add(parameter);
                }
                if (onQuestion == null)
                {
                    throw new Exception($"In order to evaluate variable one of the following situations:  {situations.ToString().Trim(',')}, you need to provide a delegate callback to the client for providing an answer");
                }
                onQuestion(caller, new QuestionArgs("", parameters));
                // situation has to be formulated as an input parameter by the client.
                throw new UnresolvedException($"Can't evaluate formula {formula.Name} for situation. Please specify one of the following situations: {situations.ToString().Trim(',')}.");
            }
        }
        private Parameter SituationalEvaluate(out IDynamicExpression e)
        {
            foreach (var function in _formula.Functions)
            {
                foreach (var item in _parameters)
                {
                    if (item.Name == function.Situation && bool.TryParse(item.Value.ToString(), out bool value) && value)
                    {
                        try
                        {
                            if (_formula.IsAutoFunc)
                            {
                                // do not compile, autofunc is derived from a user choice from step.
                                e = _context.CompileDynamic(function.Expression);
                                return(item as Parameter);
                            }
                            else
                            {
                                e = _context.CompileDynamic(function.Expression);
                                var parameter = new Parameter(_formula.Name, e.Evaluate().Infer(), null, ref _model);
                                parameter.IsCalculated = true;
                                if (_parameters.GetParameter(_formula.Name) != null)
                                {
                                    // while reclaculating make sure to keep parameters distinct
                                    _parameters.Remove(_parameters.GetParameter(_formula.Name));
                                }

                                _parameters.Add(parameter);
                                if (_context.Variables.ContainsKey(parameter.Name))
                                {
                                    _context.Variables.Remove(parameter.Name);
                                }
                                _context.Variables.Add(parameter.Name, parameter.Value.Infer());
                                return(parameter);
                            }
                        }
                        catch (ExpressionCompileException ex)
                        {
                            // Function can not evaluate further, before a Question/Answer sequence is fullfilled by the client.
                            throw new UnresolvedException($"Function {function.Expression} can not evaluate further, before a Question/Answer sequence is fullfilled by the client.", ex);
                        }
                    }
                }
            }
            StringBuilder situations = new StringBuilder();
            var           parameters = new ParametersCollection();

            foreach (var function in _formula.Functions)
            {
                situations.Append(function.Situation + ",");
                var parameter = new Parameter(function.Situation, null, TypeInference.Infer(function).Type, ref _model);
                parameters.Add(parameter);
            }
            if (OnQuestion == null)
            {
                throw new Exception($"In order to evaluate variable one of the following situations:  {situations.ToString().Trim(',')}, you need to provide a delegate callback to the client for providing an answer");
            }
            OnQuestion(this, new QuestionArgs("", parameters));
            // situation has to be formulated as an input parameter by the client.
            throw new UnresolvedException($"Can't evaluate formula {_formula.Name} for situation. Please specify one of the following situations: {situations.ToString().Trim(',')}.");
        }