verdict4 0.2.0__tar.gz

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.
@@ -0,0 +1,54 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ build:
12
+ name: Build distributions
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Check out the released tag
16
+ uses: actions/checkout@v4
17
+ with:
18
+ ref: ${{ github.event.release.tag_name }}
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.x"
24
+
25
+ - name: Install build tooling
26
+ run: python -m pip install --upgrade build
27
+
28
+ - name: Build distributions
29
+ run: python -m build
30
+
31
+ - name: Upload distributions
32
+ uses: actions/upload-artifact@v4
33
+ with:
34
+ name: python-package-distributions
35
+ path: dist/
36
+
37
+ publish:
38
+ name: Publish distributions
39
+ needs: build
40
+ runs-on: ubuntu-latest
41
+ environment:
42
+ name: pypi
43
+ url: https://pypi.org/p/verdict4
44
+ permissions:
45
+ id-token: write
46
+ steps:
47
+ - name: Download distributions
48
+ uses: actions/download-artifact@v4
49
+ with:
50
+ name: python-package-distributions
51
+ path: dist/
52
+
53
+ - name: Publish distributions to PyPI
54
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,8 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .mypy_cache/
7
+ .pytest_cache/
8
+ .venv/
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to verdict4 are documented here.
4
+
5
+ ## 0.2.0 — 2026-09-04
6
+
7
+ - Add the substrate-free `QICTController` with finite-rank termination.
8
+ - Add typed `EvidenceNeed` and `ComputeNeed` payloads for `MAYBE`.
9
+ - Add one-use failure, evidence, computation, and dependency alphabets.
10
+ - Add logical lease expiry as a controller event.
11
+ - Add receipt replay auditing without candidate activations.
12
+ - Preserve the v0.1.0 runner API and legacy string `MAYBE` behavior.
13
+
14
+ ## 0.1.0 — 2026-07-17
15
+
16
+ - Initial four-verdict protocol and agent-loop runner.
verdict4-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MetaCortex Dynamics
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.5
2
+ Name: verdict4
3
+ Version: 0.2.0
4
+ Summary: Four-value evaluation for agentic AI loops. Replace pass/fail with NO/YES/MAYBE/IFF.
5
+ Project-URL: Homepage, https://github.com/MetaCortex-Dynamics/verdict4
6
+ Project-URL: Documentation, https://metacortexdynamics.substack.com/p/your-loop-has-two-states-it-needs
7
+ Project-URL: Repository, https://github.com/MetaCortex-Dynamics/verdict4
8
+ Project-URL: Issues, https://github.com/MetaCortex-Dynamics/verdict4/issues
9
+ Project-URL: Paper, https://doi.org/10.5281/zenodo.22309225
10
+ Author-email: MetaCortex Dynamics <Contact@metacortexdynamics.com>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: agentic,ai,evaluation,loop,quaternary,verdict
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.11
23
+ Description-Content-Type: text/markdown
24
+
25
+ # verdict4
26
+
27
+ Four-value evaluation for agentic AI loops.
28
+
29
+ **Replace pass/fail with NO / YES / MAYBE / IFF.**
30
+
31
+ Most agentic loops evaluate with a boolean. Pass or fail. That works when every non-pass condition is actually failure. But it is not. Some outputs cannot be evaluated yet because evidence is missing. Some outputs are correct only if another result holds. A boolean check compresses both into failure and destroys correct work.
32
+
33
+ This package provides a four-value `Verdict` enum, a structured `CheckResult`, and a loop runner that handles all four branches.
34
+
35
+ Read the full explanation: [Your Loop Has Two States. It Needs Four.](https://metacortexdynamics.substack.com/p/your-loop-has-two-states-it-needs)
36
+
37
+ The finite-rank controller is specified in [Quaternary Iteration Control for Looped Transformers](https://doi.org/10.5281/zenodo.22309225). The controller is included in this release; looped-transformer substrate integration is in preparation.
38
+
39
+ ## Install
40
+
41
+ Install directly from GitHub:
42
+
43
+ ```bash
44
+ pip install git+https://github.com/MetaCortex-Dynamics/verdict4.git@v0.2.0
45
+ ```
46
+
47
+ Or from source:
48
+
49
+ ```bash
50
+ git clone https://github.com/MetaCortex-Dynamics/verdict4.git
51
+ cd verdict4
52
+ pip install -e .
53
+ ```
54
+
55
+ After the GitHub release has published the package to PyPI, install the pinned release with:
56
+
57
+ ```bash
58
+ pip install verdict4==0.2.0
59
+ ```
60
+
61
+ Until that release workflow completes, use the GitHub install above.
62
+
63
+ ## Quick start
64
+
65
+ ```python
66
+ from quaternary import Verdict, CheckResult, no, yes, maybe, iff, run
67
+
68
+ # Define your check function — return a CheckResult, not a bool
69
+ def check(output):
70
+ if not output.get("valid"):
71
+ return no("validation failed: missing required field")
72
+ if not output.get("schema_available"):
73
+ return maybe("schema file not found")
74
+ if output.get("depends_on_auth"):
75
+ return iff("auth module deployed")
76
+ return yes()
77
+
78
+ # Define your generator
79
+ def generate(task, *, exclusions):
80
+ # Your agent generates output here
81
+ # `exclusions` carries named reasons from prior NO results
82
+ return {"valid": True, "schema_available": True}
83
+
84
+ # Run the loop
85
+ outcome = run(
86
+ task="build parser",
87
+ generate=generate,
88
+ check=check,
89
+ )
90
+
91
+ print(outcome.status) # "accepted" | "held" | "blocked" | "exhausted"
92
+ print(outcome.exclusions) # accumulated NO reasons
93
+ print(outcome.rounds) # how many iterations
94
+ ```
95
+
96
+ ## The four verdicts
97
+
98
+ | Verdict | Meaning | Loop action |
99
+ |---------|---------|-------------|
100
+ | `NO` | Fails a named condition | Add reason to exclusions, retry |
101
+ | `YES` | Satisfies conditions | Accept |
102
+ | `MAYBE` | Cannot evaluate — evidence missing | Hold, gather evidence, recheck |
103
+ | `IFF` | Correct if dependency holds | Bind to dependency, resolve, recheck |
104
+
105
+ ## API
106
+
107
+ ### Core types
108
+
109
+ ```python
110
+ from quaternary import Verdict, CheckResult, no, yes, maybe, iff
111
+ ```
112
+
113
+ **`Verdict`** — `IntEnum` with values `NO=0`, `YES=1`, `MAYBE=2`, `IFF=3`
114
+
115
+ **`CheckResult`** — frozen dataclass:
116
+ - `verdict: Verdict`
117
+ - `reason: str | None` — required for `NO`
118
+ - `needed: str | EvidenceNeed | ComputeNeed | None` — required for `MAYBE`
119
+ - `dependency: str | None` — required for `IFF`
120
+ - `meta: dict[str, Any]` — optional domain metadata
121
+
122
+ **Constructors**: `no(reason)`, `yes()`, `maybe(needed)`, `iff(dependency)` — all accept `**meta` kwargs.
123
+
124
+ ### Runner
125
+
126
+ ```python
127
+ from quaternary import run, LoopOutcome
128
+ ```
129
+
130
+ **`run(task, *, generate, check, ...)`** — runs the quaternary loop.
131
+
132
+ Required:
133
+ - `generate(task, *, exclusions) -> output`
134
+ - `check(output) -> CheckResult`
135
+
136
+ Optional:
137
+ - `gather(needed) -> evidence` — called on MAYBE
138
+ - `recheck(output, evidence?) -> CheckResult` — called after gather or dependency resolution
139
+ - `is_resolved(dep) -> bool` — called on IFF
140
+ - `is_failed(dep) -> bool` — called on IFF
141
+ - `max_rounds: int` — default 10
142
+ - `on_hold(output, reason)` — callback when holding
143
+ - `on_blocked(output, dep)` — callback when blocked
144
+
145
+ **`LoopOutcome`**:
146
+ - `status`: `"accepted"` | `"held"` | `"blocked"` | `"exhausted"`
147
+ - `output`: the final output (or None if exhausted)
148
+ - `exclusions`: accumulated NO reasons
149
+ - `rounds`: iterations used
150
+ - `held_reason` / `blocked_by`: why the loop stopped
151
+ - `contradiction`: flagged contradictory exclusion pairs (if any)
152
+
153
+ ### Finite-rank controller
154
+
155
+ Version 0.2.0 adds a substrate-free controller for repeated computation. It
156
+ preserves the v0.1.0 runner API while adding typed `MAYBE` needs, finite
157
+ one-use alphabets, dependency bindings, logical leases, and replayable
158
+ accounting receipts.
159
+
160
+ ```python
161
+ from quaternary import (
162
+ ComputeNeed,
163
+ QICTConfig,
164
+ QICTController,
165
+ maybe,
166
+ rank,
167
+ yes,
168
+ )
169
+
170
+ config = QICTConfig(compute_alphabet={"next_1", "next_2"})
171
+ controller = QICTController(config)
172
+ initial_rank = rank(config, controller.state)
173
+
174
+ controller.process(maybe(ComputeNeed("next_1")))
175
+ controller.process(maybe(ComputeNeed("next_2")))
176
+ controller.process(yes())
177
+
178
+ assert controller.state.evaluation_count <= initial_rank + 1
179
+ assert controller.audit().valid
180
+ ```
181
+
182
+ Every evaluation that continues consumes exactly one finite opportunity: a
183
+ new exclusion, an evidence request, another computation, or a dependency.
184
+ Therefore the controller terminates in at most `initial_rank + 1`
185
+ evaluations, without assuming that the evaluator is sound.
186
+
187
+ Receipts contain controller accounting state and transition data. Candidate
188
+ activations are excluded from the receipt state by type.
189
+
190
+ ## Examples
191
+
192
+ ```bash
193
+ python examples/json_parser.py
194
+ python examples/multi_file_refactor.py
195
+ ```
196
+
197
+ ## Design constraints
198
+
199
+ - **Zero domain logic.** The runner is a protocol over user-supplied callables.
200
+ - **No framework.** The fix is local — an enum and a branch.
201
+ - **Bounded MAYBE.** A second MAYBE after evidence gathering → hold and report. No infinite gather loops.
202
+ - **Exclusion memory.** NO reasons accumulate across rounds. Contradictions are flagged, not resolved.
203
+ - **No dependencies.** Standard library only.
204
+
205
+ ## License
206
+
207
+ MIT — [MetaCortex Dynamics](https://github.com/MetaCortex-Dynamics)
@@ -0,0 +1,183 @@
1
+ # verdict4
2
+
3
+ Four-value evaluation for agentic AI loops.
4
+
5
+ **Replace pass/fail with NO / YES / MAYBE / IFF.**
6
+
7
+ Most agentic loops evaluate with a boolean. Pass or fail. That works when every non-pass condition is actually failure. But it is not. Some outputs cannot be evaluated yet because evidence is missing. Some outputs are correct only if another result holds. A boolean check compresses both into failure and destroys correct work.
8
+
9
+ This package provides a four-value `Verdict` enum, a structured `CheckResult`, and a loop runner that handles all four branches.
10
+
11
+ Read the full explanation: [Your Loop Has Two States. It Needs Four.](https://metacortexdynamics.substack.com/p/your-loop-has-two-states-it-needs)
12
+
13
+ The finite-rank controller is specified in [Quaternary Iteration Control for Looped Transformers](https://doi.org/10.5281/zenodo.22309225). The controller is included in this release; looped-transformer substrate integration is in preparation.
14
+
15
+ ## Install
16
+
17
+ Install directly from GitHub:
18
+
19
+ ```bash
20
+ pip install git+https://github.com/MetaCortex-Dynamics/verdict4.git@v0.2.0
21
+ ```
22
+
23
+ Or from source:
24
+
25
+ ```bash
26
+ git clone https://github.com/MetaCortex-Dynamics/verdict4.git
27
+ cd verdict4
28
+ pip install -e .
29
+ ```
30
+
31
+ After the GitHub release has published the package to PyPI, install the pinned release with:
32
+
33
+ ```bash
34
+ pip install verdict4==0.2.0
35
+ ```
36
+
37
+ Until that release workflow completes, use the GitHub install above.
38
+
39
+ ## Quick start
40
+
41
+ ```python
42
+ from quaternary import Verdict, CheckResult, no, yes, maybe, iff, run
43
+
44
+ # Define your check function — return a CheckResult, not a bool
45
+ def check(output):
46
+ if not output.get("valid"):
47
+ return no("validation failed: missing required field")
48
+ if not output.get("schema_available"):
49
+ return maybe("schema file not found")
50
+ if output.get("depends_on_auth"):
51
+ return iff("auth module deployed")
52
+ return yes()
53
+
54
+ # Define your generator
55
+ def generate(task, *, exclusions):
56
+ # Your agent generates output here
57
+ # `exclusions` carries named reasons from prior NO results
58
+ return {"valid": True, "schema_available": True}
59
+
60
+ # Run the loop
61
+ outcome = run(
62
+ task="build parser",
63
+ generate=generate,
64
+ check=check,
65
+ )
66
+
67
+ print(outcome.status) # "accepted" | "held" | "blocked" | "exhausted"
68
+ print(outcome.exclusions) # accumulated NO reasons
69
+ print(outcome.rounds) # how many iterations
70
+ ```
71
+
72
+ ## The four verdicts
73
+
74
+ | Verdict | Meaning | Loop action |
75
+ |---------|---------|-------------|
76
+ | `NO` | Fails a named condition | Add reason to exclusions, retry |
77
+ | `YES` | Satisfies conditions | Accept |
78
+ | `MAYBE` | Cannot evaluate — evidence missing | Hold, gather evidence, recheck |
79
+ | `IFF` | Correct if dependency holds | Bind to dependency, resolve, recheck |
80
+
81
+ ## API
82
+
83
+ ### Core types
84
+
85
+ ```python
86
+ from quaternary import Verdict, CheckResult, no, yes, maybe, iff
87
+ ```
88
+
89
+ **`Verdict`** — `IntEnum` with values `NO=0`, `YES=1`, `MAYBE=2`, `IFF=3`
90
+
91
+ **`CheckResult`** — frozen dataclass:
92
+ - `verdict: Verdict`
93
+ - `reason: str | None` — required for `NO`
94
+ - `needed: str | EvidenceNeed | ComputeNeed | None` — required for `MAYBE`
95
+ - `dependency: str | None` — required for `IFF`
96
+ - `meta: dict[str, Any]` — optional domain metadata
97
+
98
+ **Constructors**: `no(reason)`, `yes()`, `maybe(needed)`, `iff(dependency)` — all accept `**meta` kwargs.
99
+
100
+ ### Runner
101
+
102
+ ```python
103
+ from quaternary import run, LoopOutcome
104
+ ```
105
+
106
+ **`run(task, *, generate, check, ...)`** — runs the quaternary loop.
107
+
108
+ Required:
109
+ - `generate(task, *, exclusions) -> output`
110
+ - `check(output) -> CheckResult`
111
+
112
+ Optional:
113
+ - `gather(needed) -> evidence` — called on MAYBE
114
+ - `recheck(output, evidence?) -> CheckResult` — called after gather or dependency resolution
115
+ - `is_resolved(dep) -> bool` — called on IFF
116
+ - `is_failed(dep) -> bool` — called on IFF
117
+ - `max_rounds: int` — default 10
118
+ - `on_hold(output, reason)` — callback when holding
119
+ - `on_blocked(output, dep)` — callback when blocked
120
+
121
+ **`LoopOutcome`**:
122
+ - `status`: `"accepted"` | `"held"` | `"blocked"` | `"exhausted"`
123
+ - `output`: the final output (or None if exhausted)
124
+ - `exclusions`: accumulated NO reasons
125
+ - `rounds`: iterations used
126
+ - `held_reason` / `blocked_by`: why the loop stopped
127
+ - `contradiction`: flagged contradictory exclusion pairs (if any)
128
+
129
+ ### Finite-rank controller
130
+
131
+ Version 0.2.0 adds a substrate-free controller for repeated computation. It
132
+ preserves the v0.1.0 runner API while adding typed `MAYBE` needs, finite
133
+ one-use alphabets, dependency bindings, logical leases, and replayable
134
+ accounting receipts.
135
+
136
+ ```python
137
+ from quaternary import (
138
+ ComputeNeed,
139
+ QICTConfig,
140
+ QICTController,
141
+ maybe,
142
+ rank,
143
+ yes,
144
+ )
145
+
146
+ config = QICTConfig(compute_alphabet={"next_1", "next_2"})
147
+ controller = QICTController(config)
148
+ initial_rank = rank(config, controller.state)
149
+
150
+ controller.process(maybe(ComputeNeed("next_1")))
151
+ controller.process(maybe(ComputeNeed("next_2")))
152
+ controller.process(yes())
153
+
154
+ assert controller.state.evaluation_count <= initial_rank + 1
155
+ assert controller.audit().valid
156
+ ```
157
+
158
+ Every evaluation that continues consumes exactly one finite opportunity: a
159
+ new exclusion, an evidence request, another computation, or a dependency.
160
+ Therefore the controller terminates in at most `initial_rank + 1`
161
+ evaluations, without assuming that the evaluator is sound.
162
+
163
+ Receipts contain controller accounting state and transition data. Candidate
164
+ activations are excluded from the receipt state by type.
165
+
166
+ ## Examples
167
+
168
+ ```bash
169
+ python examples/json_parser.py
170
+ python examples/multi_file_refactor.py
171
+ ```
172
+
173
+ ## Design constraints
174
+
175
+ - **Zero domain logic.** The runner is a protocol over user-supplied callables.
176
+ - **No framework.** The fix is local — an enum and a branch.
177
+ - **Bounded MAYBE.** A second MAYBE after evidence gathering → hold and report. No infinite gather loops.
178
+ - **Exclusion memory.** NO reasons accumulate across rounds. Contradictions are flagged, not resolved.
179
+ - **No dependencies.** Standard library only.
180
+
181
+ ## License
182
+
183
+ MIT — [MetaCortex Dynamics](https://github.com/MetaCortex-Dynamics)
@@ -0,0 +1,123 @@
1
+ """
2
+ Worked example: JSON parser — binary vs quaternary convergence.
3
+
4
+ From: "Your Loop Has Two States. It Needs Four."
5
+ https://metacortexdynamics.substack.com/p/your-loop-has-two-states-it-needs
6
+
7
+ Simulates the JSON parser scenario from the post.
8
+ Binary loop: 3 full generations, oscillation.
9
+ Quaternary loop: 1 generation, 1 targeted repair, convergence.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from quaternary import CheckResult, LoopOutcome, Verdict, iff, maybe, no, run, yes
15
+
16
+
17
+ # --- Simulated component state ---
18
+
19
+ class SimulatedParser:
20
+ """Simulates a parser that initially fails on nested arrays
21
+ and has a missing schema import."""
22
+
23
+ def __init__(self) -> None:
24
+ self.handles_nested_arrays = False
25
+ self.schema_imported = False
26
+ self.generation_count = 0
27
+
28
+ def generate(self, task: str, *, exclusions: list[str]) -> dict[str, str]:
29
+ self.generation_count += 1
30
+
31
+ # After being told about the nested array issue, fix it
32
+ if "nested array not handled" in exclusions:
33
+ self.handles_nested_arrays = True
34
+
35
+ return {
36
+ "parser": "json_parser_v" + str(self.generation_count),
37
+ "handles_nested": str(self.handles_nested_arrays),
38
+ "schema_imported": str(self.schema_imported),
39
+ }
40
+
41
+ def check(self, output: dict[str, str]) -> CheckResult:
42
+ """Evaluate each component."""
43
+ # Test 1: basic parsing — always passes
44
+ # Test 2: nested arrays
45
+ if output["handles_nested"] == "False":
46
+ return no("nested array not handled")
47
+
48
+ # Validator: depends on schema import
49
+ if output["schema_imported"] == "False":
50
+ return iff("schema library imported")
51
+
52
+ return yes()
53
+
54
+ def is_resolved(self, dep: str) -> bool:
55
+ if dep == "schema library imported":
56
+ # Simulate: resolve by importing
57
+ self.schema_imported = True
58
+ return True
59
+ return False
60
+
61
+ def is_failed(self, dep: str) -> bool:
62
+ return False
63
+
64
+ def recheck(self, output: dict[str, str], evidence: object = None) -> CheckResult:
65
+ # After dependency resolved, recheck
66
+ if self.schema_imported and self.handles_nested_arrays:
67
+ return yes()
68
+ return no("still failing after dependency resolution")
69
+
70
+
71
+ def run_binary_simulation() -> None:
72
+ """Simulate binary loop behavior from the post."""
73
+ print("=" * 60)
74
+ print("BINARY LOOP (simulated)")
75
+ print("=" * 60)
76
+
77
+ generations = 0
78
+ for attempt in range(1, 4):
79
+ generations += 1
80
+ print(f"\nRound {attempt}: generate everything from scratch")
81
+ if attempt == 1:
82
+ print(" test 2 fails: nested arrays not handled")
83
+ print(" -> regenerate everything")
84
+ elif attempt == 2:
85
+ print(" test 1 now fails (regression)")
86
+ print(" -> regenerate everything")
87
+ elif attempt == 3:
88
+ print(" schema validator fails: missing import")
89
+ print(" -> regenerate everything")
90
+
91
+ print(f"\nResult: {generations} full generations, oscillation, no convergence")
92
+
93
+
94
+ def run_quaternary() -> None:
95
+ """Run actual quaternary loop."""
96
+ print("\n" + "=" * 60)
97
+ print("QUATERNARY LOOP")
98
+ print("=" * 60)
99
+
100
+ sim = SimulatedParser()
101
+
102
+ outcome: LoopOutcome = run(
103
+ task="write json parser with schema validation",
104
+ generate=sim.generate,
105
+ check=sim.check,
106
+ recheck=sim.recheck,
107
+ is_resolved=sim.is_resolved,
108
+ is_failed=sim.is_failed,
109
+ max_rounds=5,
110
+ )
111
+
112
+ print(f"\nStatus: {outcome.status}")
113
+ print(f"Rounds: {outcome.rounds}")
114
+ print(f"Generations: {sim.generation_count}")
115
+ print(f"Exclusions accumulated: {outcome.exclusions}")
116
+ if outcome.contradiction:
117
+ print(f"Contradictions flagged: {outcome.contradiction}")
118
+ print(f"Output: {outcome.output}")
119
+
120
+
121
+ if __name__ == "__main__":
122
+ run_binary_simulation()
123
+ run_quaternary()