|
| 1 | +# JSONPath axiomatic semantics |
| 2 | + |
| 3 | +** WORK IN PROGRESS ** |
| 4 | + |
| 5 | +## sequences of JSON values |
| 6 | + |
| 7 | +A JSONPath is modelled as mapping one sequence of JSON values to another sequence of JSON values. |
| 8 | +The `<>` notation is used for sequences, to try to distinguish these from JSON arrays. |
| 9 | + |
| 10 | +Empty sequence: `<>`. |
| 11 | + |
| 12 | +Concatenation: `<a, b> = <a> ^ <b>`. |
| 13 | + |
| 14 | +So, for example, the sequence `<a, b, c>` is equivalent to the concatenation of three single item |
| 15 | +sequences `<a> ^ <b> ^ <c>`. |
| 16 | + |
| 17 | +## sequence semantics |
| 18 | +A selector `s` takes a sequence of values and applies to each one separately. |
| 19 | +The results are then concatenated. |
| 20 | + |
| 21 | +``` |
| 22 | +<> s = <> |
| 23 | +(x^y)s = (x s)^(y s) |
| 24 | +``` |
| 25 | + |
| 26 | +## JSON object construction |
| 27 | + |
| 28 | +If `m` and `n` are JSON objects with no keys in common, then `m ∪ n` is the JSON object containing |
| 29 | +all the mappings of `m` and `n` (but no others). |
| 30 | + |
| 31 | +## compound path semantics |
| 32 | + |
| 33 | +If JSONPath `p` is selector `s` followed by JSONPath `t`, then for all JSON values `v`: |
| 34 | +``` |
| 35 | +<v>p = (<v>s)t |
| 36 | +``` |
| 37 | + |
| 38 | +## root selector semantics |
| 39 | +`$` is effectively a no-op. If `t` is a JSONPath (without a leading `$`), then: |
| 40 | +``` |
| 41 | +<v>$t = <v>t |
| 42 | +``` |
| 43 | +Question: do we need to use something like quasi quotes to clarify the above? |
| 44 | + |
| 45 | +## dot child |
| 46 | +If `o` is a JSON object which does not have key `k`, then: |
| 47 | +``` |
| 48 | +<o>.k = <> |
| 49 | +``` |
| 50 | +and: |
| 51 | +``` |
| 52 | +<o ∪ {k:v}>.k = <v> |
| 53 | +``` |
| 54 | + |
| 55 | +## union |
| 56 | +``` |
| 57 | +<a>[u, v] = (<a>[u]) ^ (<a>[v]) |
| 58 | +``` |
| 59 | + |
| 60 | +## bracket child |
| 61 | +If `o` is a JSON object which does not have key `k` (for certain forms of k...), then: |
| 62 | +``` |
| 63 | +<o>[k] = <> |
| 64 | +``` |
| 65 | +and: |
| 66 | +``` |
| 67 | +<o ∪ {k:v}>[k] = <v> |
| 68 | +``` |
| 69 | + |
| 70 | +## array slice |
| 71 | +If `a` is an array, then: |
| 72 | +``` |
| 73 | +... details! ... |
| 74 | +``` |
| 75 | + |
| 76 | +If `a` is not an array and `sl` is a slice expression, then: |
| 77 | +``` |
| 78 | +<a>[sl] = <> |
| 79 | +``` |
| 80 | + |
| 81 | +## recursive descent |
| 82 | +If `z` is a scalar: |
| 83 | +``` |
| 84 | +<z>.. = <z> |
| 85 | +``` |
| 86 | +If `o` is an empty object: |
| 87 | +``` |
| 88 | +<o>.. = <> |
| 89 | +``` |
| 90 | + |
| 91 | +If `o` is a JSON object which does not have key `k`, then: |
| 92 | +If `o` is an object comprised of `k:v` and an object p: |
| 93 | +``` |
| 94 | +<o ∪ {k:v}>.. = (<v>)^(<v>..)^(<o>..) |
| 95 | +``` |
| 96 | +Note: since an object can be deconstructed to the form `o ∪ {k:v}` for arbitrary key `k` in |
| 97 | +the original object, the ordering of the result is only partially defined. |
| 98 | + |
| 99 | +If `a` is an empty array: |
| 100 | +``` |
| 101 | +<a>.. = <> |
| 102 | +``` |
| 103 | +If `h` is a JSON value and `t` is a JSON array: |
| 104 | +``` |
| 105 | +(<h>^t).. = (<h>)^(<h>..)^(t..) |
| 106 | +``` |
0 commit comments