re: the sufficient side -- each phase exit now names the condition that FIRES it
Dominance said a phase cannot end unless X. A port also needs "once X holds, it must end", and that is a must-reach set: nodes from which END_PHASE is unavoidable, as a least fixpoint where n qualifies when it has successors and ALL of them qualify. The conservatism is deliberate and is the honest answer: a loop never enters the set, because a poll loop reaches its exit only if the polled predicate eventually becomes true, which is a liveness property rather than a graph one. A dominating condition is a TRIGGER when the successor it takes on being satisfied lies in that set. Over all 28 stages: 732 dominating conditions, 234 triggers (31.97%). isl_report.py phase-guards now tags every line precond / TRIGGER. The split lands where it should. Stage 02's phase-1 objective exit is six preconditions -- player alive, TCN004 destroyed, t <= 210, ADT102/ADT107/ADT113 destroyed -- and exactly ONE trigger: hp_pct_test(ADN101, 0) != 1. Destroying ADN101 is what fires the phase. That is a sentence a port can implement. Per-exit distribution over 172 reachable exits: 89 have exactly one trigger, 42 have none, 41 have several. The 42 with none are not a failure -- they are the exits no branch fires; Stage 02's 0x006260 ends on read_freg(0) < 1200, a timeout, and time passing is not a property of the graph, so declining to call it a trigger is correct. Recorded as a heuristic rather than a rule: "the first trigger is the point of no return" holds for 33 of the 41 multi-trigger exits, with 8 counterexamples where a precondition appears after a trigger. The likely cause is that the listing is ordered by file offset, which is not execution order -- coroutines and jumps let a lower offset run later. Not asserted. calls, phase-ends and conditions all regenerate byte-identical; the two phase-guards artefacts change only by gaining the tags.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -9,94 +9,99 @@ in a poll loop both successors reach the exit.
|
||||
|
||||
CFG reached 15670 of 18739 instructions (83.6%).
|
||||
|
||||
`precond` = necessary: the exit cannot happen unless it holds.
|
||||
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
|
||||
An exit with no TRIGGER is not fired by a branch — a timeout exit is
|
||||
fired by time passing, which is not a property of the graph.
|
||||
|
||||
## phase 1 — END_PHASE at 0x0051E4: 2 necessary condition(s)
|
||||
0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x005110 random(3) == 0
|
||||
precond 0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
TRIGGER 0x005110 random(3) == 0
|
||||
|
||||
## phase 1 — END_PHASE at 0x005828: 3 necessary condition(s)
|
||||
0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x00523C hp_pct_test(TCN004, 0) != 1
|
||||
0x00572C random(5) == 0
|
||||
precond 0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
precond 0x00523C hp_pct_test(TCN004, 0) != 1
|
||||
TRIGGER 0x00572C random(5) == 0
|
||||
|
||||
## phase 1 — END_PHASE at 0x006010: 7 necessary condition(s)
|
||||
0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x00523C hp_pct_test(TCN004, 0) != 1
|
||||
0x005888 read_freg(0) <= 210
|
||||
0x0058DC hp_pct_test(ADT102, 0) != 1
|
||||
0x005930 hp_pct_test(ADT107, 0) != 1
|
||||
0x005984 hp_pct_test(ADT113, 0) != 1
|
||||
0x005B3C hp_pct_test(ADN101, 0) != 1
|
||||
precond 0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
precond 0x00523C hp_pct_test(TCN004, 0) != 1
|
||||
precond 0x005888 read_freg(0) <= 210
|
||||
precond 0x0058DC hp_pct_test(ADT102, 0) != 1
|
||||
precond 0x005930 hp_pct_test(ADT107, 0) != 1
|
||||
precond 0x005984 hp_pct_test(ADT113, 0) != 1
|
||||
TRIGGER 0x005B3C hp_pct_test(ADN101, 0) != 1
|
||||
|
||||
## phase 1 — END_PHASE at 0x006260: 4 necessary condition(s)
|
||||
0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x00523C hp_pct_test(TCN004, 0) != 1
|
||||
0x005888 read_freg(0) <= 210
|
||||
0x006070 read_freg(0) < 1200
|
||||
precond 0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
precond 0x00523C hp_pct_test(TCN004, 0) != 1
|
||||
precond 0x005888 read_freg(0) <= 210
|
||||
precond 0x006070 read_freg(0) < 1200
|
||||
|
||||
## phase 1 — FORCE_END_PHASE at 0x01482C: UNREACHABLE from any static entry
|
||||
(started from the trigger queue at `phase+272`, by data not code)
|
||||
|
||||
## phase 2 — END_PHASE at 0x019640: 2 necessary condition(s)
|
||||
0x0191CC unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x01956C random(3) == 0
|
||||
precond 0x0191CC unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
TRIGGER 0x01956C random(3) == 0
|
||||
|
||||
## phase 2 — END_PHASE at 0x019934: 2 necessary condition(s)
|
||||
0x0191CC unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x019698 hp_pct_test(TCT206, 0) != 1
|
||||
precond 0x0191CC unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
precond 0x019698 hp_pct_test(TCT206, 0) != 1
|
||||
|
||||
## phase 2 — END_PHASE at 0x01AC44: 9 necessary condition(s)
|
||||
0x0191CC unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x019698 hp_pct_test(TCT206, 0) != 1
|
||||
0x0199C8 builtin7(TCT206, 1, Route_TCT206_p2S, 4294967295, 500) == 1
|
||||
0x019A8C <unknown> <= 240
|
||||
0x01A1E4 global[4] == 0
|
||||
0x01A2B0 global[4] != 1
|
||||
0x01A924 hp_pct_test(TCT206, 89.9) != 0
|
||||
0x01AA38 global[104] != 0
|
||||
0x01AAF8 global[4] == 0
|
||||
precond 0x0191CC unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
precond 0x019698 hp_pct_test(TCT206, 0) != 1
|
||||
precond 0x0199C8 builtin7(TCT206, 1, Route_TCT206_p2S, 4294967295, 500) == 1
|
||||
precond 0x019A8C <unknown> <= 240
|
||||
precond 0x01A1E4 global[4] == 0
|
||||
TRIGGER 0x01A2B0 global[4] != 1
|
||||
TRIGGER 0x01A924 hp_pct_test(TCT206, 89.9) != 0
|
||||
TRIGGER 0x01AA38 global[104] != 0
|
||||
TRIGGER 0x01AAF8 global[4] == 0
|
||||
|
||||
## phase 2 — FORCE_END_PHASE at 0x0249F0: 2 necessary condition(s)
|
||||
0x0247E4 hp_pct_test(ADN202, 0) != 1
|
||||
0x024848 unit_state(TCT206) != 1
|
||||
precond 0x0247E4 hp_pct_test(ADN202, 0) != 1
|
||||
TRIGGER 0x024848 unit_state(TCT206) != 1
|
||||
|
||||
## phase 3 — END_PHASE at 0x02B96C: 2 necessary condition(s)
|
||||
0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x02B898 random(3) == 0
|
||||
precond 0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
TRIGGER 0x02B898 random(3) == 0
|
||||
|
||||
## phase 3 — END_PHASE at 0x02BFB0: 3 necessary condition(s)
|
||||
0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
0x02BEB4 random(5) == 0
|
||||
precond 0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
precond 0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
TRIGGER 0x02BEB4 random(5) == 0
|
||||
|
||||
## phase 3 — END_PHASE at 0x02C1E0: 3 necessary condition(s)
|
||||
0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
0x02BFC8 global[112] < 4
|
||||
precond 0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
precond 0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
precond 0x02BFC8 global[112] < 4
|
||||
|
||||
## phase 3 — END_PHASE at 0x02CF74: 16 necessary condition(s)
|
||||
0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
0x02BFC8 global[112] < 4
|
||||
0x02C240 read_freg(0) <= 300
|
||||
0x02C294 hp_pct_test(ADT301, 0) != 1
|
||||
0x02C2E8 hp_pct_test(ADT302, 0) != 1
|
||||
0x02C33C hp_pct_test(ADT303, 0) != 1
|
||||
0x02C390 hp_pct_test(ADT304, 0) != 1
|
||||
0x02C3E4 hp_pct_test(ADT305, 0) != 1
|
||||
0x02C438 hp_pct_test(ADT306, 0) != 1
|
||||
0x02C48C hp_pct_test(ADT307, 0) != 1
|
||||
0x02C4E0 hp_pct_test(ADT308, 0) != 1
|
||||
0x02C5C4 global[112] != 0
|
||||
0x02CC0C global[112] != 0
|
||||
0x02CDC8 global[4] == 0
|
||||
0x02CE9C global[112] != 0
|
||||
precond 0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
precond 0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
precond 0x02BFC8 global[112] < 4
|
||||
precond 0x02C240 read_freg(0) <= 300
|
||||
precond 0x02C294 hp_pct_test(ADT301, 0) != 1
|
||||
precond 0x02C2E8 hp_pct_test(ADT302, 0) != 1
|
||||
precond 0x02C33C hp_pct_test(ADT303, 0) != 1
|
||||
precond 0x02C390 hp_pct_test(ADT304, 0) != 1
|
||||
precond 0x02C3E4 hp_pct_test(ADT305, 0) != 1
|
||||
precond 0x02C438 hp_pct_test(ADT306, 0) != 1
|
||||
precond 0x02C48C hp_pct_test(ADT307, 0) != 1
|
||||
precond 0x02C4E0 hp_pct_test(ADT308, 0) != 1
|
||||
TRIGGER 0x02C5C4 global[112] != 0
|
||||
TRIGGER 0x02CC0C global[112] != 0
|
||||
TRIGGER 0x02CDC8 global[4] == 0
|
||||
TRIGGER 0x02CE9C global[112] != 0
|
||||
|
||||
## phase 3 — END_PHASE at 0x02D1DC: 5 necessary condition(s)
|
||||
0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
0x02BFC8 global[112] < 4
|
||||
0x02C240 read_freg(0) <= 300
|
||||
0x02CFD4 read_freg(0) < 1200
|
||||
precond 0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
precond 0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
precond 0x02BFC8 global[112] < 4
|
||||
precond 0x02C240 read_freg(0) <= 300
|
||||
precond 0x02CFD4 read_freg(0) < 1200
|
||||
|
||||
## phase 3 — FORCE_END_PHASE at 0x034A10: UNREACHABLE from any static entry
|
||||
(started from the trigger queue at `phase+272`, by data not code)
|
||||
|
||||
Reference in New Issue
Block a user