Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1157 unarytests decisiontable #672

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

StrayAlien
Copy link
Contributor

This may surprise you all, but we actually do not yet assert anywhere on the usage of unary tests for input and output values in decisions tables. Given the recent changes to the spec regarding unary tests I thought I'd revisit the tests for decision tables unary tests. There are none. So ... here are some ...

There are some interesting things to note in here - specifically around the vagueness of the "applied to" part of the spec in alternative c. and booleans. Please (please!) tell me if this is not correct.

Here is the new spec text:

A UnaryTests is satisfied if and only if one of the following alternatives is true: 

a) One of the expressions in the UnaryTests evaluates to a value, and the implicit value is equal to that value. 
b) One of the expressions in the UnaryTests evaluates to a list of values, and the implicit value is equal to at least one of the values in that list. 
c) One of the expressions in the UnaryTests evaluates to true when the implicit value is applied to it. 
d) One of the expressions in the UnaryTests is a boolean expression using the special ‘?’ variable and that expression evaluates to true when the implicit value is assigned to ‘?’.

What about all the stuff in table 55 for testing inclusion? Like a list of ranges? (we'll discuss in a moment).

here we go:

Booleans

If I test boolean constant false against the unary tests with a boolean constant true - what do you expect? At this time, we seem to be expecting that the unary test is not satisfied.

But, the constant value true is an expression - and according to the "c" option above, if it evaluates to true then it is satisfied. But ... in practice, that is not what people are expecting - I tried it and some existing tests failed (as I recall). And this is where the kind of vague "applied to" thing comes in. I think the spec is assuming here that an "expression" is really a unary type comparison and not just any expression ... and 'applied to" really means that the expression takes into account the tested-for value.

So, if I tested false against (say) =false, the unary test is satisfied, and I think this is what option "c" is anticipating.

Likewise, if I tested false against any non-unary expression that evaluates to true like (say) 1=1 then implicitly, I think we might expect it to be satisfied, but, this is simply an extension of the boolean constant true situation and it is not satisfied.

This applies to DT rules as well. Here is a simple illustration. An input expression of constant false with two rules. The first to match against constant true, the second to match against constant false. The first rule will not be satisfied, the second will. So, an expression that simply evaluates to true is a bit weird.

    <decision name="decision" id="_decision">
        <variable name="decision"/>
        <decisionTable>
            <input>
                <inputExpression>
                    <text>false</text>
                </inputExpression>
            </input>
            <output/>
            <rule>
                <inputEntry>
                    <text>true</text>
                </inputEntry>
                <outputEntry>
                    <text>"fail"</text>
                </outputEntry>
            </rule>
            <rule>
                <inputEntry>
                    <text>false</text>
                </inputEntry>
                <outputEntry>
                    <text>"success"</text>
                </outputEntry>
            </rule>
        </decisionTable>
    </decision>

A list of results

This is option (b) is the new unary tests text. "One of the expressions in the UnaryTests evaluates to a list of values, and the implicit value is equal to at least one of the values in that list."

This excludes the possibility that the list may contain ranges. We have 'in' tests that assert that a list may contain ranges, and those ranges are tested against for inclusion, not equality.

In "Table 55: Semantics of decision table syntax" we see reference to grammar rule 49.c. Now, I'm a bit confused about what this table us really telling us, but I think it dovetails with the syntax for unary tests. Tell me if I am wrong. The third row says that a list may have ranges and they are checked for inclusion, not equality.

The new unary test text says that if a result is a list, then check for equality in the elements.

Should the new text be ""One of the expressions in the UnaryTests evaluates to a list of values, and the implicit value is equal to at least one of the values in that list, or if the list item value is a range, then the implicit value is checked for inclusion in that range".

usage of the '?' special char

Now this can get a little weird.

The spec option (d) says the "One of the expressions in the UnaryTests is a boolean expression using the special ‘?’ variable and that expression evaluates to true when the implicit value is assigned to ‘?’."

So, if the expression does not evaluate to boolean true .... ? Like ... if I test (say) "foo" against the unary test "?" ... (with just the "?" special char nothing else) .... the expression will result in "foo" .. not true .... will this mean option (a), the equality check is satisfied instead?

Also ... (here we go), what if I test boolean constant false against "?", it it is a boolean expression but does not evaluate to true ....

Here I have assumed that even if it does not return true, and equality check as per option (a) can apply.

usage of the '?' special char inside list results

If I test (say) 123 against a unary test that has a list expression like [345, ? = 123, 456] then, this is testing against [345, true, 456] and, according to the spec, values inside lists are checked for equality and this would not be satisfied as the "?" char is not used as per option (d).

... or is it?

Apols for the long PR description, but, sometimes when you lift the lid on something to try to understand it explicitly, you just kind of end up wondering what the spec is trying to say, not what it actually says ..

@opatrascoiu
Copy link
Contributor

opatrascoiu commented Oct 16, 2024

@StrayAlien Thank you for the tests. You raised a few interesting issues :)

I have noticed that all decisions require several inputs but the <informationRequirement> tags are missing. Please add them and the corresponding <inputData> with the correct typeRef. We agreed a while back that all <inputData> must have a typeRef (e.g. number or string).

I will look again at the tests once the above is addressed.

Thank you.

@StrayAlien
Copy link
Contributor Author

Hi @opatrascoiu - the decision tables do not have information requirements, nor do the models have any input data. The input clauses of decision table are just literal expressions. In these tests, all the input clauses are just simple literal expression with a value.

Regarding the typing of those literal expressions. According to the spec on where types are enforced, adding a type would have no effect on a literal expression.

As I've outlined here: https://issues.omg.org/issues/spec/DMN#issue-55153. The type system has some large holes. That is a different topic and can be discussed separately I guess.

But, here, to keep the tests as simple and clear as possible, the decision tables just have a literal expression with a constant value as input.

@opatrascoiu
Copy link
Contributor

opatrascoiu commented Oct 17, 2024

@StrayAlien Got it. You are using a simpler pattern - constant input expressions.

I see there is a mixture of DTs with and without constraints applied on inputs and outputs.

What is the purpose of this PR? To add test cases for the constraints on input and output or to test the expressions in the inputEntry inside rules ?

I suggest we break the test cases into two files with meaningful names if the intent is to cover both.

Also, could you point to the part in the spec that you used for the operational semantics of the constraints on input and output. I can think of several ways of handling them (e.g. input is invalid, DT returns null or execution continues with null as input).

@StrayAlien
Copy link
Contributor Author

StrayAlien commented Oct 17, 2024

hey @opatrascoiu - cool, thanks. Yes, about as simple as it gets for decision tables. Keeps it clean and focussed on the assertions.

The tests do cover unary tests for input and output clauses. I can break that up. No sweat.

Re a spec reference. The trouble is, all that stuff re constant true/false is not described in the spec - I guess that is my point. It is pretty unclear. As is how unary test relate to decision tables.

Like, table 55. ... "Semantics of decision table syntax" .. like .. what does that actually mean? The only other place table 55 is mentioned is "The semantics of comparison expressions involving ranges" ..... so is that decision specific? I doubt it.

But the flip side, is that the stuff in table 55 does not seem to hold when dealing with the new (or old!) text for how a unary tests are satisfied. They seem at odds with each other.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants