Skip to content

Commit b2aa766

Browse files
committed
P-037 A2.2-4R4: the F-VOCAB ruling; predicate_result, interpolation_hole, indexer_argument named, constructor initializer re-classified
No production change. A2.2-4's completeness oracle met four argument shapes the frozen list had no name for (formal note §10.6.10, F-VOCAB, §10.1 case 3) and, by the letter of the completeness sentence, read them RED. The owner's ruling splits them, and this commit carries it: - predicate_result: `Use6(r != null)` — the handle takes part in computing a predicate and the callee receives the bool; nothing of the handle flows; - interpolation_hole: `Use4($"{r}")` — the callee receives the built string; - indexer_argument: `d[r] = 1` — the handle IS semantically an argument of the indexer accessor's call, and that accessor call deliberately stays outside the frozen call-site vocabulary; the definition says so outright rather than letting the name hide it. The index position is this rule; a handle stored through an indexer stays storage_assignment; - the constructor-initializer argument, `Holder(MemoryStream r) : base(r, true)`, is NOT an exclusion: it passes the handle into a really invoked constructor's declared ordinal 0, the same ownership edge object_creation was added for, and "the callee is outside the vocabulary" would be circular. It is a call-like fact shape (call_kind constructor_initializer; site the ConstructorInitializerSyntax; callee the target constructor's {Type}..ctor key; sig its canonical signature; arguments bound to the target constructor's declared ordinals; first_party by declaring syntax; the same value-flow and binding machinery), landing in A2.2-4R5, and it stays pinned RED until then under F-CTOR-INIT. The three names join corpus/p037-relevance/registry.json with definitions, §10.6.4 with examples, and the probe with one row each (PredicateResult, InterpolationHole, IndexerArgument, helper Use6). The rows' historical columns were measured, never assumed, with the extractor rebuilt at each step's commit (A' 5a0de07, A2.2-1 268bbd4, A2.2-2 376f2e6, A2.2-2b 7de7a6f, A2.2-3P 80cd9aa): record_without_call_fact for the first two at every step (the handle never escapes, the method is admitted, no call fact), no_record for the third (the index position is an argument to the legacy escape rule, every candidate escapes, nothing to carry). The oracle assigns the three names (a predicate's bool or an interpolated string under an argument; any element-access index) and its RED kinds shrink to the constructor initializer; the three vocab-* witnesses read green by their designs; the probe reads all 31 rows as their class; F-VOCAB moves to `closed` and F-CTOR-INIT opens in the ledger. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfeUtLRm6KFRWcTGQZxQQb
1 parent 947d6c3 commit b2aa766

14 files changed

Lines changed: 187 additions & 81 deletions

File tree

