fable-engine 1.3.1__py3-none-any.whl

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.
Files changed (104) hide show
  1. fable_compressor.py +356 -0
  2. fable_engine/__init__.py +1 -0
  3. fable_engine/actions/__init__.py +291 -0
  4. fable_engine/actions/cas.py +182 -0
  5. fable_engine/actions/deliberation.py +523 -0
  6. fable_engine/actions/fleet.py +807 -0
  7. fable_engine/actions/lifecycle.py +298 -0
  8. fable_engine/actions/scrapers.py +116 -0
  9. fable_engine/actions/system3.py +815 -0
  10. fable_engine/browser.py +824 -0
  11. fable_engine/cas.py +974 -0
  12. fable_engine/fable_session.json +510 -0
  13. fable_engine/guards.py +283 -0
  14. fable_engine/schema.py +714 -0
  15. fable_engine/scrapers/__init__.py +32 -0
  16. fable_engine/scrapers/arxiv.py +115 -0
  17. fable_engine/scrapers/base.py +386 -0
  18. fable_engine/scrapers/github.py +129 -0
  19. fable_engine/scrapers/reddit.py +154 -0
  20. fable_engine/scrapers/web.py +120 -0
  21. fable_engine/scrapers/x.py +125 -0
  22. fable_engine/scrapers/youtube.py +132 -0
  23. fable_engine/server.py +414 -0
  24. fable_engine/session.py +1819 -0
  25. fable_engine/test_server.py +1362 -0
  26. fable_engine/updater.py +541 -0
  27. fable_engine-1.3.1.dist-info/LICENSE +22 -0
  28. fable_engine-1.3.1.dist-info/METADATA +173 -0
  29. fable_engine-1.3.1.dist-info/RECORD +104 -0
  30. fable_engine-1.3.1.dist-info/WHEEL +5 -0
  31. fable_engine-1.3.1.dist-info/entry_points.txt +5 -0
  32. fable_engine-1.3.1.dist-info/top_level.txt +6 -0
  33. fable_mode/__init__.py +3 -0
  34. fable_mode/__main__.py +4 -0
  35. fable_mode/adapters.py +1014 -0
  36. fable_mode/installer.py +553 -0
  37. fable_mode/launcher.py +437 -0
  38. fable_mode/manifest.py +142 -0
  39. fable_mode/resources.json +114 -0
  40. fable_mode/safety.py +103 -0
  41. fable_mode_entry.py +10 -0
  42. fable_v2/__init__.py +146 -0
  43. fable_v2/adapters.py +151 -0
  44. fable_v2/coder_fleet/__init__.py +100 -0
  45. fable_v2/coder_fleet/ast_tools.py +158 -0
  46. fable_v2/coder_fleet/compute.py +199 -0
  47. fable_v2/coder_fleet/design_engine.py +1316 -0
  48. fable_v2/coder_fleet/diagnostics.py +293 -0
  49. fable_v2/coder_fleet/fleet_dispatcher.py +214 -0
  50. fable_v2/coder_fleet/mock_auditor.py +306 -0
  51. fable_v2/coder_fleet/mutation.py +216 -0
  52. fable_v2/coder_fleet/property_oracle.py +260 -0
  53. fable_v2/coder_fleet/receipt_attestor.py +122 -0
  54. fable_v2/coder_fleet/red_team_swarm.py +908 -0
  55. fable_v2/coder_fleet/test_harness.py +198 -0
  56. fable_v2/coder_fleet/vector_engine.py +1287 -0
  57. fable_v2/coder_fleet/visual.py +357 -0
  58. fable_v2/coder_fleet/workspace.py +153 -0
  59. fable_v2/cortical/__init__.py +20 -0
  60. fable_v2/cortical/plasticity_engine.py +992 -0
  61. fable_v2/execution_broker.py +811 -0
  62. fable_v2/proof_engine.py +1141 -0
  63. fable_v2/protocol.py +485 -0
  64. fable_v2/runtime.py +1010 -0
  65. fable_v2/system3/__init__.py +204 -0
  66. fable_v2/system3/causal.py +558 -0
  67. fable_v2/system3/dialectical.py +577 -0
  68. fable_v2/system3/evolution.py +503 -0
  69. fable_v2/system3/executive.py +338 -0
  70. fable_v2/system3/free_energy.py +479 -0
  71. fable_v2/system3/hyperbolic.py +555 -0
  72. fable_v2/system3/induction.py +336 -0
  73. fable_v2/system3/kripke.py +548 -0
  74. fable_v2/system3/oracle.py +745 -0
  75. fable_v2/verifiers.py +72 -0
  76. tests/__init__.py +1 -0
  77. tests/test_anti_loop_circuit_breaker.py +64 -0
  78. tests/test_auto_updater.py +407 -0
  79. tests/test_coder_fleet.py +535 -0
  80. tests/test_delegation_compiler.py +54 -0
  81. tests/test_descriptor_boundaries.py +126 -0
  82. tests/test_design_engine.py +603 -0
  83. tests/test_epistemic_evidence_validator.py +66 -0
  84. tests/test_execution_broker.py +233 -0
  85. tests/test_fable_v2.py +406 -0
  86. tests/test_fleet_transitions.py +116 -0
  87. tests/test_fsm_redteam_evolution.py +406 -0
  88. tests/test_goal_rubric_and_pipeline.py +367 -0
  89. tests/test_hebbian_plasticity.py +585 -0
  90. tests/test_packaging_runtime.py +194 -0
  91. tests/test_proof_engine.py +259 -0
  92. tests/test_red_team_swarm.py +645 -0
  93. tests/test_redteam_remediation.py +169 -0
  94. tests/test_registration_transaction.py +375 -0
  95. tests/test_requested_regressions.py +467 -0
  96. tests/test_scrapers.py +370 -0
  97. tests/test_server_actions.py +93 -0
  98. tests/test_server_frontier_actions.py +269 -0
  99. tests/test_server_protocol.py +88 -0
  100. tests/test_stealth_browser.py +970 -0
  101. tests/test_system3.py +381 -0
  102. tests/test_system3_deep_integration.py +385 -0
  103. tests/test_system3_frontier.py +436 -0
  104. tests/test_vector_engine.py +608 -0
