DMN - Singleton list conversion for inequalities

40 views
Skip to first unread message

Ryan B

unread,
May 10, 2022, 11:24:12 AM5/10/22
to Drools Usage
Example:

There is some inconsistency in the behavior of singleton list conversion for equalities and inequalities.

I'm using the programatic api in package: org.kie:kie-dmn-core:7.61.0.Final

Example code:

List<Map<String, Object>> myList = ImmutableList.of(
ImmutableMap.of("name", "name1", "value", BigDecimal.ONE),
ImmutableMap.of("name", "name2", "value", new BigDecimal(2)),
ImmutableMap.of("name", "name3", "value", new BigDecimal(3))
);

EvaluationContext evalContext = ((FEELImpl) feel).newEvaluationContext(
Collections.emptyList(), Collections.emptyMap());
evalContext.setValue("MY_LIST", myList);

// null because of EvalHelper.compare(). Should singleton list be converted in this case?
System.out.println(feel.evaluate("MY_LIST[name=\"name2\"].value >= 1", evalContext));

// true because of EvalHelper.isEqual().  This method does the conversion and returns true for 2 = 2.
System.out.println(feel.evaluate("MY_LIST[name=\"name2\"].value >= 2", evalContext));

// true because of EvalHelper.isEqual().  Same reason as above.
System.out.println(feel.evaluate("MY_LIST[name=\"name2\"].value = 2", evalContext));

// true because of manual conversion to first element
System.out.println(feel.evaluate("MY_LIST[name=\"name2\"].value[1] >= 1", evalContext));

---
Discussion:

Conversion of a singleton list to the value of the single element ([a] -> a) should take place any time a list is not expected, as stated in the DMN 1.3 spec:

a singleton list L, when used in an expression where a list is not expected, behaves as if L[1] is written

Also, inequalities are not supported for list types as stated:

The other comparison operators are defined only for the datatypes listed in Table 54 (does not include list type)

Since lists are not expected in inequalities, when a singleton list is compared to a value, should the singleton list be converted to its first element?  There is ambiguity in DMN spec in regards to this, as it also states:

e1 and e2 must both be of the same kind/datatype (is this pre or post conversion?)

Why is it converted for the equals scenario?  

See call stack :
InfixOpNode.evaluate (case: GTE) ->
EvalHelper.compare() ->
EvalHelper.isEqual()

Thank you!!

Matteo Mortari

unread,
May 11, 2022, 4:47:44 AM5/11/22
to Drools Usage
Hi Ryan,

when you say:
>There is ambiguity in DMN spec in regards to this, as it also states: e1 and e2 must both be of the same kind/datatype (is this pre or post conversion?)

you have hit the nail on the head.

In the previous versions of DMN spec, the [2]=2 held true.

In subsequent versions of DMN, the automatic conversion is subject to the chapter "10.3.2.9.4 Type conversions", so the conversion "from singleton list" happens only for "Invocation context Table 63".
So theoretically from DMNv1.3 it should work that only:
list contains([1, 2, 3], [2]) = list contains([1, 2, 3], 2) // is true=true, hence true
but not that:
[2]=2 // is true

But as you can imagine, this is a drastic backward incompatible change, that's why we tried to keep at least the [x]=x equivalence, and that is generating in your scenario the result you are getting.

The most appropriate DMN and FEEL you can write today, is when you have a list Vs element in an equality/inequality, you always use the list[1] accessor,
as the conversion "from singleton list" is defined only for "Invocation context Table 63" but not for equality/inequality.

I'm happy to continue engaging in the conversation about this topic, I hope I was able at least to shed some light on the balance I'm trying to achieve without being too strict and obliterate backward compatibility as an implementation.

Hope this helps!
MM

--
You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/drools-usage/08d7f5df-de25-4739-a26d-3c121ce3b6f8n%40googlegroups.com.


--

Ryan B

unread,
May 12, 2022, 10:44:19 AM5/12/22
to Drools Usage
Hi Matteo!

Thanks for the clarification.  Do you know if the spec will be updated to allow singleton list conversion for equality?   On "Table 52" it specifies that equality must be the same type, and on "Table 53" it specifies strict guidelines for list equality.  

I would argue (and I'm guessing you would agree since it is implemented in Drools) that allowing singleton list conversion for equality does no harm.  In the case of [2] = 2, if you convert the singleton list to a number, you have 2=2 which is true.  If you convert the integer to a singleton list, you have [2] = [2] which is also true, because 2 will always be in the first position.  So, all in all, it does not break list equality semantics other than the type constraint, which I imagine is not relevant most of the time.  Also, given that prior versions allowed it, it should not be a big problem for backwards compatibility.  If this is allowable, it follows that it is also allowable for inequalities, since inequalities are undefined for lists anyway.  Again, no harm done.  

It would be nice if the spec adopted that since there is a lot of convenience, and not many downsides.  What do you think?

Thanks again!!

Matteo Mortari

unread,
May 16, 2022, 3:45:24 AM5/16/22
to Drools Usage
Hi Ryan,
no problem and always glad to help.

With regards to the DMN specification, I wouldn't hold my breath, as this implicit conversion has been formalized this way I believe being the most basic common ground of all possible compromises?
You are free (as anyone) to raise this at the OMG's RTF, I would recommend while doing so in being diligent in laying your arguments while opening the jira.

In the meantime, I can just reiterate my previous suggestion, when you are using equality/disequality operator with a list, better to always use the [1] postfix accessor

Hope this helps?
MM

Ryan B

unread,
May 16, 2022, 4:56:08 PM5/16/22
to Drools Usage
Definitely helps, and really appreciate the conversation!

Thanks again,

Ryan

Reply all
Reply to author
Forward
0 new messages