‎corpus/p037-hostile/README.md‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ classification, derived from the frozen taxonomy
1919
- `occurrences` — the universe occurrences of the method in source order, each
2020
with the verdict the taxonomy assigns: `captured` (site kind, declared
2121
ordinal, representation `var` / `param` / `opaque`, enclosing
22-
`nested_call_result` calls) or `excluded` (by exactly one of the eleven
22+
`nested_call_result` calls) or `excluded` (by exactly one of the frozen
2323
names), or, for a vocabulary edge, the RED the sentence's letter demands;
2424
- `carrier` — where production must deliver the member's record:
2525
`functions`, `guarded_functions` (the orphan carrier) or `none` (nothing
@@ -57,9 +57,11 @@ plus the named cases:
5757
accessor, and a declared local function (the known, counted gap);
5858
- two receiver forms (`ext-*`): a reduced extension through `?.`, and a
5959
struct handle boxed into an `object` receiver;
60-
- the argument shapes the frozen vocabulary has no name for (`vocab-*`): a
61-
tested operand, an interpolation hole, an indexer argument, a
62-
constructor-initializer argument.
60+
- the argument shapes the frozen vocabulary had no name for (`vocab-*`): a
61+
tested operand, an interpolation hole and an indexer argument, named by the
62+
A2.2-4R4 ruling (`predicate_result`, `interpolation_hole`,
63+
`indexer_argument`), and a constructor-initializer argument, a call-like
64+
fact shape pending A2.2-4R5.
6365

6466
The findings these witness are classified in
6567
`corpus/p037-relevance/oracle_findings.json`; each stays RED, by name, until a

‎corpus/p037-hostile/cases/vocab-constructor-initializer.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// GENERATED by scripts/p037_hostile_census.py (P-037 A2.2-4 hostile census); do not edit.
2-
// vocabulary edge: an owned constructor parameter forwarded through `: base(...)`, a call site that is neither an invocation nor an object creation (finding F-VOCAB)
2+
// vocabulary edge: an owned constructor parameter forwarded through `: base(...)`, a really invoked constructor's declared ordinal 0; ruled a call-like fact shape in A2.2-4R4, landing in A2.2-4R5 (finding F-CTOR-INIT)
33
using System;
44
using System.IO;
55
using System.Collections.Generic;

‎corpus/p037-hostile/cases/vocab-indexer-argument.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// GENERATED by scripts/p037_hostile_census.py (P-037 A2.2-4 hostile census); do not edit.
2-
// vocabulary edge: the handle is the index of an element access (finding F-VOCAB)
2+
// vocabulary edge: the handle is the index of an element access, an argument of an indexer accessor's call that the vocabulary deliberately leaves out; the A2.2-4R4 ruling names it indexer_argument
33
using System;
44
using System.IO;
55
using System.Collections.Generic;

‎corpus/p037-hostile/cases/vocab-interpolation-hole.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// GENERATED by scripts/p037_hostile_census.py (P-037 A2.2-4 hostile census); do not edit.
2-
// vocabulary edge: the handle is an interpolation hole and the string is the argument (finding F-VOCAB)
2+
// vocabulary edge: the handle is an interpolation hole and the string is the argument; the A2.2-4R4 ruling names it interpolation_hole
33
using System;
44
using System.IO;
55
using System.Collections.Generic;

‎corpus/p037-hostile/cases/vocab-tested-operand.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// GENERATED by scripts/p037_hostile_census.py (P-037 A2.2-4 hostile census); do not edit.
2-
// vocabulary edge: the handle is compared and the boolean is the argument; no frozen exclusion names a tested operand under an argument (finding F-VOCAB)
2+
// vocabulary edge: the handle is compared and the boolean is the argument; the A2.2-4R4 ruling names it predicate_result
33
using System;
44
using System.IO;
55
using System.Collections.Generic;

‎corpus/p037-hostile/expected.json‎

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3049,71 +3049,66 @@
30493049
"red": {
30503050
"unclassified_argument_shape:constructor_initializer": 1
30513051
},
3052-
"finding": "F-VOCAB",
3053-
"why": "vocabulary edge: an owned constructor parameter forwarded through `: base(...)`, a call site that is neither an invocation nor an object creation (finding F-VOCAB)"
3052+
"finding": "F-CTOR-INIT",
3053+
"why": "vocabulary edge: an owned constructor parameter forwarded through `: base(...)`, a really invoked constructor's declared ordinal 0; ruled a call-like fact shape in A2.2-4R4, landing in A2.2-4R5 (finding F-CTOR-INIT)"
30543054
},
30553055
"vocab-indexer-argument": {
30563056
"member": "H_vocab_indexer_argument.M",
30573057
"carrier": "functions",
30583058
"occurrences": [
30593059
{
30603060
"symbol": "r",
3061-
"verdict": "red",
3062-
"explanation": "unclassified_argument_shape:indexer_argument"
3061+
"verdict": "excluded",
3062+
"explanation": "indexer_argument"
30633063
},
30643064
{
30653065
"symbol": "keep",
30663066
"verdict": "excluded",
30673067
"explanation": "receiver_not_summary_parameter"
30683068
}
30693069
],
3070-
"red": {
3071-
"unclassified_argument_shape:indexer_argument": 1
3072-
},
3073-
"finding": "F-VOCAB",
3074-
"why": "vocabulary edge: the handle is the index of an element access (finding F-VOCAB)"
3070+
"red": {},
3071+
"why": "vocabulary edge: the handle is the index of an element access, an argument of an indexer accessor's call that the vocabulary deliberately leaves out; the A2.2-4R4 ruling names it indexer_argument"
30753072
},
30763073
"vocab-interpolation-hole": {
30773074
"member": "H_vocab_interpolation_hole.M",
30783075
"carrier": "functions",
30793076
"occurrences": [
30803077
{
30813078
"symbol": "r",
3082-
"verdict": "red",
3083-
"explanation": "unclassified_argument_shape:interpolation_hole"
3079+
"verdict": "excluded",
3080+
"explanation": "interpolation_hole",
3081+
"site_kind": "invocation",
3082+
"ordinal": 0
30843083
},
30853084
{
30863085
"symbol": "keep",
30873086
"verdict": "excluded",
30883087
"explanation": "receiver_not_summary_parameter"
30893088
}
30903089
],
3091-
"red": {
3092-
"unclassified_argument_shape:interpolation_hole": 1
3093-
},
3094-
"finding": "F-VOCAB",
3095-
"why": "vocabulary edge: the handle is an interpolation hole and the string is the argument (finding F-VOCAB)"
3090+
"red": {},
3091+
"why": "vocabulary edge: the handle is an interpolation hole and the string is the argument; the A2.2-4R4 ruling names it interpolation_hole"
30963092
},
30973093
"vocab-tested-operand": {
30983094
"member": "H_vocab_tested_operand.M",
30993095
"carrier": "functions",
31003096
"occurrences": [
31013097
{
31023098
"symbol": "r",
3103-
"verdict": "red",
3104-
"explanation": "unclassified_argument_shape:tested_operand"
3099+
"verdict": "excluded",
3100+
"explanation": "predicate_result",
3101+
"site_kind": "invocation",
3102+
"ordinal": 0
31053103
},
31063104
{
31073105
"symbol": "keep",
31083106
"verdict": "excluded",
31093107
"explanation": "receiver_not_summary_parameter"
31103108
}
31113109
],
3112-
"red": {
3113-
"unclassified_argument_shape:tested_operand": 1
3114-
},
3115-
"finding": "F-VOCAB",
3116-
"why": "vocabulary edge: the handle is compared and the boolean is the argument; no frozen exclusion names a tested operand under an argument (finding F-VOCAB)"
3110+
"red": {},
3111+
"why": "vocabulary edge: the handle is compared and the boolean is the argument; the A2.2-4R4 ruling names it predicate_result"
31173112
}
31183113
}
31193114
}

