fix(v4): (DOWN) calls the GONE hook and puts (ONE) back; the hand-on swept
Found by the depth sweep: a hook that sent a message about another node overwrote (ONE), which AWAIT reads after believing a GONE, so the wait went on. (DOWN) now calls the hook through (RUN) and restores (ONE). AWAIT ended by a GONE that is handed on: works to 26 values and 21 calls deep, then a stack error and nothing else, at both widths. Removal sweep: node 11 or 12 removed, or the wire cut, at every step: 0 wrong. hosted dict_hash=0x248b4edc47f4357e on all three ISAs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3506747d5a
commit
529ba0fc48
@@ -218,10 +218,10 @@ static void fill(char *text, size_t cap, unsigned count)
|
||||
for (bit = 8; bit; bit >>= 1) if (count >= bit) { at += (size_t)snprintf(text + at, cap - at, "P%u ", bit); count -= bit; }
|
||||
}
|
||||
|
||||
#define PATHS 10u
|
||||
#define PATHS 11u
|
||||
static const char *const path_name[PATHS] = { "a text that prints", "SEND", "SEND with no way", "AWAIT answered", "AWAIT ended by a GONE", "passing on while its text waits for room",
|
||||
"AWAIT broken by a line from the console", "a refusal while its text waits for room", "GONE",
|
||||
"a spent message refused while its text waits" };
|
||||
"a spent message refused while its text waits", "AWAIT ended by a GONE that is handed on" };
|
||||
static char numbers[8192]; /* what 1200 0 DO I . LOOP prints */
|
||||
|
||||
/* A row made afresh for one path; node 11 is given the word ACT that takes it, and the words that fill the
|
||||
@@ -239,6 +239,7 @@ static int made(unsigned path)
|
||||
": ACT 1200 0 DO I . LOOP ;",
|
||||
": ACT 44 12 GONE ;",
|
||||
": ACT 1200 0 DO I . LOOP ;",
|
||||
": ACT 77 AWAIT DROP ;",
|
||||
};
|
||||
char line[64];
|
||||
unsigned k;
|
||||
@@ -250,6 +251,11 @@ static int made(unsigned path)
|
||||
}
|
||||
if (path == 2 && !told(11, "NO-ROUTES 1 2 ROUTE 10 2 ROUTE 12 3 ROUTE")) return 0; /* no way for any node it has not been told of */
|
||||
if (path == 4 && !told(12, ": LL 400000 0 DO LOOP ;")) return 0;
|
||||
/* path 10: node 11 waits on a node 77 that never answers; its centre says 77 is gone, and node 11 hands the
|
||||
* believed GONE on (MESH.md 9a.2, ruling 7) -- a GONE about 44 to node 12, which knows a way to 44. (Not
|
||||
* about 12: believing a GONE about 12 makes node 11 forget its way to 12, and a GONE-DOWN never tells a node
|
||||
* of its own going.) */
|
||||
if (path == 10 && !told(11, "VARIABLE FWD : DOWN DROP 44 12 GONE 1 FWD +! ; ' DOWN (GONE-HOOK) !")) return 0;
|
||||
if (path == 5 && !told(10, ": SLOW 500000 0 DO LOOP ; : BUSY SLOW S\" 1 DROP\" 12 SEND SLOW ;")) return 0;
|
||||
if (path == 9 && !told(10, ": SLOW 500000 0 DO LOOP ; : BUSY SLOW SLOW ;")) return 0;
|
||||
/* 320 characters: more than fits beside what node 11 itself is waiting to print */
|
||||
@@ -280,12 +286,16 @@ static int one(unsigned path, const char *what, unsigned depth, const char *text
|
||||
runs++;
|
||||
step_cap = 60000000;
|
||||
if (path == 8 && !told(12, "44 2 ROUTE")) why = "node 12 did not take a way";
|
||||
if (path == 10 && !(told(11, "0 FWD !") && told(12, "44 NO-ROUTE 44 2 ROUTE"))) why = "node 11 did not clear FWD, or node 12 did not take a way to 44";
|
||||
ways12 = pool[far].n.mem[ROUTE_COUNT];
|
||||
forget();
|
||||
saw_room_wait = 0; saw_passed = 0;
|
||||
clock12 = pool[far].es.anticlock;
|
||||
if (why) { }
|
||||
else if (path == 4) { /* node 12 is busy for a long while and sends no answer; node 11 waits; its centre says 12 is gone */
|
||||
else if (path == 10) { /* node 11 waits on 77; its centre says 77 is gone */
|
||||
if (!put_text(11, text) || !run()) why = "it did not come to wait";
|
||||
else if (!put_text(10, "77 11 GONE") || !run()) why = "the nodes did not come to rest";
|
||||
} else if (path == 4) { /* node 12 is busy for a long while and sends no answer; node 11 waits; its centre says 12 is gone */
|
||||
stuck = 1u << far;
|
||||
if (!put_text(12, "LL") || !put_text(11, text) || !run()) why = "it did not come to wait";
|
||||
else if (!put_text(10, "12 11 GONE") || !run()) why = "the GONE was not done";
|
||||
@@ -340,6 +350,17 @@ static int one(unsigned path, const char *what, unsigned depth, const char *text
|
||||
clean_error = over && is_cut_short(printed, numbers, over) && pool[far].n.mem[REFUSED] == refused12 + 1; break; /* whoever refused it, node 12 was told */
|
||||
case 8: works = how11 == V4_TEXT_COMPLETED && printed_len == 0 && left == values && pool[far].n.mem[ROUTE_COUNT] == ways12 - 1;
|
||||
clean_error = over && strcmp(printed, over) == 0; break;
|
||||
case 10: {
|
||||
int down = pool[far].n.mem[ROUTE_COUNT] == ways12 - 1; /* node 12 believed the GONE node 11 handed on */
|
||||
works = how11 == V4_TEXT_ERROR && strcmp(printed, "Node gone\n") == 0 && left == values && down;
|
||||
clean_error = over && strcmp(printed, over) == 0;
|
||||
if (works) works = strcmp(tell(11, "FWD @ ."), "1 ") == 0;
|
||||
else if (clean_error) {
|
||||
int fwd1 = strcmp(tell(11, "FWD @ ."), "1 ") == 0, fwd0 = strcmp(printed, "0 ") == 0;
|
||||
clean_error = down ? (fwd1 || fwd0) : fwd0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 9: works = how11 == V4_TEXT_COMPLETED && strcmp(printed, numbers) == 0 && left == values && saw_room_wait > 0
|
||||
&& pool[mid].n.mem[LOST] == lost11 + 1 && pool[far].n.mem[REFUSED] == refused12 + 1;
|
||||
clean_error = over && is_cut_short(printed, numbers, over) && pool[mid].n.mem[LOST] == lost11 + 1 && pool[far].n.mem[REFUSED] == refused12 + 1; break; /* it was dropped: its sender was told */
|
||||
@@ -420,7 +441,7 @@ int main(void)
|
||||
first_error = 0;
|
||||
for (k = V4_RET_DEPTH - 18u; k <= V4_RET_DEPTH + 1u; k++) {
|
||||
snprintf(text, sizeof text, "N%u", k);
|
||||
r = one(path, "calls deep", k, text, 0, k + ((path == 5 || path == 7 || path == 9) ? 16u : 11u) <= V4_RET_DEPTH);
|
||||
r = one(path, "calls deep", k, text, 0, k + ((path == 5 || path == 7 || path == 9) ? 16u : path == 10 ? 14u : 11u) <= V4_RET_DEPTH);
|
||||
if (r == 0 && !first_error) first_error = k;
|
||||
}
|
||||
printf(" calls: works to %u deep; %u worked, %u clean errors, %u failures\n", first_error ? first_error - 1u : (unsigned)(V4_RET_DEPTH + 1u), worked - w0, refused_clean - e0, bad - before);
|
||||
|
||||
Reference in New Issue
Block a user