colregs 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/data/applicability.json +270 -270
- package/data/facts.json +19 -19
- package/data/i18n/en.json +3 -3
- package/data/i18n/fi.json +3 -3
- package/data/version.json +1 -1
- package/docs/adr/0011-api-shape.md +7 -7
- package/docs/adr/0012-trace-and-rule2-departure-api.md +2 -2
- package/docs/adr/0016-encounter-roles-are-pooled-across-frames.md +82 -0
- package/docs/adr/0017-closed-vocabularies-are-prefixed-identifiers.md +105 -0
- package/docs/budgets.json +4 -1
- package/docs/decisions.md +6 -0
- package/docs/identifiers.md +73 -59
- package/docs/part-b-invariants.md +19 -18
- package/docs/requirements.md +72 -72
- package/fixtures/situation-fixtures.json +600 -329
- package/package.json +1 -1
- package/schema/applicability.schema.json +59 -59
- package/schema/conduct-evaluation.schema.json +1 -1
- package/schema/encounter-evaluation.schema.json +6 -6
- package/schema/evaluation.schema.json +2 -2
- package/schema/facts.schema.json +4 -4
- package/schema/i18n-catalog.schema.json +2 -2
- package/schema/situation-fixtures.schema.json +39 -0
- package/schema/situation.schema.json +3 -3
package/docs/identifiers.md
CHANGED
|
@@ -24,6 +24,17 @@ but it is a name in a namespace and a consumer reads the paragraph out of
|
|
|
24
24
|
Paragraph-keying is argued in ADR 0001 and required by REQ-MODEL-4; nothing
|
|
25
25
|
here reopens either.
|
|
26
26
|
|
|
27
|
+
**Jurisdiction values sit beside paragraph paths in this class, and for the
|
|
28
|
+
same reason.** `intl` and `us/inland` are not names this package coined:
|
|
29
|
+
jurisdiction is a coordinate with REQ-SCOPE-2's own `<body>/<waters>`
|
|
30
|
+
grammar, its left segment borrowed from ISO 3166, the whole value doubling
|
|
31
|
+
as a corpus key and a `data/text/` filesystem path — its sibling axis,
|
|
32
|
+
`language`, is a bare BCP 47 tag for the same reason. A jurisdiction value
|
|
33
|
+
is immutable under REQ-MODEL-10 like any identifier here — renaming
|
|
34
|
+
`us/inland` would break every stored provenance and corpus path — it just
|
|
35
|
+
carries no prefix, because the grammar that owns it already keeps it stable
|
|
36
|
+
and collision-free (ADR 0017).
|
|
37
|
+
|
|
27
38
|
**Vocabulary identifiers carry a type prefix.** These names are this
|
|
28
39
|
package's own — nothing in COLREGS calls anything `masthead` or `nuc`. They
|
|
29
40
|
share one flat string space across five files, and before the prefix they
|
|
@@ -31,7 +42,11 @@ collided in it: `towing` was simultaneously a light id (Rule 21(d)) and an
|
|
|
31
42
|
`activity` value (Rule 24(a)), so a consumer holding the string `towing`
|
|
32
43
|
could not say what it was a name *for* without knowing which field it came
|
|
33
44
|
out of. The prefix makes the namespace part of the identifier, which
|
|
34
|
-
resolves that collision by construction rather than by convention.
|
|
45
|
+
resolves that collision by construction rather than by convention. The same
|
|
46
|
+
shape recurs inside the closed vocabularies themselves: `shall-not-impede`
|
|
47
|
+
names both a modality and a role, and `none` names both a role and an
|
|
48
|
+
encounter — resolved the identical way, `modality:shall-not-impede` and
|
|
49
|
+
`role:shall-not-impede` being two names rather than one (ADR 0017).
|
|
35
50
|
|
|
36
51
|
## The scheme
|
|
37
52
|
|
|
@@ -42,6 +57,10 @@ resolves that collision by construction rather than by convention.
|
|
|
42
57
|
| `fact:<key>` | fact keys — the input vocabulary (`data/facts.json`) | `fact:activity`, `fact:length_m`, `fact:making_way`, `fact:on_mooring_buoy` |
|
|
43
58
|
| `<fact>:<value>` | values of an enumerated fact | `activity:nuc`, `position:anchored`, `propulsion:sail`, `obstruction_side:port` |
|
|
44
59
|
| `rel:<name>` | the five relation verbs (`data/applicability.json`) | `rel:includes`, `rel:in_lieu_of`, `rel:exempts` |
|
|
60
|
+
| `modality:<value>` | modality values (`data/applicability.json` `modalities`) | `modality:shall`, `modality:may` |
|
|
61
|
+
| `role:<value>` | effect role values (`data/applicability.json` `effects.roles`) | `role:give-way`, `role:none` |
|
|
62
|
+
| `encounter:<value>` | effect encounter values (`data/applicability.json` `effects.encounters`) | `encounter:head-on`, `encounter:none` |
|
|
63
|
+
| `category:<value>` | entry category values (`data/applicability.json` `categories`) | `category:precedence`, `category:display` |
|
|
45
64
|
|
|
46
65
|
The prefix names the namespace the identifier lives in. For a fact *value*
|
|
47
66
|
that namespace is the fact itself, written bare: `activity:nuc`, not
|
|
@@ -72,9 +91,9 @@ for a better idea, logging the change. What would settle it: the first
|
|
|
72
91
|
two-subject entry — Rule 18 — actually being written against it. This
|
|
73
92
|
section answers `Q-28`.
|
|
74
93
|
|
|
75
|
-
A `display` entry reads one vessel. A `classification` or
|
|
76
|
-
entry reads two, and needs to say *whose*
|
|
77
|
-
is three segments:
|
|
94
|
+
A `category:display` entry reads one vessel. A `category:classification` or
|
|
95
|
+
`category:precedence` entry reads two, and needs to say *whose*
|
|
96
|
+
`fact:activity` it means. The form is three segments:
|
|
78
97
|
|
|
79
98
|
```
|
|
80
99
|
<subject>:<class>:<key>
|
|
@@ -82,14 +101,14 @@ is three segments:
|
|
|
82
101
|
|
|
83
102
|
| segment | values |
|
|
84
103
|
|---|---|
|
|
85
|
-
| subject | `
|
|
104
|
+
| subject | `self`, `other`, `pair` |
|
|
86
105
|
| class | `fact`, `kin`, `geo`, `hist` |
|
|
87
106
|
| key | the identifier as it already exists, or a new one in a new class |
|
|
88
107
|
|
|
89
|
-
`
|
|
90
|
-
`
|
|
108
|
+
`self:fact:activity`, `other:kin:heading_deg`, `pair:geo:in_sight`,
|
|
109
|
+
`self:hist:was_overtaking`.
|
|
91
110
|
|
|
92
|
-
**A key with no subject segment means `
|
|
111
|
+
**A key with no subject segment means `self:`.** This is the whole of the
|
|
93
112
|
backward-compatibility story and it is why the subject is a *prefix* rather
|
|
94
113
|
than a change to the fact keys. `fact:activity` still spells `fact:activity`
|
|
95
114
|
and still denotes what it always denoted, so every predicate in
|
|
@@ -97,14 +116,14 @@ and still denotes what it always denoted, so every predicate in
|
|
|
97
116
|
`fixtures/applicability-fixtures.json` and every stored citation a consumer
|
|
98
117
|
holds stays correct unedited — `REQ-MODEL-10` is satisfied by construction
|
|
99
118
|
rather than by a migration. The alternative shapes were a suffix
|
|
100
|
-
(`fact:activity:
|
|
119
|
+
(`fact:activity:self`), which buries the thing you are scanning for at the
|
|
101
120
|
end of a variable-length name, and per-subject fact keys
|
|
102
121
|
(`fact:own_activity`), which would double the fact vocabulary and repoint
|
|
103
122
|
nothing but would leave two names for one concept forever. Prefixing is the
|
|
104
123
|
only one of the three where the existing vocabulary is a strict subset of
|
|
105
124
|
the new one.
|
|
106
125
|
|
|
107
|
-
The cost, stated so nobody rediscovers it: `
|
|
126
|
+
The cost, stated so nobody rediscovers it: `self`, `other` and `pair` are now
|
|
108
127
|
reserved at the head of the identifier space, and no fact, light or relation
|
|
109
128
|
may ever be named one of them. That is the price of a subject segment that
|
|
110
129
|
is not itself prefixed, and it is cheap — the three words are not candidate
|
|
@@ -112,9 +131,9 @@ names for anything this package models.
|
|
|
112
131
|
|
|
113
132
|
### The three subjects
|
|
114
133
|
|
|
115
|
-
`
|
|
134
|
+
`self` is the vessel the rule addresses; `other` is the vessel it is in an
|
|
116
135
|
encounter with. **`pair` is the encounter itself**, and it exists because
|
|
117
|
-
some facts belong to neither vessel: range is one number, not
|
|
136
|
+
some facts belong to neither vessel: range is one number, not self's number
|
|
118
137
|
and the other's. Putting `geo:range_m` under both subjects would create two
|
|
119
138
|
identifiers for one quantity and a class of bug — the two disagreeing —
|
|
120
139
|
that has no meaning.
|
|
@@ -125,21 +144,21 @@ Geometry splits on whether the quantity is symmetric between the vessels:
|
|
|
125
144
|
|
|
126
145
|
| fact | subject | |
|
|
127
146
|
|---|---|---|
|
|
128
|
-
| `geo:rel_bearing_deg` | `
|
|
147
|
+
| `geo:rel_bearing_deg` | `self` / `other` | bearing of the *other* subject, clockwise from this subject's heading |
|
|
129
148
|
| `geo:range_m` | `pair` | |
|
|
130
149
|
| `geo:bearing_change_deg_min` | `pair` | Rule 7(d)(i)'s steady bearing |
|
|
131
150
|
| `geo:cpa_m`, `geo:tcpa_s` | `pair` | |
|
|
132
151
|
| `geo:in_sight` | `pair` | Rule 3(k), symmetric because the rule defines it that way |
|
|
133
152
|
|
|
134
153
|
The directional row is where the namespace earns its keep.
|
|
135
|
-
`
|
|
136
|
-
off
|
|
154
|
+
`self:geo:rel_bearing_deg` is relative bearing — where the other vessel is
|
|
155
|
+
off self's bow. `other:geo:rel_bearing_deg` is the same fact read from the
|
|
137
156
|
other side, which is **aspect**. So aspect gets no identifier of its own: it
|
|
138
157
|
is a subject swap, not a second fact. Rule 13(b)'s overtaking sector is then
|
|
139
|
-
`other:geo:rel_bearing_deg` in (112.5, 247.5) —
|
|
158
|
+
`other:geo:rel_bearing_deg` in (112.5, 247.5) — self more than 22.5° abaft
|
|
140
159
|
the other vessel's beam — written once, in the units the rule itself uses.
|
|
141
|
-
Swapping `
|
|
142
|
-
which is exactly the operation a `precedence` rule needs and the reason to
|
|
160
|
+
Swapping `self` and `other` throughout a predicate reverses the encounter,
|
|
161
|
+
which is exactly the operation a `category:precedence` rule needs and the reason to
|
|
143
162
|
prefer a subject namespace over two parallel vocabularies.
|
|
144
163
|
|
|
145
164
|
The directional and the pair geometry are redundant with `kin:` wherever both
|
|
@@ -153,7 +172,7 @@ and a record that omits the kinematics is unchecked rather than wrong.
|
|
|
153
172
|
|
|
154
173
|
`kin:` is the kinematic class ADR 0005 introduces — `kin:position`,
|
|
155
174
|
`kin:heading_deg`, `kin:sog_kn`, `kin:rot_deg_min`, `kin:dynamics`. It takes
|
|
156
|
-
`
|
|
175
|
+
`self`/`other` only; there is no kinematic state of a pair. `kin:dynamics`
|
|
157
176
|
is an enumerated fact, so its values follow the bare-fact-name rule above:
|
|
158
177
|
`dynamics:tanker`, not `kin:dynamics:tanker`.
|
|
159
178
|
|
|
@@ -164,12 +183,12 @@ overtaking, a subsequent alteration of the bearing does not make her a
|
|
|
164
183
|
crossing vessel; the instantaneous geometry, read alone, says otherwise and
|
|
165
184
|
hands the duty to the wrong vessel. So the latch is a fact:
|
|
166
185
|
|
|
167
|
-
- `
|
|
186
|
+
- `self:hist:was_overtaking` — this subject was, earlier in this encounter,
|
|
168
187
|
an overtaking vessel with respect to the other.
|
|
169
|
-
- `
|
|
188
|
+
- `self:hist:latched_at_s` — how long ago that attached, for a `category:conduct`
|
|
170
189
|
monitor. A predicate at a point does not read it.
|
|
171
190
|
|
|
172
|
-
History is directional — it is *
|
|
191
|
+
History is directional — it is *self* that was overtaking — so it takes a
|
|
173
192
|
subject segment like the fact record does, and never `pair`.
|
|
174
193
|
|
|
175
194
|
### What this does not do
|
|
@@ -183,41 +202,41 @@ keys would have broken.
|
|
|
183
202
|
## Effects `✎`
|
|
184
203
|
|
|
185
204
|
**Pencil** (`docs/conventions.md`): ADR 0005 puts the whole two-subject shape
|
|
186
|
-
there. What would settle it: a second family of `precedence` paragraphs —
|
|
205
|
+
there. What would settle it: a second family of `category:precedence` paragraphs —
|
|
187
206
|
Rules 12, 14 and 15 — written against it. **Written, and it held with one
|
|
188
|
-
addition**: Rules 7(d) and 13–15 are the first `classification` entries, and a
|
|
207
|
+
addition**: Rules 7(d) and 13–15 are the first `category:classification` entries, and a
|
|
189
208
|
classification produces neither a role nor a section, so the table below grows
|
|
190
|
-
a third row. Rule 12 turned out to be `precedence` and not `classification`
|
|
209
|
+
a third row. Rule 12 turned out to be `category:precedence` and not `category:classification`
|
|
191
210
|
(below). This section answers the data half of `Q-27` and is required by
|
|
192
211
|
`REQ-CAT-8`.
|
|
193
212
|
|
|
194
|
-
A `display` entry produces `lights`. A `scope` or `precedence` entry produces
|
|
213
|
+
A `category:display` entry produces `lights`. A `category:scope` or `category:precedence` entry produces
|
|
195
214
|
an **effect**, and the shape of the effect is fixed by the category:
|
|
196
215
|
|
|
197
216
|
| category | effect |
|
|
198
217
|
|---|---|
|
|
199
|
-
| `scope` | `{"part", "section", "applies_rules"}` — which section of which Part governs, and the rules it contains |
|
|
200
|
-
| `precedence` | `{"
|
|
201
|
-
| `classification` | `{"encounter": <encounter>}` **or** `{"risk_of_collision": true}` — exactly one key |
|
|
218
|
+
| `category:scope` | `{"part", "section", "applies_rules"}` — which section of which Part governs, and the rules it contains |
|
|
219
|
+
| `category:precedence` | `{"self": <role>, "other": <role>}` — one role per subject |
|
|
220
|
+
| `category:classification` | `{"encounter": <encounter>}` **or** `{"risk_of_collision": true}` — exactly one key |
|
|
202
221
|
|
|
203
|
-
Five roles, a closed set: `give-way`, `stand-on`,
|
|
204
|
-
`keep-clear`, `none`. They are declared
|
|
205
|
-
`effects`, and
|
|
206
|
-
|
|
207
|
-
binds.
|
|
222
|
+
Five roles, a closed set: `role:give-way`, `role:stand-on`,
|
|
223
|
+
`role:shall-not-impede`, `role:keep-clear`, `role:none`. They are declared
|
|
224
|
+
in `data/applicability.json` under `effects`, and, like modality and
|
|
225
|
+
category, they are identifiers: prefixed closed vocabularies `REQ-MODEL-10`
|
|
226
|
+
binds (ADR 0017).
|
|
208
227
|
|
|
209
228
|
### Encounters, and why a classification effect has two shapes
|
|
210
229
|
|
|
211
|
-
Four encounters, a closed set like the roles: `head-on` (Rule 14),
|
|
212
|
-
(Rule 15), `overtaking` (Rule 13) and
|
|
213
|
-
`data/applicability.json` under
|
|
214
|
-
are
|
|
230
|
+
Four encounters, a closed set like the roles: `encounter:head-on` (Rule 14),
|
|
231
|
+
`encounter:crossing` (Rule 15), `encounter:overtaking` (Rule 13) and
|
|
232
|
+
`encounter:none`. They are declared in `data/applicability.json` under
|
|
233
|
+
`effects.encounters` and, like the roles, they are identifiers.
|
|
215
234
|
|
|
216
|
-
A `classification` effect carries **exactly one key**, and which key it is
|
|
235
|
+
A `category:classification` effect carries **exactly one key**, and which key it is
|
|
217
236
|
depends on which question the paragraph answers. Rule 7(d)(i) answers *does
|
|
218
237
|
risk of collision exist* and produces `{"risk_of_collision": true}`; Rules 13,
|
|
219
238
|
14 and 15 answer *what kind of encounter is this* and produce an `encounter`.
|
|
220
|
-
ADR 0005 gives both questions to `classification` — "relative geometry,
|
|
239
|
+
ADR 0005 gives both questions to `category:classification` — "relative geometry,
|
|
221
240
|
history → encounter type, risk of collision" — and the two do not merge. A
|
|
222
241
|
single shape would have made every encounter entry state a risk it does not
|
|
223
242
|
decide, and 15(a)'s crossing test reads `pair:geo:risk_of_collision` as an
|
|
@@ -226,7 +245,7 @@ input rather than producing it.
|
|
|
226
245
|
There is no `{"risk_of_collision": false}` and there never will be. 7(a) makes
|
|
227
246
|
risk a judgement on all available means and deems it to exist in any doubt, so
|
|
228
247
|
an entry can add a ground for risk and nothing in this package can deny one.
|
|
229
|
-
`none` is declared
|
|
248
|
+
`encounter:none` is declared for the completeness of the vocabulary and
|
|
230
249
|
no entry produces it: an encounter type is asserted by a paragraph, and the
|
|
231
250
|
absence of one is the absence of an entry rather than an entry with a null
|
|
232
251
|
value.
|
|
@@ -242,17 +261,17 @@ subjects' bearings in half-degree steps and asserts exactly one encounter at
|
|
|
242
261
|
each of the 518 400 points; the Alloy version of the same property lives in
|
|
243
262
|
`colregs-engine`.
|
|
244
263
|
|
|
245
|
-
### Rule 12 is `precedence`, not `classification`
|
|
264
|
+
### Rule 12 is `category:precedence`, not `category:classification`
|
|
246
265
|
|
|
247
266
|
ADR 0005 §1 and the proposal's first-cut table file Rule 12 under
|
|
248
|
-
`classification`. It is `precedence` here, for the reason `Q-37` gives for
|
|
267
|
+
`category:classification`. It is `category:precedence` here, for the reason `Q-37` gives for
|
|
249
268
|
13(a): **12(a) produces a role, and a classification effect has nowhere to put
|
|
250
269
|
one.** "One of them shall keep out of the way of the other" is give-way and
|
|
251
270
|
stand-on in the effect vocabulary that already exists, and it is not an
|
|
252
271
|
encounter type — two sailing vessels meeting are still in a head-on, a
|
|
253
272
|
crossing or an overtaking, and Rule 12 says which of them gives way rather
|
|
254
273
|
than which kind of meeting it is. Rule 12 has no deeming paragraph at all:
|
|
255
|
-
12(b) defines the windward side and is a `definition`, so it is the cite on the
|
|
274
|
+
12(b) defines the windward side and is a `category:definition`, so it is the cite on the
|
|
256
275
|
`kin:wind_side` fact rather than an entry.
|
|
257
276
|
|
|
258
277
|
The category is `Q-14`'s to settle paragraph by paragraph and this is two more
|
|
@@ -280,18 +299,18 @@ that checkable: a Rule 18 entry meets Rule 15 when it assigns a helm role and
|
|
|
280
299
|
neither subject is gated to a sailing vessel, and every such entry must carry
|
|
281
300
|
the override, so a Rule 18 paragraph added later cannot join Rule 15 silently.
|
|
282
301
|
|
|
283
|
-
**The effect names both subjects, and that is the point.** A `precedence`
|
|
284
|
-
entry is evaluated from
|
|
285
|
-
other vessel stands on. Writing only
|
|
302
|
+
**The effect names both subjects, and that is the point.** A `category:precedence`
|
|
303
|
+
entry is evaluated from self's side, so 18(a)(i) says self gives way *and* the
|
|
304
|
+
other vessel stands on. Writing only self's half would lose Rule 17, which
|
|
286
305
|
attaches to the counterpart of a give-way duty and to nothing else. So
|
|
287
|
-
`stand-on` appears only opposite `give-way`, and the counterpart of
|
|
288
|
-
`shall-not-impede` is always `none` — that is 8(f)(iii) in the data: a vessel
|
|
289
|
-
whose passage is not to be impeded acquires no privilege by it. `none` is
|
|
306
|
+
`role:stand-on` appears only opposite `role:give-way`, and the counterpart of
|
|
307
|
+
`role:shall-not-impede` is always `role:none` — that is 8(f)(iii) in the data: a vessel
|
|
308
|
+
whose passage is not to be impeded acquires no privilege by it. `role:none` is
|
|
290
309
|
written rather than omitted, because a norm that confers nothing on a subject
|
|
291
|
-
is a finding and not an absence: NUC against RAM is `none` on both sides, and
|
|
310
|
+
is a finding and not an absence: NUC against RAM is `role:none` on both sides, and
|
|
292
311
|
that is Rule 18's partial order rather than a gap in the table.
|
|
293
312
|
|
|
294
|
-
`keep-clear` is one role for the two duties 18(e) and 18(f)(i) impose together
|
|
313
|
+
`role:keep-clear` is one role for the two duties 18(e) and 18(f)(i) impose together
|
|
295
314
|
— keep well clear, and avoid impeding navigation. The vocabulary cannot
|
|
296
315
|
separate them and does not pretend to.
|
|
297
316
|
|
|
@@ -299,7 +318,7 @@ separate them and does not pretend to.
|
|
|
299
318
|
|
|
300
319
|
A two-subject entry is keyed on its paragraph like any other (below):
|
|
301
320
|
`rule:18a_i` is 18(a)(i), `rule:9c` is 9(c), `rule:8f_iii` is 8(f)(iii). No
|
|
302
|
-
subject segment appears in an id: every entry is evaluated from
|
|
321
|
+
subject segment appears in an id: every entry is evaluated from self's side,
|
|
303
322
|
and where the paragraph classifies the pair rather than one vessel the entry
|
|
304
323
|
reads both subjects inside one predicate — `rule:13b` is 13(b) whichever
|
|
305
324
|
vessel is coming up. Where a paragraph's subject is disjunctive — 9(b) is
|
|
@@ -391,11 +410,6 @@ implemented in the reference evaluator and asserted by the fixtures.
|
|
|
391
410
|
|
|
392
411
|
## What is not an identifier
|
|
393
412
|
|
|
394
|
-
- **Modality values** (`shall`, `may`, `shall-if-practicable`,
|
|
395
|
-
`conditional`, `exempt`) and **jurisdiction values** (`intl`,
|
|
396
|
-
`us/inland`) are their own closed vocabularies, defined in §2 of the
|
|
397
|
-
requirements and not part of the identifier space REQ-MODEL-10 binds. So are
|
|
398
|
-
the **role** and **encounter** values of an effect.
|
|
399
413
|
- **Constants** — `situation.constants` in `data/facts.json`: the numbers a
|
|
400
414
|
Part B predicate needs and the Rules do not always give
|
|
401
415
|
(`appreciable_bearing_change_deg_min`, `head_on_half_angle_deg`, the two
|
|
@@ -410,7 +424,7 @@ implemented in the reference evaluator and asserted by the fixtures.
|
|
|
410
424
|
data is addressed by. Only the values inside them can be identifiers, and
|
|
411
425
|
where they are (`also_activity` holds an activity value) they are prefixed.
|
|
412
426
|
`not` and `any_of` are the second pair of words reserved at the head of an
|
|
413
|
-
identifier space, after `
|
|
427
|
+
identifier space, after `self`/`other`/`pair`: they appear where a fact key
|
|
414
428
|
appears, so no fact may ever be named either. The cost is the same and as
|
|
415
429
|
cheap — every fact key carries a class prefix (`fact:`, `geo:`, `kin:`,
|
|
416
430
|
`hist:`, `env:`) and neither word could be one.
|
|
@@ -46,7 +46,7 @@ suffix naming what distinguishes them.
|
|
|
46
46
|
A **situation** is the record of `REQ-CAT-4` and `REQ-CAT-6`: two per-vessel
|
|
47
47
|
fact records, a kinematic state each, relative geometry, history and the
|
|
48
48
|
environment, addressed as `<subject>:<class>:<key>`, subject in
|
|
49
|
-
`
|
|
49
|
+
`self`/`other`/`pair`. A **trace** is a sequence of situations for one ordered
|
|
50
50
|
pair, sampled at *t*₀ < *t*₁ < … . Each invariant is a property of one state
|
|
51
51
|
("at every state") or relates two or more ("at every state after", "from the
|
|
52
52
|
first state at which") — the whole content of §4.1's `conduct` category, and
|
|
@@ -74,8 +74,8 @@ latches the result against the geometry that follows.
|
|
|
74
74
|
`13(b)` under 11 · classification · single-state · `✎`
|
|
75
75
|
|
|
76
76
|
**Invariant.** At any state at which the two vessels are in sight of one
|
|
77
|
-
another and both underway,
|
|
78
|
-
|
|
77
|
+
another and both underway, self is deemed to be overtaking other exactly when
|
|
78
|
+
self is coming up with other and self bears, from other, more than 22.5° abaft
|
|
79
79
|
other's beam — `other:geo:rel_bearing_deg` strictly inside (112.5°, 247.5°).
|
|
80
80
|
The sector is open at both ends (*more than* 22.5°: a vessel on the edge is
|
|
81
81
|
not overtaking); its edges are the forward edges of Rule 21(c)'s sternlight
|
|
@@ -93,7 +93,7 @@ arc, which 13(b)'s second limb states in light terms.
|
|
|
93
93
|
|
|
94
94
|
`13(b)` · classification, derived · single-state · `✎`
|
|
95
95
|
|
|
96
|
-
**Invariant.** Where `INV-13b` holds of
|
|
96
|
+
**Invariant.** Where `INV-13b` holds of self with respect to other, the
|
|
97
97
|
encounter type of the pair is `overtaking` read from *either* subject: the
|
|
98
98
|
vessel being overtaken is in an overtaking, not a crossing, though the
|
|
99
99
|
overtaking vessel bears forward of her beam.
|
|
@@ -127,13 +127,13 @@ well as Rules 14 and 15.
|
|
|
127
127
|
`13(d)` · classification · temporal, a state to every later state of the
|
|
128
128
|
encounter · `✎`
|
|
129
129
|
|
|
130
|
-
**Invariant.** Let *s* be the first state of an encounter at which
|
|
130
|
+
**Invariant.** Let *s* be the first state of an encounter at which self is
|
|
131
131
|
deemed to be overtaking other. At every state of that encounter after *s*,
|
|
132
|
-
until
|
|
132
|
+
until self is finally past and clear, the encounter type of the pair is
|
|
133
133
|
`overtaking` whatever the relative bearings then are; in particular it is not
|
|
134
134
|
`crossing`, and the tests of Rules 14 and 15 do not apply to the pair.
|
|
135
135
|
|
|
136
|
-
- **State remembered.** One directional boolean per subject per encounter (
|
|
136
|
+
- **State remembered.** One directional boolean per subject per encounter (self
|
|
137
137
|
was, earlier in this encounter, the overtaking vessel), plus the time of *s*
|
|
138
138
|
for a monitor that says when the duty attached; window *s* to finally past and
|
|
139
139
|
clear. Reading only the current state is wrong in the direction the paragraph
|
|
@@ -144,7 +144,7 @@ until own is finally past and clear, the encounter type of the pair is
|
|
|
144
144
|
model's is its segmentation, and no bearing or range is invented here.
|
|
145
145
|
- **Readings in doubt.** Two: what arms the latch, `Q-51`; what it forbids,
|
|
146
146
|
`Q-52`.
|
|
147
|
-
- Entries: `rule:13d`, reading `
|
|
147
|
+
- Entries: `rule:13d`, reading `self`/`other:hist:was_overtaking` and no geometry; the
|
|
148
148
|
`was_overtaking: false` gates on `rule:14b`, `rule:15a:crossing`, `rule:15a:keep_out_of_the_way`
|
|
149
149
|
implement `Q-52`'s *broad* reading. Settled by `Q-51`, `Q-52`, then TLC on a
|
|
150
150
|
three-state trace of an overtaking drawing out onto the bow.
|
|
@@ -153,15 +153,15 @@ until own is finally past and clear, the encounter type of the pair is
|
|
|
153
153
|
|
|
154
154
|
`13(d)` second limb · precedence · temporal, as `INV-13d` · `✎`
|
|
155
155
|
|
|
156
|
-
**Invariant.** With *s* as in `INV-13d`, at every state after *s* until
|
|
157
|
-
finally past and clear,
|
|
156
|
+
**Invariant.** With *s* as in `INV-13d`, at every state after *s* until self is
|
|
157
|
+
finally past and clear, self holds `give-way` and other `stand-on`, whatever the
|
|
158
158
|
bearings. Separate from `INV-13d` because the two limbs come apart: a reading
|
|
159
159
|
on which 13(d) forbids only the *crossing* reclassification still preserves
|
|
160
160
|
the duty by its second clause, and a formalisation deriving role from encounter
|
|
161
161
|
type alone cannot distinguish `Q-52`'s readings.
|
|
162
162
|
|
|
163
163
|
- **State remembered.** As `INV-13d`.
|
|
164
|
-
- Entries: `rule:13a`'s `any_of` second limb, `
|
|
164
|
+
- Entries: `rule:13a`'s `any_of` second limb, `self:hist:was_overtaking: true` — role
|
|
165
165
|
asserted from the latch directly, keeping the limbs separable. Settled by
|
|
166
166
|
`Q-52`.
|
|
167
167
|
|
|
@@ -176,7 +176,7 @@ type alone cannot distinguish `Q-52`'s readings.
|
|
|
176
176
|
**Invariant.** At any state at which two power-driven vessels are in sight,
|
|
177
177
|
both underway, with risk of collision, and neither latched under `INV-13d`, a
|
|
178
178
|
head-on situation is deemed to exist exactly when each sees the other ahead or
|
|
179
|
-
nearly ahead: `
|
|
179
|
+
nearly ahead: `self:geo:rel_bearing_deg` and `other:geo:rel_bearing_deg` each
|
|
180
180
|
in [0°, 11.25°] ∪ [348.75°, 360°).
|
|
181
181
|
|
|
182
182
|
- **Both bearings, not one.** 14(b)'s lights limb is a statement about the
|
|
@@ -241,7 +241,7 @@ vessel which has the other on her own starboard side holds `give-way` and the
|
|
|
241
241
|
other holds `stand-on`.
|
|
242
242
|
|
|
243
243
|
- **Undetermined term.** "On her own starboard side" has no sector in the
|
|
244
|
-
paragraph; the data reads `
|
|
244
|
+
paragraph; the data reads `self:geo:rel_bearing_deg` in (0°, 112.5°], its upper
|
|
245
245
|
edge 13(b)'s constant, so it is checkable against the partition.
|
|
246
246
|
- Entries: `rule:15a:keep_out_of_the_way`, plus six `rel:overrides` from Rule 18 entries, since
|
|
247
247
|
Rule 18's chapeau excepts Rules 9, 10 and 13 and no others.
|
|
@@ -255,7 +255,7 @@ bearings only
|
|
|
255
255
|
under `INV-15a-give-way`.
|
|
256
256
|
|
|
257
257
|
- **Why it is not free.** Both-starboard is a consistent *record* and an
|
|
258
|
-
impossible *situation* on a steady bearing:
|
|
258
|
+
impossible *situation* on a steady bearing: self's speed times the sine of her
|
|
259
259
|
relative bearing equals minus other's speed times the sine of the aspect, so
|
|
260
260
|
the bearings lie on opposite sides. A theorem at zero bearing rate, an
|
|
261
261
|
observation elsewhere.
|
|
@@ -703,7 +703,7 @@ action in ample time.
|
|
|
703
703
|
|
|
704
704
|
**Invariant.** Where `INV-19d-action`'s action is an alteration of course,
|
|
705
705
|
then so far as possible the vessel shall not alter course to port for a vessel
|
|
706
|
-
forward of her beam — `
|
|
706
|
+
forward of her beam — `self:geo:rel_bearing_deg` in (270°, 360°) ∪ [0°, 90°) —
|
|
707
707
|
other than for a vessel being overtaken.
|
|
708
708
|
|
|
709
709
|
- **The exception reaches across the switch.** "A vessel being overtaken" is
|
|
@@ -718,7 +718,7 @@ other than for a vessel being overtaken.
|
|
|
718
718
|
|
|
719
719
|
**Invariant.** Where `INV-19d-action`'s action is an alteration of course,
|
|
720
720
|
then so far as possible the vessel shall not alter course toward a vessel
|
|
721
|
-
abeam or abaft her beam — `
|
|
721
|
+
abeam or abaft her beam — `self:geo:rel_bearing_deg` in [90°, 270°].
|
|
722
722
|
|
|
723
723
|
- **"Toward"** is the sign of the alteration against the other's bearing, not
|
|
724
724
|
the resulting heading: toward when it reduces her relative bearing off the bow
|
|
@@ -760,7 +760,7 @@ paragraph of its own.
|
|
|
760
760
|
|
|
761
761
|
`13(a)`, `15(a)`, `12(a)`, `18(a)–(c)` with 18's chapeau · precedence, derived
|
|
762
762
|
· single-state · `✎`, asserted over consistent steady bearings only
|
|
763
|
-
(`REQ-VERIFY-8`)
|
|
763
|
+
(`REQ-VERIFY-8`), over the pooled two-frame read of ADR 0016
|
|
764
764
|
|
|
765
765
|
**Invariant.** At every state, after every `rel:overrides` is applied, no pair
|
|
766
766
|
holds `give-way` on both subjects, and none holds `stand-on` on both.
|
|
@@ -786,7 +786,8 @@ P2.2.
|
|
|
786
786
|
|
|
787
787
|
### INV-PB-one-role-source — a vessel holds one helm role at a time
|
|
788
788
|
|
|
789
|
-
`13(a)`, `18` chapeau, with 16 and 17 · precedence, derived · single-state ·
|
|
789
|
+
`13(a)`, `18` chapeau, with 16 and 17 · precedence, derived · single-state · `✎`,
|
|
790
|
+
over the pooled two-frame read of ADR 0016
|
|
790
791
|
|
|
791
792
|
**Invariant.** After every `rel:overrides` is applied, no vessel holds both
|
|
792
793
|
`give-way` and `stand-on` with respect to the same other vessel at the same
|