‎corpus/p037-relevance/oracle_findings.json‎

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
"status": "open: a census finding; carrying these members in the orphan carrier is a production change to be classified on its own",
1010
"red": "occurrence_not_captured"
1111
},
12-
"F-VOCAB": {
12+
"F-CTOR-INIT": {
1313
"class": "case 3",
14-
"title": "argument shapes the frozen vocabulary has no name for: a tested operand, an interpolation hole, an indexer argument, a constructor-initializer argument",
15-
"evidence": "Each is a candidate occurrence under a call-related syntax site that no frozen exclusion names; production emits no fact for any of them (correctly: no handle reaches a callee of the vocabulary), so each needs a name, never a bucket. Witnessed by four hostile cases.",
16-
"status": "open: awaiting a naming ruling (\u00a710.6.4 additions)",
17-
"red": "unclassified_argument_shape:*"
14+
"title": "a constructor initializer `: base(...)` / `: this(...)` is a call-like site without a fact shape",
15+
"evidence": "`Holder(MemoryStream r) : base(r, true)` passes the owned parameter into a really invoked constructor's declared ordinal 0, the same ownership edge object_creation was added for; the frozen vocabulary has no call_kind for a ConstructorInitializerSyntax site, so no fact exists and the oracle reads the occurrence as unclassified. Ruled in A2.2-4R4 to be a fact shape (call_kind constructor_initializer; site the initializer; callee the target constructor's {Type}..ctor key; sig its canonical signature; arguments bound to the target constructor's declared ordinals; first_party by declaring syntax; the same value-flow and binding machinery), landing in A2.2-4R5. Witnessed by the hostile case vocab-constructor-initializer.",
16+
"status": "open: A2.2-4R5 adds the fact shape",
17+
"red": "unclassified_argument_shape:constructor_initializer"
1818
}
1919
},
2020
"expected_red": {
@@ -47,6 +47,13 @@
4747
"evidence": "The invocation loop reads the receiver only from a MemberAccessExpressionSyntax; `r?.Ext(...)` invokes through a MemberBindingExpressionSyntax and the receiver handle is dropped, so the call is not relevant unless another argument is a handle. Witnessed by the hostile case ext-conditional-access.",
4848
"status": "closed: A2.2-4R3. The invocation loop reads the reduced receiver of an invocation through a MemberBindingExpressionSyntax from the nearest enclosing ConditionalAccessExpressionSyntax's expression; ext-conditional-access is designed green.",
4949
"red": "occurrence_not_captured"
50+
},
51+
"F-VOCAB": {
52+
"class": "case 3",
53+
"title": "argument shapes the frozen vocabulary has no name for: a tested operand, an interpolation hole, an indexer argument, a constructor-initializer argument",
54+
"evidence": "Each is a candidate occurrence under a call-related syntax site that no frozen exclusion names; production emits no fact for any of them (correctly: no handle reaches a callee of the vocabulary), so each needs a name, never a bucket. Witnessed by four hostile cases.",
55+
"status": "closed: the A2.2-4R4 ruling. predicate_result, interpolation_hole and indexer_argument are frozen exclusions (registry, \u00a710.6.4, probe rows PredicateResult / InterpolationHole / IndexerArgument, oracle); the constructor-initializer argument is not an exclusion but a call-like fact shape, tracked as F-CTOR-INIT.",
56+
"red": "unclassified_argument_shape:*"
5057
}
5158
}
5259
}

