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

Add a non-deterministic test not involving objects #66

Merged
merged 1 commit into from
Mar 14, 2024

Conversation

glyn
Copy link
Contributor

@glyn glyn commented Mar 12, 2024

The non-determinism in this case arises because of the interleaving of descendants allowed by RFC 9535 Section 2.5.2.2.

Note that there is more non-determinism in the ordering of descendants, but much of this is removed by the applications of the child wildcard ([*]).

The list of the input node and its descendants (the result of .. before [*] is applied) can be in any of these orders:

[[[[1]],[2]],[[1]],[1],[2],1,2]
[[[[1]],[2]],[[1]],[1],[2],2,1]
[[[[1]],[2]],[[1]],[1],1,[2],2]
[[[[1]],[2]],[[1]],[2],[1],1,2]
[[[[1]],[2]],[[1]],[2],[1],2,1]
[[[[1]],[2]],[[1]],[2],2,[1],1]

Notice that these all satisfy the rules in Section 2.5.2.2:

  • nodes of any array are visited in array order, and
  • nodes are visited before their descendants.

Ref: https://github.com/glyn/jsonpath-nondeterminism

/cc @gregsdennis @jg-rp @f3ath @hiltontj who were involved in the initial discussion of non-deterministic tests.

The non-determinism in this case arises because of the interleaving of
descendants allowed by RFC 9535 Section 2.5.2.2.

Note that there is more non-determinism in the ordering of descendants,
but much of this is removed by the applications of the child wildcard
([*]).

The list of the input node and its descendants (the result of ..
before [*] is applied) can be in any of these orders:

[[[[1]],[2]],[[1]],[1],[2],1,2]
[[[[1]],[2]],[[1]],[1],[2],2,1]
[[[[1]],[2]],[[1]],[1],1,[2],2]
[[[[1]],[2]],[[1]],[2],[1],1,2]
[[[[1]],[2]],[[1]],[2],[1],2,1]
[[[[1]],[2]],[[1]],[2],2,[1],1]

Notice that these all satisfy the rules in Section 2.5.2.2:

* nodes of any array are visited in array order, and
* nodes are visited before their descendants.

Ref: https://github.com/glyn/jsonpath-nondeterminism
Copy link
Collaborator

@gregsdennis gregsdennis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The examples in your opening comment don't exactly line up with this test, but I get the point.

Comment on lines +408 to +409
[[[1]],[2],[1],1,2],
[[[1]],[2],[1],2,1]
Copy link
Collaborator

@gregsdennis gregsdennis Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect we'd want all of the orderings here.

These should be valid as well, right?

[[[1]],[1],1,[2],2]
[[[1]],[1],[2],1,2]
[[[1]],[1],[2],2,1]
[[[1]],[2],2,[1],1]

I think the only constraints are:

  • [[1]] comes before [2] (array order) and [1] (descendant)
  • [2] comes before 2 (descendant)
  • [1] comes before 1 (descendant)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there's a way we can express the constraints themselves rather than listing all of the possibilities.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be valid as well, right?

Although valid permutations, applying the wildcard selector to 1 and 2 will never produce a node, so their position has no impact on the resulting node list.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applying the wildcard selector to 1 and 2 will never produce a node

They don't have to produce a node for these orderings. I'm not sure what point you're making.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might have misunderstood what you were saying 😞

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect we'd want all of the orderings here.

These should be valid as well, right?

[[[1]],[1],1,[2],2]
[[[1]],[1],[2],1,2]
[[[1]],[1],[2],2,1]
[[[1]],[2],2,[1],1]

No, these are the result of .. before [*] is applied. See section 2.5.2.2 of the RFC. Actually, I made the same mistake the other day, see "Confession" in my recent blog post.

I think the only constraints are:

* `[[1]]` comes before `[2]` (array order) and `[1]` (descendant)

* `[2]` comes before `2` (descendant)

* `[1]` comes before `1` (descendant)

Those are constraints on the traversal order. The RFC requires that [*] is applied to the input node and its descendants.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there's a way we can express the constraints themselves rather than listing all of the possibilities.

@gregsdennis I've given that a lot of thought. The best description of the constraints that I know of is in the RFC, but that's not amenable to coding in a testcase. The difficulty is that a mixture of deterministically and non-deterministically ordered subsections are flattened into the resultant nodelist and it's very hard to keep track of what's going on. If someone can think of a way of encoding this rather than listing all the possibilities, that would be very interesting. For the moment, I think generating the list of possibilities is the most reliable approach.

Copy link
Collaborator

@gregsdennis gregsdennis Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are the result of .. before [*] is applied.

This doesn't make sense. .. on its own doesn't do anything. It merely informs the [*] that it should recurse.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are the result of .. before [*] is applied.

This doesn't make sense. .. on its own doesn't do anything. It merely informs the [*] that it should recurse.

That's not what RFC 9535 says. Section 2.5.2.2 explains the semantics of ..[<selectors>] in terms of first visiting the input value and its descendants to form the list of nodes D1, ..., Dn (where n >= 1 and D1 is the input value).

So that's the semantics of the .. part of ..[*], even though .. on its own is not valid syntax in the RFC.

Then, and this is crucial, the RFC says:

For each i such that 1 <= i <= n, the nodelist Ri is defined to be a result of applying the child segment [] to the node Di.

So, in this example, we need to apply [*] to each of the input node and its descendants. We then concatenate the resultant nodelists to form the result of ..[*].

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're confident that these are the only two possibilities, I'm happy to go with it. I still don't understand why the others I listed aren't valid outputs, though.

@jg-rp
Copy link
Contributor

jg-rp commented Mar 12, 2024

I've cobbled together a nondeterministic recursive descent visitor in JSON-P3 (PR #9).

It does, after enough test runs, produce each of the valid orderings listed here, and the results match those in this PR. 👍

@glyn
Copy link
Contributor Author

glyn commented Mar 12, 2024

I've cobbled together a nondeterministic recursive descent visitor in JSON-P3 (PR #9).

It does, after enough test runs, produce each of the valid orderings listed here, and the results match those in this PR. 👍

@jg-rp thanks for the validation.

@glyn glyn merged commit b4b10ea into jsonpath-standard:main Mar 14, 2024
2 checks passed
@glyn glyn deleted the interleaving branch March 14, 2024 23:06
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.

3 participants