Giter Club home page Giter Club logo

adamecr / common.dmn.engine Goto Github PK

View Code? Open in Web Editor NEW
83.0 10.0 24.0 2.21 MB

DMN Engine is a decision engine (rule engine) allowing to execute and evaluate the decisions defined in a DMN model. Its primary target is to evaluate the decision tables that transform the inputs into the output(s) using the decision rules.

License: MIT License

C# 100.00%
dmn dmn-engine rule-engine rules-engine decision-making decision-engine dmn-model decision-table camunda-engine

common.dmn.engine's People

Contributors

adamecr avatar samuelsen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

common.dmn.engine's Issues

how do i install DMN.Engine in my .NET project?

i tried to install DMN.Engine in my .NET project(.NETFramework,Version=v4.5.2).
i type the
PM> Install-Package net.adamec.lib.common.dmn.engine -Version 0.1.2
and than responded

Install-Package : Package 'net.adamec.lib.common.dmn.engine,0.1.2' is not found in the following primary source(s): 'https://api.nuget.org/v3/index.json,C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\'. P
lease verify all your online package sources are available (OR) package id, version are specified correctly.
At line:1 char:16
+ Install-Package <<<<  net.adamec.lib.common.dmn.engine -Version 0.1.2
    + CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand

why the online package sources are missing?
did i missing something?

Unable to build application

While build the application in VS2022, we got the following error.

build.tasks

CS0246 The type or namespace name 'Task' could not be found (are you missing a using directive or an assembly reference?)
CS0103 The name 'Log' does not exist in the current context

Kindly assistance

DmnExecutionContext.ExecuteDecision() seems to be using the label instead of the name to identify output from a dependent Decision

I am using the downloaded DMN (v1.3) from https://consulting.camunda.com/dmn-simulator/

I changed the Inputs' name to 'season', 'guestCount', 'guestsWithChildren' from the original 'Season', 'Number of Guests', 'Guests with children?' so that WithInputParameter will run correctly.

        string fileName = "simulation.dmn";
        var def = DmnParser.Parse(fileName, DmnParser.DmnVersionEnum.V1_3);
        var ctx = DmnExecutionContextFactory.CreateExecutionContext(def);
        ctx.WithInputParameter("season", "Winter");
        ctx.WithInputParameter("guestCount", 1);
        ctx.WithInputParameter("guestsWithChildren", true); 
        var outcome = ctx.ExecuteDecision("Beverages");

        foreach (var result in outcome.Results)
        {
            foreach (var variable in result.Variables)
            {
                Console.WriteLine(variable.Name + ": " + variable.Value);
            }
        }

At the line 'var outcome = ctx.ExecuteDecision("Beverages");', I encountered this exception:
DynamicExpresso.Exceptions.UnknownIdentifierException: 'Unknown identifier 'desiredDish' (at index 0).'

I looked at the DMN file and saw that the Beverages decision has an input:

<inputExpression id="LiteralExpression_0bqgrlg" typeRef="string"> <text>desiredDish</text> </inputExpression>
... that is the output from Dish decision:
<output id="OutputClause_0lfar1z" label="Dish" name="desiredDish" typeRef="string" />

When I changed the output clause of Dish decision to the following, the code worked:
<output id="OutputClause_0lfar1z" label="desiredDish" name="desiredDish" typeRef="string" />

Seems like you are using the label as the identifier of the output element instead of using name.

Not compatible with Kie DMN documents?

I have been looking at how to use either Camunda Modeler or the Kie/DROOLS VS Code plugin to edit DMN files for use with your excellent DMN Engine and in particular with its simulator. I have found a few issues. One is that the simulator declares that it cannot parse a simple Kie/DROOLS DMN document owning to an error in line 2, column 2. This looks to be a question of namespace incompatibility. Simultaneously, I don't think I can use Camunda Modeler, as it does not recognise an information requirement. This means that the simulator does not offer me the chance to enter test inputs. Kie/DROOLS has a nice information requirement function and if I copy and paste the InputData and InformationRequirement elements from Kie/DROOLS across to a Camunda document, I get a very nice experience in the simulator. On balance, I think the Kie/DROOLS editor in VS Code offers the better opportunities, but I don't know how to manipulate the namespaces to avoid the error in your simulator. Do you have any advice?

FEEL instead of SFEEL

Hi Radec,

I am very happy with this open source implementation and am heavily using it as a generic back end service able to execute DM's from a central repository. Only thing I am missing is being able to use the complete FEEL expression language constructs. Are you considering adding this in the future? In my optinion that would make this implementation a valuable product. How much effort would you need to add this? Would you be interested to work on this (with me)?

Kind regards,
Radoslaw

Issue in net 6 with parsing definition from DM

Dear Radek,

Thanks for sharing the DMN execution engine code. It's great! However I found an issue with the .NET 6 implementation which doesn't appear in netstandard2.0.

The DmnModel created by calling DmnDefinitionFactory.CreateDmnDefinition(dmnModel); is slightly different in NET 6, which causes problems during evaluation of rule expressions.

Attached is a DMN which cannot be executed in NET 6 but can in netstandard2.0.

The root cause seems to be that on generating the definition the 'Inputs.Variable' of Decision is null in NET6, whereas it is a Typed variable in netstandard2.0.

For example check out in debugmode the generated definition decision 3:

NET 6:
definition.Decisions[3].Inputs[0] = {#0:aantal kostendelers}

netstandard2.0:
definition.Decisions[3].Inputs[0] = {#0:aantal_kostendelers:System.Int32}

The Eval exception will be triggered on execution of the engine. Could you please advise how to get around this as netstandar2.0 is not the way to go anymore?

Kind regards,
Radoslaw Merkx

ParsedExpressionsCache Corruption when running multiple concurrent evaluations

The ParsedExpressionsCache in the class DmnExecutionContext is defined as a static Dictionary which in single threaded environments works fine.
In the case where there are multiple evaluations happening at the same time we get concurrency exceptions being throw by the .NET runtime, as the cache is being modified as it's been read from.
I downloaded the code to evaluate what the problem may be and found that changing the ParsedExpressionsCache to a ConcurrentDictionary overcame this issue.

NormalizeVariableName(string name)

In the latest version of the library the following code has been introduced to validate input names:

public static string NormalizeVariableName(string name)

For out part this brakes because of using Norwegian letters like æ, ø, å, within the DMN files, and also as input params to the library.

A better solution would probably be to use the .net function:

public static string NormalizeVariableName(string name)
{
    var retVal = name?.Trim().Replace(' ', '_');

    if (string.IsNullOrWhiteSpace(retVal))
        throw new ArgumentException($"Variable name is null or empty",nameof(name));

    if (retVal.Any(c => char.IsLetter(c) || char.IsDigit(c)  || c == '_')))
        throw new ArgumentException($"Variable name '{name}' contains invalid character", nameof(name));

    if (!char.IsLetter(retVal[0])
        throw new ArgumentException($"Variable name '{nameof(name)}' must start with letter", nameof(name));

    return retVal;
}

Not working under parallel

I am trying to speed up the execution for large number of dataset using parallel.
However, I encounter some list/dictionary concurrent add/update issue.

using System;
using System.Collections.Concurrent;
using System.Dynamic;
using System.Linq;
using System.Text.Json;
using net.adamec.lib.common.dmn.engine.engine.decisions;
using net.adamec.lib.common.dmn.engine.engine.runtime;
using net.adamec.lib.common.dmn.engine.parser;

public class Program
{
    public static void Main()
    {
        string DmnXmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><definitions xmlns=\"https://www.omg.org/spec/DMN/20191111/MODEL/\" xmlns:dmndi=\"https://www.omg.org/spec/DMN/20191111/DMNDI/\" xmlns:dc=\"http://www.omg.org/spec/DMN/20180521/DC/\" xmlns:di=\"http://www.omg.org/spec/DMN/20180521/DI/\" id=\"dish\" name=\"Dish\" namespace=\"http://camunda.org/schema/1.0/dmn\" exporter=\"dmn-js (https://demo.bpmn.io/dmn)\" exporterVersion=\"10.1.0\">  <inputData id=\"dayType_id\" name=\"TypeOfDay\">    <variable id=\"dayType_ii\" name=\"Type of day\" typeRef=\"string\" />  </inputData>  <inputData id=\"temperature_id\" name=\"WeatherInCelsius\">    <variable id=\"temperature_ii\" name=\"Weather in Celsius\" typeRef=\"integer\" />  </inputData>  <knowledgeSource id=\"host_ks\" name=\"Host\" />  <knowledgeSource id=\"guest_ks\" name=\"Guest Type\">    <authorityRequirement id=\"AuthorityRequirement_0vkhray\">      <requiredDecision href=\"#guestCount\" />    </authorityRequirement>  </knowledgeSource>  <businessKnowledgeModel id=\"elMenu\" name=\"El menú\" />  <decision id=\"dish-decision\" name=\"Dish Decision\">    <informationRequirement id=\"InformationRequirement_1d56kg6\">      <requiredDecision href=\"#guestCount\" />    </informationRequirement>    <informationRequirement id=\"InformationRequirement_11onl5b\">      <requiredDecision href=\"#season\" />    </informationRequirement>    <authorityRequirement id=\"AuthorityRequirement_142y75e\">      <requiredAuthority href=\"#host_ks\" />    </authorityRequirement>    <decisionTable id=\"dishDecisionTable\">      <input id=\"seasonInput\" label=\"Season\">        <inputExpression id=\"seasonInputExpression\" typeRef=\"string\">          <text>season</text>        </inputExpression>      </input>      <input id=\"guestCountInput\" label=\"GuestCount\">        <inputExpression id=\"guestCountInputExpression\" typeRef=\"integer\">          <text></text>        </inputExpression>      </input>      <output id=\"output1\" label=\"Dish\" name=\"desiredDish\" typeRef=\"string\" />      <rule id=\"row-495762709-1\">        <inputEntry id=\"UnaryTests_1nxcsjr\">          <text>\"Winter\"</text>        </inputEntry>        <inputEntry id=\"UnaryTests_1r9yorj\">          <text>&lt;= 8</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_1mtwzqz\">          <text>\"Spareribs\"</text>        </outputEntry>      </rule>      <rule id=\"row-495762709-2\">        <inputEntry id=\"UnaryTests_1lxjbif\">          <text>\"Winter\"</text>        </inputEntry>        <inputEntry id=\"UnaryTests_0nhiedb\">          <text>&gt; 8</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_1h30r12\">          <text>\"Pasta\"</text>        </outputEntry>      </rule>      <rule id=\"row-495762709-3\">        <inputEntry id=\"UnaryTests_0ifgmfm\">          <text>\"Summer\"</text>        </inputEntry>        <inputEntry id=\"UnaryTests_12cib9m\">          <text>&gt; 10</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_0wgaegy\">          <text>\"Light salad\"</text>        </outputEntry>      </rule>      <rule id=\"row-495762709-7\">        <inputEntry id=\"UnaryTests_0ozm9s7\">          <text>\"Summer\"</text>        </inputEntry>        <inputEntry id=\"UnaryTests_0sesgov\">          <text>&lt;= 10</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_1dvc5x3\">          <text>\"Beans salad\"</text>        </outputEntry>      </rule>      <rule id=\"row-445981423-3\">        <inputEntry id=\"UnaryTests_1er0je1\">          <text>\"Spring\"</text>        </inputEntry>        <inputEntry id=\"UnaryTests_1uzqner\">          <text>&lt; 10</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_1pxy4g1\">          <text>\"Stew\"</text>        </outputEntry>      </rule>      <rule id=\"row-445981423-4\">        <inputEntry id=\"UnaryTests_06or48g\">          <text>\"Spring\"</text>        </inputEntry>        <inputEntry id=\"UnaryTests_0wa71sy\">          <text>&gt;= 10</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_09ggol9\">          <text>\"Steak\"</text>        </outputEntry>      </rule>    </decisionTable>  </decision>  <decision id=\"season\" name=\"Season decision\">    <informationRequirement id=\"InformationRequirement_1sdwefx\">      <requiredInput href=\"#temperature_id\" />    </informationRequirement>    <decisionTable id=\"seasonDecisionTable\">      <input id=\"temperatureInput\" label=\"WeatherInCelsius\">        <inputExpression id=\"temperatureInputExpression\" typeRef=\"integer\">          <text></text>        </inputExpression>      </input>      <output id=\"seasonOutput\" label=\"season\" name=\"season\" typeRef=\"string\" />      <rule id=\"row-495762709-5\">        <inputEntry id=\"UnaryTests_1fd0eqo\">          <text>&gt;30</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_0l98klb\">          <text>\"Summer\"</text>        </outputEntry>      </rule>      <rule id=\"row-495762709-6\">        <inputEntry id=\"UnaryTests_1nz6at2\">          <text>&lt;10</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_08moy1k\">          <text>\"Winter\"</text>        </outputEntry>      </rule>      <rule id=\"row-445981423-2\">        <inputEntry id=\"UnaryTests_1a0imxy\">          <text>[10..30]</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_1poftw4\">          <text>\"Spring\"</text>        </outputEntry>      </rule>    </decisionTable>  </decision>  <decision id=\"guestCount\" name=\"Guest Count\">    <informationRequirement id=\"InformationRequirement_0j60f3j\">      <requiredInput href=\"#dayType_id\" />    </informationRequirement>    <knowledgeRequirement id=\"KnowledgeRequirement_0n56cqb\">      <requiredKnowledge href=\"#elMenu\" />    </knowledgeRequirement>    <decisionTable id=\"guestCountDecisionTable\">      <input id=\"typeOfDayInput\" label=\"TypeOfDay\">        <inputExpression id=\"typeOfDayInputExpression\" typeRef=\"string\">          <text></text>        </inputExpression>      </input>      <output id=\"guestCountOutput\" label=\"GuestCount\" typeRef=\"integer\" />      <rule id=\"row-495762709-8\">        <inputEntry id=\"UnaryTests_0l72u8n\">          <text>\"Weekday\"</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_0wuwqaz\">          <text>4</text>        </outputEntry>      </rule>      <rule id=\"row-495762709-9\">        <inputEntry id=\"UnaryTests_03a73o9\">          <text>\"Holiday\"</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_1whn119\">          <text>10</text>        </outputEntry>      </rule>      <rule id=\"row-495762709-10\">        <inputEntry id=\"UnaryTests_12tygwt\">          <text>\"Weekend\"</text>        </inputEntry>        <outputEntry id=\"LiteralExpression_1b5k9t8\">          <text>15</text>        </outputEntry>      </rule>    </decisionTable>  </decision>  <textAnnotation id=\"TextAnnotation_1\">    <text>Week day or week end</text>  </textAnnotation>  <association id=\"Association_18hoj4i\">    <sourceRef href=\"#dayType_id\" />    <targetRef href=\"#TextAnnotation_1\" />  </association>  <dmndi:DMNDI>    <dmndi:DMNDiagram id=\"DMNDiagram_05sfxgt\">      <dmndi:DMNShape id=\"DMNShape_1nkrqp5\" dmnElementRef=\"dayType_id\">        <dc:Bounds height=\"45\" width=\"125\" x=\"417\" y=\"377\" />      </dmndi:DMNShape>      <dmndi:DMNShape id=\"DMNShape_0wgwr3t\" dmnElementRef=\"temperature_id\">        <dc:Bounds height=\"45\" width=\"125\" x=\"188\" y=\"377\" />      </dmndi:DMNShape>      <dmndi:DMNShape id=\"DMNShape_17n98pm\" dmnElementRef=\"host_ks\">        <dc:Bounds height=\"63\" width=\"100\" x=\"646\" y=\"48\" />      </dmndi:DMNShape>      <dmndi:DMNShape id=\"DMNShape_1i9incu\" dmnElementRef=\"guest_ks\">        <dc:Bounds height=\"63\" width=\"100\" x=\"660\" y=\"198\" />      </dmndi:DMNShape>      <dmndi:DMNEdge id=\"DMNEdge_0tdfvdg\" dmnElementRef=\"AuthorityRequirement_0vkhray\">        <di:waypoint x=\"570\" y=\"245\" />        <di:waypoint x=\"660\" y=\"235\" />      </dmndi:DMNEdge>      <dmndi:DMNShape id=\"DMNShape_1uo50vq\" dmnElementRef=\"elMenu\">        <dc:Bounds height=\"46\" width=\"135\" x=\"642\" y=\"307\" />      </dmndi:DMNShape>      <dmndi:DMNShape id=\"DMNShape_0s7a8pk\" dmnElementRef=\"dish-decision\">        <dc:Bounds height=\"80\" width=\"180\" x=\"301\" y=\"48\" />      </dmndi:DMNShape>      <dmndi:DMNEdge id=\"DMNEdge_1cvfntf\" dmnElementRef=\"InformationRequirement_1d56kg6\">        <di:waypoint x=\"480\" y=\"210\" />        <di:waypoint x=\"421\" y=\"148\" />        <di:waypoint x=\"421\" y=\"128\" />      </dmndi:DMNEdge>      <dmndi:DMNEdge id=\"DMNEdge_0djoiii\" dmnElementRef=\"InformationRequirement_11onl5b\">        <di:waypoint x=\"251\" y=\"210\" />        <di:waypoint x=\"361\" y=\"148\" />        <di:waypoint x=\"361\" y=\"128\" />      </dmndi:DMNEdge>      <dmndi:DMNEdge id=\"DMNEdge_0qqxexx\" dmnElementRef=\"AuthorityRequirement_142y75e\">        <di:waypoint x=\"646\" y=\"81\" />        <di:waypoint x=\"481\" y=\"86\" />      </dmndi:DMNEdge>      <dmndi:DMNShape id=\"DMNShape_06z5z89\" dmnElementRef=\"season\">        <dc:Bounds height=\"80\" width=\"180\" x=\"161\" y=\"210\" />      </dmndi:DMNShape>      <dmndi:DMNEdge id=\"DMNEdge_1383eyj\" dmnElementRef=\"InformationRequirement_1sdwefx\">        <di:waypoint x=\"251\" y=\"377\" />        <di:waypoint x=\"251\" y=\"310\" />        <di:waypoint x=\"251\" y=\"290\" />      </dmndi:DMNEdge>      <dmndi:DMNShape id=\"DMNShape_0qbhe8q\" dmnElementRef=\"guestCount\">        <dc:Bounds height=\"80\" width=\"180\" x=\"390\" y=\"210\" />      </dmndi:DMNShape>      <dmndi:DMNEdge id=\"DMNEdge_131oa1j\" dmnElementRef=\"KnowledgeRequirement_0n56cqb\">        <di:waypoint x=\"691\" y=\"307\" />        <di:waypoint x=\"570\" y=\"262\" />      </dmndi:DMNEdge>      <dmndi:DMNEdge id=\"DMNEdge_1avtdb1\" dmnElementRef=\"InformationRequirement_0j60f3j\">        <di:waypoint x=\"480\" y=\"377\" />        <di:waypoint x=\"480\" y=\"310\" />        <di:waypoint x=\"480\" y=\"290\" />      </dmndi:DMNEdge>      <dmndi:DMNShape id=\"DMNShape_0bblyhb\" dmnElementRef=\"TextAnnotation_1\">        <dc:Bounds height=\"45\" width=\"125\" x=\"328\" y=\"477\" />      </dmndi:DMNShape>      <dmndi:DMNEdge id=\"DMNEdge_0aqnkob\" dmnElementRef=\"Association_18hoj4i\">        <di:waypoint x=\"480\" y=\"422\" />        <di:waypoint x=\"391\" y=\"477\" />      </dmndi:DMNEdge>    </dmndi:DMNDiagram>  </dmndi:DMNDI></definitions>";
        string jsonString = "[{\"TypeOfDay\":\"Holiday\",\"WeatherInCelsius\":24},{\"TypeOfDay\":\"Weekend\",\"WeatherInCelsius\":4}]";
        ConcurrentBag<DmnDecisionResult> results = new ConcurrentBag<DmnDecisionResult>();
        System.Text.Json.JsonDocument.Parse(jsonString).RootElement
            .EnumerateArray()
            .AsParallel()
            .ForAll(param =>
            {
                var def = DmnParser.ParseString13(DmnXmlString);
                var ctx = DmnExecutionContextFactory.CreateExecutionContext(def);
                foreach (var property in System.Text.Json.JsonDocument.Parse(param.GetRawText()).RootElement.EnumerateObject())
                {
                    dynamic propertyvalue = getPropertyValue(property.Value);
                    ctx.WithInputParameter(property.Name.Trim().Replace(' ', '_'), propertyvalue);
                }
                var result = ctx.ExecuteDecision("Dish Decision");
                results.Add(result);
            });
        Console.WriteLine(JsonSerializer.Serialize(results.ToList()));
    }

    private static dynamic getPropertyValue(JsonElement element)
    {
        switch (element.ValueKind)
        {
            case JsonValueKind.Null:
                return null;

            case JsonValueKind.Number:
                if (element.GetRawText().Contains("."))
                    return element.GetDouble();
                else
                    return element.GetInt32();

            case JsonValueKind.False:
                return false;

            case JsonValueKind.True:
                return true;

            case JsonValueKind.Undefined:
                return null;

            case JsonValueKind.String:
                return element.GetString();

            case JsonValueKind.Object:
                return Newtonsoft.Json.JsonConvert.DeserializeObject<ExpandoObject>(element.GetRawText(), new Newtonsoft.Json.Converters.ExpandoObjectConverter());
            //case JsonValueKind.Array:
            //    result = srcData.EnumerateArray()
            //        .Select(o => new ReflectionDynamicObject { RealObject = o })
            //        .ToArray();
            //    break;
            default:
                return null;
        }
    }
}

System.InvalidOperationException: 'Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.'

image

How run all decisions ?

hi,

I would like run all decisions from example simulation.dmn

`using System;
using net.adamec.lib.common.dmn.engine.parser;
using net.adamec.lib.common.dmn.engine.engine.execution.context;
using net.adamec.lib.common.dmn.engine.engine.definition;

namespace ENGINE
{
class Program
{
static void Main(string[] args)
{
string fileName = "simulation.dmn";
var model=DmnParser.Parse13(fileName);
var def= DmnDefinitionFactory.CreateDmnDefinition(model);
//var def = DmnParser.Parse(fileName, DmnParser.DmnVersionEnum.V1_3);
//var ctx = DmnExecutionContextFactory.CreateExecutionContext(def);
var ctx = DmnExecutionContextFactory.CreateExecutionContext(def, configure =>
{
configure.EvaluateTableOutputsInParallel = false;
configure.EvaluateTableRulesInParallel = true;
configure.RecordSnapshots = false;
configure.ParsedExpressionCacheScope = ParsedExpressionCacheScopeEnum.Definition;
});
//var dyna = new { Name = "season", IsOk = true, Direct="Winter" };
//ctx.WithInputParameter("season", dyna);
ctx.WithInputParameter("season", "Winter");
ctx.WithInputParameter("guestCount", 1);
ctx.WithInputParameter("guestsWithChildren", true);

	//var outcome = ctx.ExecuteDecision("Dish");
	var outcome = ctx.ExecuteDecision("Beverages");


	foreach (var result in outcome.Results)
	{
	    foreach (var variable in result.Variables)
	    {
		Console.WriteLine(variable.Name + ": " + variable.Value);
	    }
	}
    Console.WriteLine("Hello World!");
}
}

}`

Thanks for help

XML file

I didn't found the way to export to xml, Does is possible to do that?

Return matched rules as part of Decision Result

We would like to return back any rule details which matched as part of the decision evaluation.
We need to do this for audit reasons, so we can let users review the decisions and show them which rules were matched after a decision had been arrived at.

I have checked out the master branch and have modified this and all the tests to return back the positively matched rules as part of the decision result.

I would like to submit this as a PR for review, but I don't seem to have the ability to create a branch from an issue.
Therefore I would like to submit the attached patch for the master branch for your review.

Kind Regards
Noel
0001-Added-in-the-abilty-to-return-back-the-positively-ma.zip

DMN "CodeCoverage"

Is there a way to measure the "code coverage" when executing DMN decisions? The count of rules evaluated or something like that? We have implemented some unit testing to be able to modify DMNs but validating that we dont break anything.
t would be nice to know how much is the DMN file really tested with our defined unit tests.

Missing floor numeric function

Hello Everyone,

at first I want to thank you for the useful library you have implemented.
It's working great and as expected but we have one problem regarding the supported FEEL functions.

For example, it's not possible to use floor function.
So is it possible to include a wider range of the FEEL numeric functions?
Or is there a way to extend the current implementation to support the missing ones?

Best Regards

Array/list inputs to engine and/or simulator?

Hi again, Radek. I have reviewed the documentation and some of the source code, but I cannot confirm whether or not array/list inputs are usable either in the engine or the simulator. I am able to evaluate inputs like ["a","b","c"] in the Camunda engine using FEEL's 'some x in y satisfies z' construct.

I see that the simulator documentation says: When the type is not identified by parser from the definition (or it's identified but not as the known type), the entry is via text field and the combo box is provided to let the user choose a know type to which the raw value should be converted before passing to the execution context as the input parameter. I am guessing, however, that this does not allow me to enter an object like an array.

I think I can work around this by breaking my decision into two or more tables or expressions, so it's not a killer issue for me at the moment.

Cheers,
Michael

PS. It's really generous of you to contribute products like this to the public domain. Much appreciated.

Memory leak detected within DmnExecutionContext class

Hi! While working with the DmnExecutionContext class I have found a possible memory leak related with the property ParsedExpressionsCache. When creating multiple execution contexts the stale cache entries related to out of scope contexts are not removed, staying permanently cached even though the context to which are related no longer exists.

This causes a memory leak when a long running application creates multiple instances of DmnExecutionContext, like a webapi creating a new context per request.

duration nog conforming to FEEL specification

Hi Radec,

Expressions involving calculations with durations is not behaving as expected:

  • date("2023-01-01") + duration("P1M") * 12 results in 12/27/2023 12:00:00 AM instead of 2023-12-01
  • P12M == P1Y but (12 * P1M) != P12M.

The issue seems to be that cardinal periods are converted to timespans before being used in expression involving calculations on durations.

See example attached.

Kind regards,
Radoslaw

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.