‎corpus/p037-relevance/probe/case.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ sealed class Derived : Base { }
2929
static void TakeDerivedRef(Derived d) { }
3030
struct Token : IDisposable { public void Dispose() { } }
3131
static void SinkObject(object o) { }
32+
static void Use6(bool b) { }
3233

3334
// direct
3435
static void Plain() { var r = new MemoryStream(); Inner(r, true); } // implicit reference upcast at the parameter
@@ -71,4 +72,9 @@ static void SinkObject(object o) { }
7172
// indirect: the site binds no summary parameter
7273
static void Receiver() { var r = new MemoryStream(); r.CopyTo(Stream.Null); }
7374
static void Indexer() { var r = new MemoryStream(); var d = new Dictionary<int, Stream>(); d[0] = r; }
75+
76+
// indirect: a value derived from the handle flows, not the handle (A2.2-4R4 ruling)
77+
static void PredicateResult() { var r = new MemoryStream(); Use6(r != null); } // the predicate's bool is the argument
78+
static void InterpolationHole() { var r = new MemoryStream(); Use4($"{r}"); } // the built string is the argument
79+
static void IndexerArgument() { var r = new MemoryStream(); var d = new Dictionary<Stream, int>(); d[r] = 1; } // the handle is the index of an accessor call outside the vocabulary
7480
}

‎corpus/p037-relevance/probe/expected.json‎

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
"Use5",
3636
"Same",
3737
"TakeDerivedRef",
38-
"SinkObject"
38+
"SinkObject",
39+
"Use6"
3940
],
4041
"methods": {
4142
"Plain": {
@@ -352,7 +353,44 @@
352353
"a2_2_2b_observed": "no_record",
353354
"a2_2_3p_observed": "no_record",
354355
"a2_2_4_oracle": "excluded:storage_assignment"
356+
},
357+
"PredicateResult": {
358+
"class": "indirect",
359+
"exclusion": "predicate_result",
360+
"conversion": "not_applicable",
361+
"note": "the predicate's bool is the argument; nothing of the handle flows (A2.2-4R4 ruling)",
362+
"a2_1_observed": "record_without_call_fact",
363+
"a2_2_1_observed": "record_without_call_fact",
364+
"a2_2_2_observed": "record_without_call_fact",
365+
"a2_2_2b_observed": "record_without_call_fact",
366+
"a2_2_3p_observed": "record_without_call_fact",
367+
"a2_2_4_oracle": "excluded:predicate_result"
368+
},
369+
"InterpolationHole": {
370+
"class": "indirect",
371+
"exclusion": "interpolation_hole",
372+
"conversion": "not_applicable",
373+
"note": "the built string is the argument (A2.2-4R4 ruling)",
374+
"a2_1_observed": "record_without_call_fact",
375+
"a2_2_1_observed": "record_without_call_fact",
376+
"a2_2_2_observed": "record_without_call_fact",
377+
"a2_2_2b_observed": "record_without_call_fact",
378+
"a2_2_3p_observed": "record_without_call_fact",
379+
"a2_2_4_oracle": "excluded:interpolation_hole"
380+
},
381+
"IndexerArgument": {
382+
"class": "indirect",
383+
"exclusion": "indexer_argument",
384+
"conversion": "not_applicable",
385+
"note": "the handle is an argument of the indexer accessor's call, a call site the frozen vocabulary deliberately leaves out (A2.2-4R4 ruling); the legacy escape rule reads the index position as an argument, so every candidate escapes and no record exists",
386+
"a2_1_observed": "no_record",
387+
"a2_2_1_observed": "no_record",
388+
"a2_2_2_observed": "no_record",
389+
"a2_2_2b_observed": "no_record",
390+
"a2_2_3p_observed": "no_record",
391+
"a2_2_4_oracle": "excluded:indexer_argument"
355392
}
356393
},
357-
"a2_2_4_oracle_note": "The completeness oracle's live reading of each row (A2.2-4): the verdict of the row's handle occurrence, `captured:<site kind>[+enclosing exclusions]` or `excluded:<named exclusion>`. Recorded by scripts/p037_completeness_oracle.py record and held equal by check; the oracle is checked against the class, never the other way round."
394+
"a2_2_4_oracle_note": "The completeness oracle's live reading of each row (A2.2-4): the verdict of the row's handle occurrence, `captured:<site kind>[+enclosing exclusions]` or `excluded:<named exclusion>`. Recorded by scripts/p037_completeness_oracle.py record and held equal by check; the oracle is checked against the class, never the other way round.",
395+
"a2_2_4r4_note": "Three rows added by the A2.2-4R4 ruling (PredicateResult, InterpolationHole, IndexerArgument). Their historical columns were measured with the extractor rebuilt at each step's commit (A' 5a0de070, A2.2-1 268bbd4, A2.2-2 376f2e6, A2.2-2b 7de7a6f, A2.2-3P 80cd9aa), never assumed: the first two read record_without_call_fact at every step (the handle never escapes, the method is admitted, no call fact), the third no_record (the index position is an argument to the legacy escape rule, every candidate escapes, nothing to carry)."
358396
}

