public virtual IDmnDecisionTableResult EvaluateDecisionTable(IDmnDecision decision, IDictionary <string, ITypedValue> variables) { EnsureUtil.EnsureNotNull("decision", decision); EnsureUtil.EnsureNotNull("variables", variables); return(EvaluateDecisionTable(decision, Variables.FromMap(variables).AsVariableContext())); }
/// <summary> /// Creates the execution context snapshot - to be called by decision after the evaluation /// </summary> /// <param name="decision">Decision evaluated just before the snapshot</param> /// <param name="result"><paramref name="decision"/> result</param> internal virtual void CreateSnapshot(IDmnDecision decision, DmnDecisionResult result) { if (Options.RecordSnapshots) { Snapshots.CreateSnapshot(this, decision, result); } }
public virtual DmnEngineException decisionTypeNotSupported(IDmnDecision decision) { return (new DmnEngineException(ExceptionMessage("004", string.Format("Decision type '{0}' not supported by DMN engine.", decision.GetType())))); }
public virtual DmnTransformException DecisionIdIsMissing(IDmnDecision dmnDecision) { return (new DmnTransformException(ExceptionMessage("010", string.Format("The decision '{0}' must have an 'id' attribute set.", dmnDecision)))); }
public virtual DmnEngineException decisionIsNotADecisionTable(IDmnDecision decision) { return (new DmnEngineException(ExceptionMessage("013", string.Format("The decision '{0}' is not implemented as decision table.", decision)))); }
// listeners //////////////////////////////////////////////////////////////// protected internal virtual void NotifyTransformListeners(IDecision decision, IDmnDecision dmnDecision) { foreach (var transformListener in transformListeners) { transformListener.transformDecision(decision, dmnDecision); } }
/// <summary> /// Evaluate a decision with the given <seealso cref="IVariableContext" /> /// </summary> /// <param name="decision"> the decision to evaluate </param> /// <param name="variableContext"> the available variable context </param> /// <returns> the result of the decision evaluation </returns> public virtual IDmnDecisionResult evaluateDecision(IDmnDecision decision, IVariableContext variableContext) { if (ReferenceEquals(decision.Key, null)) { throw LOG.unableToFindAnyDecisionTable(); } var variableMap = buildVariableMapFromVariableContext(variableContext); IList <IDmnDecision> requiredDecisions = new List <IDmnDecision>(); buildDecisionTree(decision, requiredDecisions); IList <IDmnDecisionLogicEvaluationEvent> evaluatedEvents = new List <IDmnDecisionLogicEvaluationEvent>(); IDmnDecisionResult evaluatedResult = null; foreach (var evaluateDecision in requiredDecisions) { var handler = getDecisionEvaluationHandler(evaluateDecision); var evaluatedEvent = handler.Evaluate(evaluateDecision, variableMap.AsVariableContext()); evaluatedEvents.Add(evaluatedEvent); evaluatedResult = handler.GenerateDecisionResult(evaluatedEvent); if (decision != evaluateDecision) { addResultToVariableContext(evaluatedResult, variableMap, evaluateDecision); } } generateDecisionEvaluationEvent(evaluatedEvents); return(evaluatedResult); }
protected internal virtual bool IsDeployedDecisionTable(IDmnDecision decision) { if (decision is IDecisionDefinition) { return(!ReferenceEquals(((IDecisionDefinition)decision).Id, null)); } return(false); }
public virtual DmnTransformException DecisionTableRuleIdIsMissing(IDmnDecision dmnDecision, DmnDecisionTableRuleImpl dmnDecisionTableRule) { return (new DmnTransformException(ExceptionMessage("013", string.Format("The decision table rule '{0}' of decision '{1}' must have a 'id' attribute set.", dmnDecisionTableRule, dmnDecision)))); }
public virtual IDmnDecisionResult EvaluateDecision(IDmnDecision decision, IVariableContext variableContext) { EnsureUtil.EnsureNotNull("decision", decision); EnsureUtil.EnsureNotNull("variableContext", variableContext); if (decision is DmnDecisionImpl) { var decisionContext = new DefaultDmnDecisionContext(dmnEngineConfiguration); return(decisionContext.evaluateDecision(decision, variableContext)); } throw LOG.decisionTypeNotSupported(decision); }
protected internal virtual void buildDecisionTree(IDmnDecision decision, IList <IDmnDecision> requiredDecisions) { if (requiredDecisions.Contains(decision)) { return; } foreach (var dmnDecision in decision.RequiredDecisions) { buildDecisionTree(dmnDecision, requiredDecisions); } requiredDecisions.Add(decision); }
public virtual IDmnDecisionTableResult EvaluateDecisionTable(IDmnDecision decision, IVariableContext variableContext) { EnsureUtil.EnsureNotNull("decision", decision); EnsureUtil.EnsureNotNull("variableContext", variableContext); if (decision is DmnDecisionImpl && decision.DecisionTable) { var decisionContext = new DefaultDmnDecisionContext(dmnEngineConfiguration); var decisionResult = decisionContext.evaluateDecision(decision, variableContext); return(DmnDecisionTableResultImpl.Wrap(decisionResult)); } throw LOG.decisionIsNotADecisionTable(decision); }
protected internal virtual IList <IDmnDecision> GetRequiredDmnDecisions(IDecision decision, IDictionary <string, DmnDecisionImpl> dmnDecisions) { IList <IDmnDecision> requiredDecisionList = new List <IDmnDecision>(); foreach (var informationRequirement in decision.InformationRequirements) { var requiredDecision = informationRequirement.RequiredDecision; if (requiredDecision != null) { IDmnDecision requiredDmnDecision = dmnDecisions[requiredDecision.Id]; requiredDecisionList.Add(requiredDmnDecision); } } return(requiredDecisionList); }
public virtual IDmnDecisionLogicEvaluationEvent Evaluate(IDmnDecision decision, IVariableContext variableContext) { var evaluationResult = new DmnDecisionLiteralExpressionEvaluationEventImpl(); evaluationResult.Decision = decision; evaluationResult.ExecutedDecisionElements = 1; var dmnDecisionLiteralExpression = (DmnDecisionLiteralExpressionImpl)decision.DecisionLogic; var variable = dmnDecisionLiteralExpression.Variable; var expression = dmnDecisionLiteralExpression.Expression; var evaluateExpression = EvaluateLiteralExpression(expression, variableContext); ITypedValue typedValue = variable.TypeDefinition.Transform(evaluateExpression); evaluationResult.OutputValue = typedValue; evaluationResult.OutputName = variable.Name; return(evaluationResult); }
/// <summary> /// Executes (evaluates) given <paramref name="decision"/> /// </summary> /// <param name="decision">Decision to execute</param> /// <returns>Decision result</returns> /// <exception cref="ArgumentNullException"><paramref name="decision"/> is null</exception> public virtual DmnDecisionResult ExecuteDecision(IDmnDecision decision) { if (decision == null) { throw Logger.Fatal <ArgumentNullException>($"{nameof(decision)} is null"); } if (Options.RecordSnapshots) { //clear snapshots and create "initial" snapshot of the variables Snapshots.Reset(); Snapshots.CreateSnapshot(this); } var correlationId = Guid.NewGuid().ToString(); var result = decision.Execute(this, correlationId); //note: the decision-after-execute snapshot is created by decision (for each decision in "dependency graph") return(result); }
protected internal virtual void EnsureNoLoopInDecision(IDmnDecision decision, IList <string> parentDecisionList, IList <string> visitedDecisions) { if (visitedDecisions.Contains(decision.Key)) { return; } parentDecisionList.Add(decision.Key); foreach (var requiredDecision in decision.RequiredDecisions) { if (parentDecisionList.Contains(requiredDecision.Key)) { throw LOG.RequiredDecisionLoopDetected(requiredDecision.Key); } EnsureNoLoopInDecision(requiredDecision, new List <string>(parentDecisionList), visitedDecisions); } visitedDecisions.Add(decision.Key); }
public virtual IDmnDecisionLogicEvaluationEvent Evaluate(IDmnDecision decision, IVariableContext variableContext) { var evaluationResult = new DmnDecisionTableEvaluationEventImpl(); evaluationResult.DecisionTable = decision; var decisionTable = (DmnDecisionTableImpl)decision.DecisionLogic; evaluationResult.ExecutedDecisionElements = CalculateExecutedDecisionElements(decisionTable); EvaluateDecisionTable(decisionTable, variableContext, evaluationResult); // apply hit policy decisionTable.HitPolicyHandler.apply(evaluationResult); // notify listeners foreach (var evaluationListener in EvaluationListeners) { evaluationListener.Notify(evaluationResult); } return(evaluationResult); }
private static string GenerateDecisionBuilder(string prefix, IDmnDecision decision, string o, List <IDmnDecision> generatedDecisions) { if (generatedDecisions.Contains(decision)) { return(o); } foreach (var requiredDecision in decision.RequiredDecisions) { o = GenerateDecisionBuilder(prefix, requiredDecision, o, generatedDecisions); } var nl = Environment.NewLine; var outDecision = $"{prefix}{decision.Name.NormalizeName()}"; if (decision is DmnExpressionDecision expressionDecision) { o += nl; o += $@" .WithExpressionDecision(""{decision.Name.CodeEncodeStr()}"", eDecision =>" + nl; o += $@" eDecision.Put(""{expressionDecision.Expression.CodeEncodeStr()}"").To({prefix}{expressionDecision.Output.Name})" + nl; if (decision.RequiredInputs != null) { o = decision.RequiredInputs.Aggregate(o, (current, requiredInput) => current + $@" .Requires({prefix}{requiredInput.Name})" + nl); } if (decision.RequiredDecisions != null) { o = decision.RequiredDecisions.Aggregate(o, (current, requiredDec) => current + $@" .Requires({prefix}{requiredDec.Name.NormalizeName()})" + nl); } o += $@" ,out var {outDecision})" + nl; } if (decision is DmnDecisionTable table) { o += nl; o += $@" .WithTableDecision(""{decision.Name}"", table =>" + nl; o += $@" table" + nl; foreach (var tableInput in table.Inputs) { if (tableInput.Variable != null) { o += $@" .WithInput({prefix}{tableInput.Variable.Name}, out var {prefix}Input{tableInput.Index}"; } else { o += $@" .WithInput(""{tableInput.Expression.CodeEncodeStr()}"", out var {prefix}Input{tableInput.Index}"; } if (tableInput.AllowedValues != null && tableInput.AllowedValues.Length > 0) { o += "," + string.Join(", ", tableInput.AllowedValues.Select(a => $@"""{a}""")); } o += ")" + nl; } foreach (var tableOutput in table.Outputs.OrderBy(i => i.Index)) { o += $@" .WithOutput({prefix}{tableOutput.Variable.Name}, out var {prefix}Output{tableOutput.Index}"; if (tableOutput.AllowedValues != null && tableOutput.AllowedValues.Length > 0) { o += "," + string.Join(", ", tableOutput.AllowedValues.Select(a => $@"""{a}""")); } o += ")" + nl; } o += $@" .WithHitPolicy(HitPolicyEnum.{table.HitPolicy})" + nl; o += $@" .WithAggregation(CollectHitPolicyAggregationEnum.{table.Aggregation})" + nl; foreach (var rule in table.Rules.OrderBy(r => r.Index)) { o += $@" .WithRule(""{rule.Name}"",{(!string.IsNullOrEmpty(rule.Description) ? $@"""{rule.Description.CodeEncodeStr()}"", " : "")} r=>r" + nl; var firstInput = true; var firstOutput = true; foreach (var ruleInput in rule.Inputs) { o += $@" .{(firstInput ? "When" : "And")}({prefix}Input{ruleInput.Input.Index},""{ruleInput.UnparsedExpression.CodeEncodeStr()}"")" + nl; firstInput = false; } if (firstInput) { //no input o += $@" .Always()" + nl; } foreach (var ruleOutput in rule.Outputs) { o += $@" .{(firstOutput ? "Then" : "And")}({prefix}Output{ruleOutput.Output.Index},""{ruleOutput.Expression.CodeEncodeStr()}"")" + nl; firstOutput = false; } o += $@" )" + nl; } if (decision.RequiredInputs != null) { o = decision.RequiredInputs.Aggregate(o, (current, requiredInput) => current + $@" .Requires({prefix}{requiredInput.Name})" + nl); } if (decision.RequiredDecisions != null) { o = decision.RequiredDecisions.Aggregate(o, (current, requiredDec) => current + $@" .Requires({prefix}{requiredDec.Name.NormalizeName()})" + nl); } o += $@" ,out var {outDecision})" + nl; } generatedDecisions.Add(decision); return(o); }
public override DmnDecisionResult ExecuteDecision(IDmnDecision decision) { RetrievedFromCache = false; AddedToCache = false; return(base.ExecuteDecision(decision)); }
protected internal virtual IDmnDecisionLogicEvaluationHandler getDecisionEvaluationHandler(IDmnDecision decision) { var key = decision.DecisionLogic.GetType(); if (evaluationHandlers.ContainsKey(key)) { return(evaluationHandlers[key]); } throw LOG.decisionLogicTypeNotSupported(decision.DecisionLogic); }
public virtual void AddDecision(IDmnDecision decision) { decisions[decision.Key] = decision; }
protected internal virtual void addResultToVariableContext(IDmnDecisionResult evaluatedResult, IVariableMap variableMap, IDmnDecision evaluatedDecision) { var resultList = evaluatedResult.ResultList; if (resultList.Count == 0) { } else if ((resultList.Count == 1) && !isDecisionTableWithCollectOrRuleOrderHitPolicy(evaluatedDecision)) { foreach (var it in evaluatedResult.SingleResult) { variableMap.PutValue(it.Key, it.Value); } //variableMap.putAll(evaluatedResult.SingleResult); } else { ISet <string> outputs = new HashSet <string>(); foreach (var resultMap in resultList) { outputs.UnionWith(resultMap.Keys); } foreach (var output in outputs) { var values = evaluatedResult.CollectEntries <object>(output); variableMap.PutValue(output, values); } } }
protected internal virtual bool isDecisionTableWithCollectOrRuleOrderHitPolicy(IDmnDecision evaluatedDecision) { var isDecisionTableWithCollectHitPolicy = false; if (evaluatedDecision.DecisionTable) { var decisionTable = (DmnDecisionTableImpl)evaluatedDecision.DecisionLogic; isDecisionTableWithCollectHitPolicy = COLLECT_HIT_POLICY.Equals(decisionTable.HitPolicyHandler.HitPolicyEntry) || RULE_ORDER_HIT_POLICY.Equals(decisionTable.HitPolicyHandler.HitPolicyEntry); } return(isDecisionTableWithCollectHitPolicy); }
/// <summary> /// CTOR /// </summary> /// <param name="step">Sequence number of the execution step</param> /// <param name="ctx">Execution context to create snapshot for</param> /// <param name="decision">Decision executed just before snapshot</param> /// <param name="result">Result of the decision executed just before snapshot</param> internal DmnExecutionSnapshot(int step, DmnExecutionContext ctx, IDmnDecision decision, DmnDecisionResult result) : this(step, ctx) { Decision = decision; DecisionResult = result?.Clone(); }
/// <summary> /// Creates the snapshot with the decision information /// </summary> /// <param name="ctx">Execution context to create snapshot for</param> /// <param name="decision">Decision executed just before snapshot</param> /// <param name="result">Result of the decision executed just before snapshot</param> internal void CreateSnapshot(DmnExecutionContext ctx, IDmnDecision decision, DmnDecisionResult result) { snapshots.Add(new DmnExecutionSnapshot(snapshots.Count, ctx, decision, result)); }