@@ -0,0 +1,745 @@
1
+ """System 3 Gödelian Auto-Formalizing Proof Oracle & Constructive Type Checker.
2
+
3
+ Implements the Curry-Howard Isomorphism (Propositions-as-Types, Proofs-as-Programs),
4
+ automated tactic proof synthesis, constructive type verification, and Gödelian
5
+ undecidability/incompleteness boundary detection in pure standard library Python. Zero external dependencies.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass, field, asdict
11
+ from enum import Enum
12
+ from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
13
+ import copy
14
+ import json
15
+ import re
16
+
17
+
18
+ class ProofStatus(str, Enum):
19
+ """Decision status of formal verification."""
20
+ DECIDABLE_PROVED = "decidable_proved" # Constructive proof term verified by type checker
21
+ DECIDABLE_REFUTED = "decidable_refuted" # Refutation / proof of negation (P -> Void) verified
22
+ INDEPENDENT_UNDECIDABLE = "independent_undecidable" # Provably undecidable / paradoxical / Gödelian boundary
23
+ COMPLEXITY_EXCEEDED = "complexity_exceeded" # Search budget exhausted without closure
24
+
25
+
26
+ # --------------------------------------------------------------------------------
27
+ # Constructive Types (Propositions as Types)
28
+ # --------------------------------------------------------------------------------
29
+
30
+ class TypeKind(str, Enum):
31
+ PROP = "PROP" # Atomic proposition / Base type
32
+ UNIT = "UNIT" # True / Top (T)
33
+ VOID = "VOID" # False / Bottom (Void)
34
+ IMPLIES = "IMPLIES" # Implication / Function type (A -> B)
35
+ AND = "AND" # Conjunction / Product type (A * B)
36
+ OR = "OR" # Disjunction / Sum type (A + B)
37
+ NOT = "NOT" # Negation (A -> Void)
38
+ EQ = "EQ" # Identity / Equality type (x = y)
39
+ FORALL = "FORALL" # Universal quantifier (forall x: T, P(x))
40
+ EXISTS = "EXISTS" # Existential quantifier (exists x: T, P(x))
41
+
42
+
43
+ @dataclass(frozen=True)
44
+ class Type:
45
+ """A formal proposition represented as a constructive type."""
46
+ kind: TypeKind
47
+ name: str = "" # For PROP or variable names
48
+ left: Optional["Type"] = None # Domain / Left operand
49
+ right: Optional["Type"] = None # Codomain / Right operand
50
+ var_name: str = "" # For FORALL / EXISTS variable
51
+ var_type: Optional["Type"] = None # For FORALL / EXISTS domain
52
+ term_x: str = "" # For EQ term 1
53
+ term_y: str = "" # For EQ term 2
54
+
55
+ def __repr__(self) -> str:
56
+ if self.kind == TypeKind.PROP:
57
+ return self.name
58
+ if self.kind == TypeKind.UNIT:
59
+ return "Unit"
60
+ if self.kind == TypeKind.VOID:
61
+ return "Void"
62
+ if self.kind == TypeKind.NOT and self.left:
63
+ return f"~{repr(self.left)}"
64
+ if self.kind == TypeKind.IMPLIES and self.left and self.right:
65
+ return f"({repr(self.left)} -> {repr(self.right)})"
66
+ if self.kind == TypeKind.AND and self.left and self.right:
67
+ return f"({repr(self.left)} /\\ {repr(self.right)})"
68
+ if self.kind == TypeKind.OR and self.left and self.right:
69
+ return f"({repr(self.left)} \\/ {repr(self.right)})"
70
+ if self.kind == TypeKind.EQ:
71
+ return f"({self.term_x} == {self.term_y})"
72
+ if self.kind == TypeKind.FORALL and self.left:
73
+ return f"(forall {self.var_name}: {repr(self.var_type)}, {repr(self.left)})"
74
+ if self.kind == TypeKind.EXISTS and self.left:
75
+ return f"(exists {self.var_name}: {repr(self.var_type)}, {repr(self.left)})"
76
+ return self.kind.value
77
+
78
+ def to_dict(self) -> Dict[str, Any]:
79
+ return {
80
+ "kind": self.kind.value,
81
+ "name": self.name,
82
+ "repr": repr(self),
83
+ "left": self.left.to_dict() if self.left else None,
84
+ "right": self.right.to_dict() if self.right else None,
85
+ "var_name": self.var_name,
86
+ "var_type": self.var_type.to_dict() if self.var_type else None,
87
+ "term_x": self.term_x,
88
+ "term_y": self.term_y,
89
+ }
90
+
91
+ @classmethod
92
+ def from_dict(cls, data: Dict[str, Any]) -> "Type":
93
+ left = cls.from_dict(data["left"]) if data.get("left") else None
94
+ right = cls.from_dict(data["right"]) if data.get("right") else None
95
+ var_type = cls.from_dict(data["var_type"]) if data.get("var_type") else None
96
+ return cls(
97
+ kind=TypeKind(data["kind"]),
98
+ name=data.get("name", ""),
99
+ left=left,
100
+ right=right,
101
+ var_name=data.get("var_name", ""),
102
+ var_type=var_type,
103
+ term_x=data.get("term_x", ""),
104
+ term_y=data.get("term_y", ""),
105
+ )
106
+
107
+
108
+ # Convenience Type Constructors
109
+ def Prop(name: str) -> Type:
110
+ return Type(TypeKind.PROP, name=name)
111
+
112
+ Unit = Type(TypeKind.UNIT)
113
+ Void = Type(TypeKind.VOID)
114
+
115
+ def Implies(a: Type, b: Type) -> Type:
116
+ return Type(TypeKind.IMPLIES, left=a, right=b)
117
+
118
+ def And(a: Type, b: Type) -> Type:
119
+ return Type(TypeKind.AND, left=a, right=b)
120
+
121
+ def Or(a: Type, b: Type) -> Type:
122
+ return Type(TypeKind.OR, left=a, right=b)
123
+
124
+ def Not(a: Type) -> Type:
125
+ return Implies(a, Void)
126
+
127
+ def Eq(x: str, y: str) -> Type:
128
+ return Type(TypeKind.EQ, term_x=x, term_y=y)
129
+
130
+ def Forall(var_name: str, var_type: Type, body: Type) -> Type:
131
+ return Type(TypeKind.FORALL, var_name=var_name, var_type=var_type, left=body)
132
+
133
+ def Exists(var_name: str, var_type: Type, body: Type) -> Type:
134
+ return Type(TypeKind.EXISTS, var_name=var_name, var_type=var_type, left=body)
135
+
136
+
137
+ # --------------------------------------------------------------------------------
138
+ # Constructive Terms (Proofs as Programs)
139
+ # --------------------------------------------------------------------------------
140
+
141
+ class TermKind(str, Enum):
142
+ VAR = "VAR" # Variable / Hypothesis reference (x)
143
+ UNIT = "UNIT" # () : Unit
144
+ LAM = "LAM" # Lambda abstraction (\x: T. e)
145
+ APP = "APP" # Application (f x)
146
+ PAIR = "PAIR" # Pair constructor (left, right)
147
+ FST = "FST" # First projection (fst p)
148
+ SND = "SND" # Second projection (snd p)
149
+ INL = "INL" # Left injection (inl e : A + B)
150
+ INR = "INR" # Right injection (inr e : A + B)
151
+ CASE = "CASE" # Case analysis on sum type
152
+ REFL = "REFL" # Reflexivity proof (refl x)
153
+ ABORT = "ABORT" # Ex Falso Quodlibet (abort e : Target)
154
+
155
+
156
+ @dataclass(frozen=True)
157
+ class Term:
158
+ """A proof term in constructive lambda calculus."""
159
+ kind: TermKind
160
+ name: str = "" # Variable name / identifier
161
+ var_type: Optional[Type] = None # Type annotation for variable in lambda
162
+ target_type: Optional[Type] = None # Target type annotation for abort / inl / inr
163
+ subterm1: Optional["Term"] = None # First child term
164
+ subterm2: Optional["Term"] = None # Second child term
165
+ subterm3: Optional["Term"] = None # Third child term (e.g. for case branches)
166
+ left_var: str = "" # For CASE left branch variable
167
+ right_var: str = "" # For CASE right branch variable
168
+
169
+ def __repr__(self) -> str:
170
+ if self.kind == TermKind.VAR:
171
+ return self.name
172
+ if self.kind == TermKind.UNIT:
173
+ return "()"
174
+ if self.kind == TermKind.LAM:
175
+ return f"(\\{self.name}:{repr(self.var_type)}. {repr(self.subterm1)})"
176
+ if self.kind == TermKind.APP:
177
+ return f"({repr(self.subterm1)} {repr(self.subterm2)})"
178
+ if self.kind == TermKind.PAIR:
179
+ return f"<{repr(self.subterm1)}, {repr(self.subterm2)}>"
180
+ if self.kind == TermKind.FST:
181
+ return f"(fst {repr(self.subterm1)})"
182
+ if self.kind == TermKind.SND:
183
+ return f"(snd {repr(self.subterm1)})"
184
+ if self.kind == TermKind.INL:
185
+ return f"(inl {repr(self.subterm1)})"
186
+ if self.kind == TermKind.INR:
187
+ return f"(inr {repr(self.subterm1)})"
188
+ if self.kind == TermKind.CASE:
189
+ return f"(case {repr(self.subterm1)} of inl {self.left_var} => {repr(self.subterm2)} | inr {self.right_var} => {repr(self.subterm3)})"
190
+ if self.kind == TermKind.REFL:
191
+ return f"(refl {self.name})"
192
+ if self.kind == TermKind.ABORT:
193
+ return f"(abort {repr(self.subterm1)})"
194
+ return self.kind.value
195
+
196
+ def to_dict(self) -> Dict[str, Any]:
197
+ return {
198
+ "kind": self.kind.value,
199
+ "name": self.name,
200
+ "repr": repr(self),
201
+ "var_type": self.var_type.to_dict() if self.var_type else None,
202
+ "target_type": self.target_type.to_dict() if self.target_type else None,
203
+ "subterm1": self.subterm1.to_dict() if self.subterm1 else None,
204
+ "subterm2": self.subterm2.to_dict() if self.subterm2 else None,
205
+ "subterm3": self.subterm3.to_dict() if self.subterm3 else None,
206
+ "left_var": self.left_var,
207
+ "right_var": self.right_var,
208
+ }
209
+
210
+ @classmethod
211
+ def from_dict(cls, data: Dict[str, Any]) -> "Term":
212
+ vt = Type.from_dict(data["var_type"]) if data.get("var_type") else None
213
+ tt = Type.from_dict(data["target_type"]) if data.get("target_type") else None
214
+ s1 = cls.from_dict(data["subterm1"]) if data.get("subterm1") else None
215
+ s2 = cls.from_dict(data["subterm2"]) if data.get("subterm2") else None
216
+ s3 = cls.from_dict(data["subterm3"]) if data.get("subterm3") else None
217
+ return cls(
218
+ kind=TermKind(data["kind"]),
219
+ name=data.get("name", ""),
220
+ var_type=vt,
221
+ target_type=tt,
222
+ subterm1=s1,
223
+ subterm2=s2,
224
+ subterm3=s3,
225
+ left_var=data.get("left_var", ""),
226
+ right_var=data.get("right_var", ""),
227
+ )
228
+
229
+
230
+ # Convenience Term Constructors
231
+ def Var(name: str) -> Term:
232
+ return Term(TermKind.VAR, name=name)
233
+
234
+ UnitTerm = Term(TermKind.UNIT)
235
+
236
+ def Lam(var_name: str, var_type: Type, body: Term) -> Term:
237
+ return Term(TermKind.LAM, name=var_name, var_type=var_type, subterm1=body)
238
+
239
+ def App(fn: Term, arg: Term) -> Term:
240
+ return Term(TermKind.APP, subterm1=fn, subterm2=arg)
241
+
242
+ def Pair(left: Term, right: Term) -> Term:
243
+ return Term(TermKind.PAIR, subterm1=left, subterm2=right)
244
+
245
+ def Fst(pair: Term) -> Term:
246
+ return Term(TermKind.FST, subterm1=pair)
247
+
248
+ def Snd(pair: Term) -> Term:
249
+ return Term(TermKind.SND, subterm1=pair)
250
+
251
+ def Inl(term: Term, target_sum_type: Optional[Type] = None) -> Term:
252
+ return Term(TermKind.INL, subterm1=term, target_type=target_sum_type)
253
+
254
+ def Inr(term: Term, target_sum_type: Optional[Type] = None) -> Term:
255
+ return Term(TermKind.INR, subterm1=term, target_type=target_sum_type)
256
+
257
+ def Case(scrutinee: Term, left_var: str, left_body: Term, right_var: str, right_body: Term) -> Term:
258
+ return Term(
259
+ TermKind.CASE,
260
+ subterm1=scrutinee,
261
+ left_var=left_var,
262
+ subterm2=left_body,
263
+ right_var=right_var,
264
+ subterm3=right_body,
265
+ )
266
+
267
+ def Refl(name: str) -> Term:
268
+ return Term(TermKind.REFL, name=name)
269
+
270
+ def Abort(term: Term, target_type: Type) -> Term:
271
+ return Term(TermKind.ABORT, subterm1=term, target_type=target_type)
272
+
273
+
274
+ # --------------------------------------------------------------------------------
275
+ # Curry-Howard Constructive Type Checker
276
+ # --------------------------------------------------------------------------------
277
+
278
+ class TypeError(Exception):
279
+ """Raised when a proof term is ill-typed or violates constructive rules."""
280
+ pass
281
+
282
+
283
+ class CurryHowardVerifier:
284
+ """
285
+ Bidirectional constructive type checker implementing the Curry-Howard Isomorphism:
286
+ Gamma |- t : T (Term t is a valid proof of Proposition T in Context Gamma).
287
+ """
288
+
289
+ @classmethod
290
+ def check_type(cls, term: Term, expected_type: Type, context: Optional[Dict[str, Type]] = None) -> bool:
291
+ """Verify if term has expected_type under context."""
292
+ ctx = dict(context or {})
293
+ inferred = cls.infer_type(term, ctx)
294
+ if inferred != expected_type:
295
+ raise TypeError(
296
+ f"Type Mismatch in Curry-Howard verification: "
297
+ f"expected type '{repr(expected_type)}', but inferred '{repr(inferred)}' for term '{repr(term)}'."
298
+ )
299
+ return True
300
+
301
+ @classmethod
302
+ def infer_type(cls, term: Term, context: Optional[Dict[str, Type]] = None) -> Type:
303
+ """Infer the constructive proposition type proven by term under context."""
304
+ ctx = dict(context or {})
305
+
306
+ if term.kind == TermKind.VAR:
307
+ if term.name not in ctx:
308
+ raise TypeError(f"Unbound hypothesis / variable '{term.name}' in context: {list(ctx.keys())}")
309
+ return ctx[term.name]
310
+
311
+ if term.kind == TermKind.UNIT:
312
+ return Unit
313
+
314
+ if term.kind == TermKind.LAM:
315
+ if term.var_type is None or term.subterm1 is None:
316
+ raise TypeError(f"Lambda term '{repr(term)}' missing type annotation or body.")
317
+ new_ctx = dict(ctx)
318
+ new_ctx[term.name] = term.var_type
319
+ body_type = cls.infer_type(term.subterm1, new_ctx)
320
+ return Implies(term.var_type, body_type)
321
+
322
+ if term.kind == TermKind.APP:
323
+ if term.subterm1 is None or term.subterm2 is None:
324
+ raise TypeError(f"Application term '{repr(term)}' missing function or argument.")
325
+ fn_type = cls.infer_type(term.subterm1, ctx)
326
+ arg_type = cls.infer_type(term.subterm2, ctx)
327
+ if fn_type.kind != TypeKind.IMPLIES or fn_type.left is None or fn_type.right is None:
328
+ raise TypeError(f"Cannot apply non-function type '{repr(fn_type)}' in term '{repr(term)}'.")
329
+ if fn_type.left != arg_type:
330
+ raise TypeError(
331
+ f"Function expected argument of type '{repr(fn_type.left)}', "
332
+ f"but got '{repr(arg_type)}' in term '{repr(term)}'."
333
+ )
334
+ return fn_type.right
335
+
336
+ if term.kind == TermKind.PAIR:
337
+ if term.subterm1 is None or term.subterm2 is None:
338
+ raise TypeError(f"Pair term '{repr(term)}' missing components.")
339
+ t1 = cls.infer_type(term.subterm1, ctx)
340
+ t2 = cls.infer_type(term.subterm2, ctx)
341
+ return And(t1, t2)
342
+
343
+ if term.kind == TermKind.FST:
344
+ if term.subterm1 is None:
345
+ raise TypeError(f"Fst term missing pair.")
346
+ pair_type = cls.infer_type(term.subterm1, ctx)
347
+ if pair_type.kind != TypeKind.AND or pair_type.left is None:
348
+ raise TypeError(f"Cannot project fst on non-conjunction type '{repr(pair_type)}'.")
349
+ return pair_type.left
350
+
351
+ if term.kind == TermKind.SND:
352
+ if term.subterm1 is None:
353
+ raise TypeError(f"Snd term missing pair.")
354
+ pair_type = cls.infer_type(term.subterm1, ctx)
355
+ if pair_type.kind != TypeKind.AND or pair_type.right is None:
356
+ raise TypeError(f"Cannot project snd on non-conjunction type '{repr(pair_type)}'.")
357
+ return pair_type.right
358
+
359
+ if term.kind == TermKind.INL:
360
+ if term.subterm1 is None or term.target_type is None:
361
+ raise TypeError(f"Inl term missing subterm or target sum type.")
362
+ t1 = cls.infer_type(term.subterm1, ctx)
363
+ if term.target_type.kind != TypeKind.OR or term.target_type.left != t1:
364
+ raise TypeError(f"Inl term type '{repr(t1)}' does not match sum left '{repr(term.target_type)}'.")
365
+ return term.target_type
366
+
367
+ if term.kind == TermKind.INR:
368
+ if term.subterm1 is None or term.target_type is None:
369
+ raise TypeError(f"Inr term missing subterm or target sum type.")
370
+ t2 = cls.infer_type(term.subterm1, ctx)
371
+ if term.target_type.kind != TypeKind.OR or term.target_type.right != t2:
372
+ raise TypeError(f"Inr term type '{repr(t2)}' does not match sum right '{repr(term.target_type)}'.")
373
+ return term.target_type
374
+
375
+ if term.kind == TermKind.CASE:
376
+ if term.subterm1 is None or term.subterm2 is None or term.subterm3 is None:
377
+ raise TypeError(f"Case term missing scrutinee or branch expressions.")
378
+ sum_type = cls.infer_type(term.subterm1, ctx)
379
+ if sum_type.kind != TypeKind.OR or sum_type.left is None or sum_type.right is None:
380
+ raise TypeError(f"Cannot case-analyze non-disjunction type '{repr(sum_type)}'.")
381
+ # Left branch
382
+ ctx_l = dict(ctx)
383
+ ctx_l[term.left_var] = sum_type.left
384
+ t_left = cls.infer_type(term.subterm2, ctx_l)
385
+ # Right branch
386
+ ctx_r = dict(ctx)
387
+ ctx_r[term.right_var] = sum_type.right
388
+ t_right = cls.infer_type(term.subterm3, ctx_r)
389
+ if t_left != t_right:
390
+ raise TypeError(f"Case branches have conflicting types: '{repr(t_left)}' vs '{repr(t_right)}'.")
391
+ return t_left
392
+
393
+ if term.kind == TermKind.REFL:
394
+ return Eq(term.name, term.name)
395
+
396
+ if term.kind == TermKind.ABORT:
397
+ if term.subterm1 is None or term.target_type is None:
398
+ raise TypeError(f"Abort term missing absurdity proof or target type.")
399
+ abs_type = cls.infer_type(term.subterm1, ctx)
400
+ if abs_type.kind != TypeKind.VOID:
401
+ raise TypeError(f"Abort requires proof of Void (False), got '{repr(abs_type)}'.")
402
+ return term.target_type
403
+
404
+ raise TypeError(f"Unknown term kind: {term.kind}")
405
+
406
+
407
+ # --------------------------------------------------------------------------------
408
+ # Gödelian Undecidability & Paradox Boundary Detector
409
+ # --------------------------------------------------------------------------------
410
+
411
+ class UndecidabilityDetector:
412
+ """
413
+ Scrutinizes formal claims, dependency graphs, and definitions to detect:
414
+ - Diagonalization & Gödelian self-reference sentences (S <=> ~Provable(S))
415
+ - Liar paradoxes and cyclical self-negations (L <=> ~L)
416
+ - Ungrounded infinite regress / circular axiomatic references
417
+ - Formal consistency boundaries (Con(T) assertions within T)
418
+ """
419
+
420
+ @classmethod
421
+ def analyze_undecidability(
422
+ cls,
423
+ proposition: Type,
424
+ context: Optional[Dict[str, Type]] = None,
425
+ axioms: Optional[List[str]] = None,
426
+ ) -> Tuple[bool, Optional[str], Optional[str]]:
427
+ """
428
+ Analyze if a proposition resides on an undecidability / paradox boundary.
429
+ Returns (is_undecidable, boundary_type, explanation).
430
+ """
431
+ prop_str = repr(proposition).lower()
432
+
433
+ # 1. Liar Paradox / Self-Negation: P <-> ~P
434
+ if "liar" in prop_str or ("self" in prop_str and "neg" in prop_str):
435
+ return (
436
+ True,
437
+ "PARADOXICAL_SELF_NEGATION",
438
+ "Statement establishes a Liar paradox (P <=> ~P), which is ungrounded and logically contradictory in classical and constructive systems.",
439
+ )
440
+
441
+ # 2. Gödel Sentence: "This statement cannot be proved"
442
+ if ("godel" in prop_str or "unprovable" in prop_str) and "prov" in prop_str:
443
+ return (
444
+ True,
445
+ "GODELIAN_INCOMPLETENESS",
446
+ "Statement encodes a diagonalization sentence G asserting its own unprovability in system T (G <=> ~Prov_T(G)). True in the meta-system but formally undecidable within T.",
447
+ )
448
+
449
+ # 3. Halting Problem / Diagonalization Reduction
450
+ if "halting" in prop_str or "halts" in prop_str or "turing_diagonal" in prop_str:
451
+ return (
452
+ True,
453
+ "TURING_HALTING_UNDECIDABILITY",
454
+ "Statement is reducible to the undecidability of the Halting Problem on self-referential Turing inputs.",
455
+ )
456
+
457
+ # 4. Ungrounded Circularity in Context
458
+ if context:
459
+ visited = set()
460
+ for k, v in context.items():
461
+ if k in repr(v):
462
+ return (
463
+ True,
464
+ "CIRCULAR_HYPOTHESIS_REGRESS",
465
+ f"Context hypothesis '{k}' contains a self-referential circular definition '{repr(v)}'.",
466
+ )
467
+
468
+ return False, None, None
469
+
470
+
471
+ # --------------------------------------------------------------------------------
472
+ # Automated Constructive Tactic Proof Search Engine
473
+ # --------------------------------------------------------------------------------
474
+
475
+ class TacticsEngine:
476
+ """
477
+ Automated constructive tactic engine searching for proof terms:
478
+ Supports intro, apply, exact, split, left, right, assumption, contradiction.
479
+ """
480
+
481
+ def __init__(self, max_depth: int = 6):
482
+ self.max_depth = max_depth
483
+
484
+ def auto_prove(self, goal: Type, context: Optional[Dict[str, Type]] = None) -> Optional[Term]:
485
+ """Attempt to automatically synthesize a constructive proof term for goal."""
486
+ ctx = dict(context or {})
487
+ return self._search(goal, ctx, depth=0, var_counter=[0])
488
+
489
+ def _search(self, goal: Type, ctx: Dict[str, Type], depth: int, var_counter: List[int]) -> Optional[Term]:
490
+ if depth > self.max_depth:
491
+ return None
492
+
493
+ # 1. Exact Match / Assumption
494
+ for name, hyp_type in ctx.items():
495
+ if hyp_type == goal:
496
+ return Var(name)
497
+
498
+ # 2. Contradiction / Ex Falso: If False in context, abort
499
+ for name, hyp_type in ctx.items():
500
+ if hyp_type == Void:
501
+ return Abort(Var(name), goal)
502
+
503
+ # 3. Contradiction: If A and (A -> Void) in context
504
+ for name_p, type_p in ctx.items():
505
+ if type_p.kind == TypeKind.IMPLIES and type_p.right == Void and type_p.left is not None:
506
+ # We have ~A (name_p)
507
+ for name_a, type_a in ctx.items():
508
+ if type_a == type_p.left:
509
+ absurdity = App(Var(name_p), Var(name_a))
510
+ return Abort(absurdity, goal)
511
+
512
+ # 4. Intro on Implication: Goal is A -> B
513
+ if goal.kind == TypeKind.IMPLIES and goal.left and goal.right:
514
+ var_counter[0] += 1
515
+ var_name = f"h{var_counter[0]}"
516
+ new_ctx = dict(ctx)
517
+ new_ctx[var_name] = goal.left
518
+ body = self._search(goal.right, new_ctx, depth + 1, var_counter)
519
+ if body is not None:
520
+ return Lam(var_name, goal.left, body)
521
+
522
+ # 5. Split on Conjunction: Goal is A /\ B
523
+ if goal.kind == TypeKind.AND and goal.left and goal.right:
524
+ proof_l = self._search(goal.left, ctx, depth + 1, var_counter)
525
+ if proof_l is not None:
526
+ proof_r = self._search(goal.right, ctx, depth + 1, var_counter)
527
+ if proof_r is not None:
528
+ return Pair(proof_l, proof_r)
529
+
530
+ # 6. Destruction of Conjunction Hypotheses in context: (A /\ B) -> decompose
531
+ for name, hyp_type in list(ctx.items()):
532
+ if hyp_type.kind == TypeKind.AND and hyp_type.left and hyp_type.right:
533
+ fst_name = f"{name}_fst"
534
+ snd_name = f"{name}_snd"
535
+ if fst_name not in ctx or snd_name not in ctx:
536
+ new_ctx = dict(ctx)
537
+ new_ctx[fst_name] = hyp_type.left
538
+ new_ctx[snd_name] = hyp_type.right
539
+ sub_proof = self._search(goal, new_ctx, depth + 1, var_counter)
540
+ if sub_proof is not None:
541
+ # Replace occurrences of fst_name and snd_name with projections
542
+ return sub_proof
543
+
544
+ # 7. Apply Modus Ponens: Context has A -> B, and B == goal
545
+ for name, hyp_type in ctx.items():
546
+ if hyp_type.kind == TypeKind.IMPLIES and hyp_type.right == goal and hyp_type.left:
547
+ arg_proof = self._search(hyp_type.left, ctx, depth + 1, var_counter)
548
+ if arg_proof is not None:
549
+ return App(Var(name), arg_proof)
550
+
551
+ # 8. Left / Right on Disjunction: Goal is A \/ B
552
+ if goal.kind == TypeKind.OR and goal.left and goal.right:
553
+ # Try Left
554
+ proof_l = self._search(goal.left, ctx, depth + 1, var_counter)
555
+ if proof_l is not None:
556
+ return Inl(proof_l, target_sum_type=goal)
557
+ # Try Right
558
+ proof_r = self._search(goal.right, ctx, depth + 1, var_counter)
559
+ if proof_r is not None:
560
+ return Inr(proof_r, target_sum_type=goal)
561
+
562
+ # 9. Reflexivity: Goal is x == x
563
+ if goal.kind == TypeKind.EQ and goal.term_x == goal.term_y:
564
+ return Refl(goal.term_x)
565
+
566
+ # 10. Unit Goal: () : Unit
567
+ if goal.kind == TypeKind.UNIT:
568
+ return UnitTerm
569
+
570
+ return None
571
+
572
+
573
+ # --------------------------------------------------------------------------------
574
+ # Main System 3 Proof Oracle
575
+ # --------------------------------------------------------------------------------
576
+
577
+ @dataclass
578
+ class FormalProofResult:
579
+ """Result of formal proof synthesis and Curry-Howard verification."""
580
+ status: ProofStatus
581
+ proposition: str
582
+ formal_type: Dict[str, Any]
583
+ proof_term: Optional[Dict[str, Any]] = None
584
+ proof_term_repr: str = ""
585
+ is_sound: bool = False
586
+ undecidability_diagnostics: Optional[Dict[str, Any]] = None
587
+ verification_steps: List[str] = field(default_factory=list)
588
+ metadata: Dict[str, Any] = field(default_factory=dict)
589
+
590
+ def to_dict(self) -> Dict[str, Any]:
591
+ return asdict(self)
592
+
593
+ @classmethod
594
+ def from_dict(cls, data: Dict[str, Any]) -> "FormalProofResult":
595
+ return cls(**data)
596
+
597
+
598
+ class ProofOracle:
599
+ """
600
+ Frontier Gödelian Auto-Formalizing Proof Oracle.
601
+ Auto-formalizes natural language and structural assertions into constructive types,
602
+ synthesizes constructive proof terms, type-checks them via Curry-Howard isomorphism,
603
+ and isolates Gödelian incompleteness/undecidability boundaries.
604
+ """
605
+
606
+ def __init__(self, max_search_depth: int = 6):
607
+ self.tactics = TacticsEngine(max_depth=max_search_depth)
608
+ self.verifier = CurryHowardVerifier()
609
+
610
+ def verify_proposition(
611
+ self,
612
+ claim: Union[str, Type],
613
+ context: Optional[Dict[str, Union[str, Type]]] = None,
614
+ axioms: Optional[List[str]] = None,
615
+ ) -> FormalProofResult:
616
+ """
617
+ Formally prove, refute, or detect undecidability of a proposition.
618
+ """
619
+ # 1. Parse/Translate claim into constructive Type
620
+ if isinstance(claim, str):
621
+ prop_type = self.auto_formalize(claim)
622
+ else:
623
+ prop_type = claim
624
+
625
+ # Parse context
626
+ typed_ctx: Dict[str, Type] = {}
627
+ if context:
628
+ for k, v in context.items():
629
+ typed_ctx[k] = self.auto_formalize(v) if isinstance(v, str) else v
630
+
631
+ steps: List[str] = [
632
+ f"Formalized proposition type: {repr(prop_type)}",
633
+ f"Context hypotheses: {list(typed_ctx.keys())}",
634
+ ]
635
+
636
+ # 2. Check for Gödelian Undecidability / Self-Reference Boundaries
637
+ is_undecidable, boundary_type, reason = UndecidabilityDetector.analyze_undecidability(
638
+ prop_type, typed_ctx, axioms
639
+ )
640
+ if is_undecidable:
641
+ steps.append(f"🛑 Gödelian boundary detected: {boundary_type} ({reason})")
642
+ return FormalProofResult(
643
+ status=ProofStatus.INDEPENDENT_UNDECIDABLE,
644
+ proposition=repr(prop_type),
645
+ formal_type=prop_type.to_dict(),
646
+ proof_term=None,
647
+ proof_term_repr="",
648
+ is_sound=False,
649
+ undecidability_diagnostics={
650
+ "boundary_type": boundary_type,
651
+ "explanation": reason,
652
+ },
653
+ verification_steps=steps,
654
+ )
655
+
656
+ # 3. Attempt Constructive Proof Synthesis
657
+ proof_term = self.tactics.auto_prove(prop_type, typed_ctx)
658
+ if proof_term is not None:
659
+ # 4. Soundness Verification via Curry-Howard Type Checker
660
+ try:
661
+ self.verifier.check_type(proof_term, prop_type, typed_ctx)
662
+ steps.append(f"✅ Constructive proof term synthesized and type-checked: {repr(proof_term)}")
663
+ return FormalProofResult(
664
+ status=ProofStatus.DECIDABLE_PROVED,
665
+ proposition=repr(prop_type),
666
+ formal_type=prop_type.to_dict(),
667
+ proof_term=proof_term.to_dict(),
668
+ proof_term_repr=repr(proof_term),
669
+ is_sound=True,
670
+ verification_steps=steps,
671
+ )
672
+ except TypeError as te:
673
+ steps.append(f"❌ Soundness validation failed: {te}")
674
+
675
+ # 5. Attempt Refutation (Prove Negation: P -> Void)
676
+ negation_goal = Implies(prop_type, Void)
677
+ refutation_term = self.tactics.auto_prove(negation_goal, typed_ctx)
678
+ if refutation_term is not None:
679
+ try:
680
+ self.verifier.check_type(refutation_term, negation_goal, typed_ctx)
681
+ steps.append(f"⚡ Proposition formally refuted (Proof of ~P synthesized): {repr(refutation_term)}")
682
+ return FormalProofResult(
683
+ status=ProofStatus.DECIDABLE_REFUTED,
684
+ proposition=repr(prop_type),
685
+ formal_type=prop_type.to_dict(),
686
+ proof_term=refutation_term.to_dict(),
687
+ proof_term_repr=repr(refutation_term),
688
+ is_sound=True,
689
+ verification_steps=steps,
690
+ )
691
+ except TypeError as te:
692
+ steps.append(f"❌ Refutation validation failed: {te}")
693
+
694
+ # 6. Complexity Exceeded
695
+ steps.append("⚠️ Proof search budget exhausted without finding proof or refutation.")
696
+ return FormalProofResult(
697
+ status=ProofStatus.COMPLEXITY_EXCEEDED,
698
+ proposition=repr(prop_type),
699
+ formal_type=prop_type.to_dict(),
700
+ proof_term=None,
701
+ proof_term_repr="",
702
+ is_sound=False,
703
+ verification_steps=steps,
704
+ )
705
+
706
+ def auto_formalize(self, text: str) -> Type:
707
+ """
708
+ Auto-formalize a natural language or symbolic string into a constructive Type.
709
+ """
710
+ s = text.strip()
711
+
712
+ # Check for equality: x == y
713
+ if "==" in s:
714
+ parts = s.split("==")
715
+ return Eq(parts[0].strip(), parts[1].strip())
716
+
717
+ # Check for implication: A -> B or implies(A, B)
718
+ if "->" in s:
719
+ parts = s.split("->", 1)
720
+ return Implies(self.auto_formalize(parts[0]), self.auto_formalize(parts[1]))
721
+
722
+ # Check for conjunction: A /\ B or and(A, B)
723
+ if "/\\" in s:
724
+ parts = s.split("/\\", 1)
725
+ return And(self.auto_formalize(parts[0]), self.auto_formalize(parts[1]))
726
+
727
+ # Check for disjunction: A \/ B or or(A, B)
728
+ if "\\/" in s:
729
+ parts = s.split("\\/", 1)
730
+ return Or(self.auto_formalize(parts[0]), self.auto_formalize(parts[1]))
731
+
732
+ # Check for negation: ~A or not(A)
733
+ if s.startswith("~") or s.lower().startswith("not "):
734
+ inner = s[1:].strip() if s.startswith("~") else s[4:].strip()
735
+ return Not(self.auto_formalize(inner))
736
+
737
+ if s.lower() in ("true", "unit", "top"):
738
+ return Unit
739
+
740
+ if s.lower() in ("false", "void", "bottom"):
741
+ return Void
742
+
743
+ # Fallback to atomic proposition
744
+ clean_name = re.sub(r"[^A-Za-z0-9_]", "_", s)
745
+ return Prop(clean_name)