‎corpus/p037-relevance/registry.json‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"schema": "p037-relevance-taxonomy/1",
3-
"frozen_at": "P-037 A2.2-0 (F0', corrected freeze on main@23e3203); conversion vocabulary closed at A2.2-1a",
3+
"frozen_at": "P-037 A2.2-0 (F0', corrected freeze on main@23e3203); conversion vocabulary closed at A2.2-1a; three exclusions named at A2.2-4R4 (predicate_result, interpolation_hole, indexer_argument)",
44
"ruling": "docs/notes/p037-formal-kernel.md §10.6",
55
"completeness": "Completeness means every candidate occurrence at a call-related syntax site is either represented by the raw guarded-call vocabulary or assigned exactly one named exclusion. Occurrence alone does not establish ownership flow to the enclosing callee.",
66
"classes": {
@@ -99,6 +99,21 @@
9999
"class": "indirect",
100100
"definition": "A member of the handle flows, not the handle.",
101101
"example": "Use5(r.Length)"
102+
},
103+
"predicate_result": {
104+
"class": "indirect",
105+
"definition": "The handle is an operand of a predicate (a comparison, an `is` test, a null test) whose boolean result is the argument. The callee receives the predicate's bool; nothing of the handle flows. Named by the A2.2-4R4 ruling from the oracle's vocabulary edge `tested operand under an argument`; a predicate that is not under a call-related site is a non-call context, not this exclusion.",
106+
"example": "Use6(r != null)"
107+
},
108+
"interpolation_hole": {
109+
"class": "indirect",
110+
"definition": "The handle is an interpolation hole; the callee receives the built string. Named by the A2.2-4R4 ruling.",
111+
"example": "Use4($\"{r}\")"
112+
},
113+
"indexer_argument": {
114+
"class": "indirect",
115+
"definition": "The handle is the index of an element access. Semantically the handle IS an argument of the indexer accessor's call; that accessor call deliberately stays outside the frozen call-site vocabulary (an invocation expression, an object creation, a delegate invocation, and a constructor initializer once A2.2-4R5 lands), so no call fact exists for it and nothing of the handle reaches a callee of the vocabulary. This rule is the INDEX position; a handle stored through an indexer (`d[0] = r`) is storage_assignment. Named by the A2.2-4R4 ruling, with the boundary stated rather than hidden.",
116+
"example": "d[r] = 1"
102117
}
103118
},
104119
"fixture_obligation": "Every exclusion has a positive fixture (the rule fires and no call fact is emitted for that site) and a negative fixture (a syntactically adjacent case that is captured instead). A2.2-4 checks both by name: the completeness oracle (frontend/roslyn/OwnSharp.Oracle) reads every probe row and every case of the generated hostile census (corpus/p037-hostile) against its designed classification, and every RED it raises must be a finding classified in oracle_findings.json.",

0 commit comments

Comments
 (0)