Skip to main content

oxilean_std/complexity/
functions.rs

1//! Auto-generated module
2//!
3//! πŸ€– Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
6
7use super::types::{
8    CircuitEvaluator, CommunicationMatrixAnalyzer, DpllSolver, GateKind,
9    ParameterizedAlgorithmChecker, ResolutionProverSmall, SensitivityChecker, SudokuSolver,
10    TwoSatSolver,
11};
12
13pub fn app(f: Expr, a: Expr) -> Expr {
14    Expr::App(Box::new(f), Box::new(a))
15}
16pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
17    app(app(f, a), b)
18}
19pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
20    app(app2(f, a, b), c)
21}
22pub fn cst(s: &str) -> Expr {
23    Expr::Const(Name::str(s), vec![])
24}
25pub fn prop() -> Expr {
26    Expr::Sort(Level::zero())
27}
28pub fn type0() -> Expr {
29    Expr::Sort(Level::succ(Level::zero()))
30}
31pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
32    Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
33}
34pub fn arrow(a: Expr, b: Expr) -> Expr {
35    pi(BinderInfo::Default, "_", a, b)
36}
37#[allow(dead_code)]
38pub fn impl_pi(name: &str, dom: Expr, body: Expr) -> Expr {
39    pi(BinderInfo::Implicit, name, dom, body)
40}
41pub fn bvar(n: u32) -> Expr {
42    Expr::BVar(n)
43}
44pub fn nat_ty() -> Expr {
45    cst("Nat")
46}
47/// Language : Type β€” a set of strings (decidable predicate on strings)
48pub fn language_ty() -> Expr {
49    arrow(cst("String"), prop())
50}
51/// TimeComplexity : (Nat β†’ Nat) β†’ Type
52/// Represents a function f : β„• β†’ β„• as a time bound
53pub fn time_complexity_ty() -> Expr {
54    type0()
55}
56/// TuringMachine : Type β€” a deterministic Turing machine
57pub fn turing_machine_ty() -> Expr {
58    type0()
59}
60/// NTM : Type β€” a nondeterministic Turing machine
61pub fn ntm_ty() -> Expr {
62    type0()
63}
64/// OracleMachine : Language β†’ Type β€” a TM with oracle access to a language
65pub fn oracle_machine_ty() -> Expr {
66    arrow(language_ty(), type0())
67}
68/// DTIME (f : Nat β†’ Nat) : Language β†’ Prop
69/// L ∈ DTIME(f) if some TM decides L in O(f(n)) steps
70pub fn dtime_ty() -> Expr {
71    arrow(arrow(nat_ty(), nat_ty()), arrow(language_ty(), prop()))
72}
73/// NTIME (f : Nat β†’ Nat) : Language β†’ Prop
74/// L ∈ NTIME(f) if some NTM decides L in O(f(n)) steps
75pub fn ntime_ty() -> Expr {
76    arrow(arrow(nat_ty(), nat_ty()), arrow(language_ty(), prop()))
77}
78/// DSPACE (f : Nat β†’ Nat) : Language β†’ Prop
79/// L ∈ DSPACE(f) if some TM decides L using O(f(n)) space
80pub fn dspace_ty() -> Expr {
81    arrow(arrow(nat_ty(), nat_ty()), arrow(language_ty(), prop()))
82}
83/// NSPACE (f : Nat β†’ Nat) : Language β†’ Prop
84pub fn nspace_ty() -> Expr {
85    arrow(arrow(nat_ty(), nat_ty()), arrow(language_ty(), prop()))
86}
87/// P : Language β†’ Prop β€” polynomial time decidable
88pub fn class_p_ty() -> Expr {
89    arrow(language_ty(), prop())
90}
91/// NP : Language β†’ Prop β€” nondeterministic polynomial time
92pub fn class_np_ty() -> Expr {
93    arrow(language_ty(), prop())
94}
95/// coNP : Language β†’ Prop β€” complement of NP
96pub fn class_conp_ty() -> Expr {
97    arrow(language_ty(), prop())
98}
99/// PSPACE : Language β†’ Prop β€” polynomial space
100pub fn class_pspace_ty() -> Expr {
101    arrow(language_ty(), prop())
102}
103/// NPSPACE : Language β†’ Prop β€” nondeterministic polynomial space
104pub fn class_npspace_ty() -> Expr {
105    arrow(language_ty(), prop())
106}
107/// EXP : Language β†’ Prop β€” exponential time 2^(n^c)
108pub fn class_exp_ty() -> Expr {
109    arrow(language_ty(), prop())
110}
111/// NEXP : Language β†’ Prop β€” nondeterministic exponential time
112pub fn class_nexp_ty() -> Expr {
113    arrow(language_ty(), prop())
114}
115/// L : Language β†’ Prop β€” logarithmic space
116pub fn class_l_ty() -> Expr {
117    arrow(language_ty(), prop())
118}
119/// NL : Language β†’ Prop β€” nondeterministic logarithmic space
120pub fn class_nl_ty() -> Expr {
121    arrow(language_ty(), prop())
122}
123/// PH : Language β†’ Prop β€” polynomial hierarchy
124pub fn class_ph_ty() -> Expr {
125    arrow(language_ty(), prop())
126}
127/// SigmaP (k : Nat) : Language β†’ Prop β€” k-th level of polynomial hierarchy
128pub fn sigma_p_ty() -> Expr {
129    arrow(nat_ty(), arrow(language_ty(), prop()))
130}
131/// PiP (k : Nat) : Language β†’ Prop
132pub fn pi_p_ty() -> Expr {
133    arrow(nat_ty(), arrow(language_ty(), prop()))
134}
135/// DeltaP (k : Nat) : Language β†’ Prop
136pub fn delta_p_ty() -> Expr {
137    arrow(nat_ty(), arrow(language_ty(), prop()))
138}
139/// SharpP : Language β†’ Prop β€” counting problems
140pub fn class_sharp_p_ty() -> Expr {
141    arrow(language_ty(), prop())
142}
143/// RP : Language β†’ Prop β€” randomized polynomial time
144pub fn class_rp_ty() -> Expr {
145    arrow(language_ty(), prop())
146}
147/// coRP : Language β†’ Prop
148pub fn class_corp_ty() -> Expr {
149    arrow(language_ty(), prop())
150}
151/// BPP : Language β†’ Prop β€” bounded-error probabilistic polynomial time
152pub fn class_bpp_ty() -> Expr {
153    arrow(language_ty(), prop())
154}
155/// ZPP : Language β†’ Prop β€” zero-error probabilistic polynomial time
156pub fn class_zpp_ty() -> Expr {
157    arrow(language_ty(), prop())
158}
159/// PP : Language β†’ Prop β€” probabilistic polynomial time (unbounded error)
160pub fn class_pp_ty() -> Expr {
161    arrow(language_ty(), prop())
162}
163/// IP : Language β†’ Prop β€” interactive proof systems
164pub fn class_ip_ty() -> Expr {
165    arrow(language_ty(), prop())
166}
167/// PSpace: L ∈ PSPACE means L is decidable in polynomial space
168pub fn in_pspace_ty() -> Expr {
169    arrow(language_ty(), prop())
170}
171/// PolyManyOneReducible (A B : Language) : Prop
172/// A ≀_m^p B β€” polynomial-time many-one reduction from A to B
173pub fn poly_many_one_reducible_ty() -> Expr {
174    pi(
175        BinderInfo::Default,
176        "A",
177        language_ty(),
178        pi(BinderInfo::Default, "B", language_ty(), prop()),
179    )
180}
181/// PolyTuringReducible (A B : Language) : Prop
182/// A ≀_T^p B β€” polynomial-time Turing reduction (Cook reduction)
183pub fn poly_turing_reducible_ty() -> Expr {
184    pi(
185        BinderInfo::Default,
186        "A",
187        language_ty(),
188        pi(BinderInfo::Default, "B", language_ty(), prop()),
189    )
190}
191/// LogSpaceReducible (A B : Language) : Prop
192/// A ≀_m^L B β€” logspace many-one reduction
193pub fn logspace_reducible_ty() -> Expr {
194    pi(
195        BinderInfo::Default,
196        "A",
197        language_ty(),
198        pi(BinderInfo::Default, "B", language_ty(), prop()),
199    )
200}
201/// NPHard (L : Language) : Prop β€” L is NP-hard under poly-many-one reductions
202pub fn np_hard_ty() -> Expr {
203    arrow(language_ty(), prop())
204}
205/// NPComplete (L : Language) : Prop β€” L ∈ NP ∧ NP-hard
206pub fn np_complete_ty() -> Expr {
207    arrow(language_ty(), prop())
208}
209/// PSPACEComplete (L : Language) : Prop
210pub fn pspace_complete_ty() -> Expr {
211    arrow(language_ty(), prop())
212}
213/// ExpComplete (L : Language) : Prop
214pub fn exp_complete_ty() -> Expr {
215    arrow(language_ty(), prop())
216}
217/// P βŠ† NP: every language decidable in poly-time is in NP
218pub fn p_subset_np_ty() -> Expr {
219    pi(
220        BinderInfo::Default,
221        "L",
222        language_ty(),
223        arrow(app(cst("P"), bvar(0)), app(cst("NP"), bvar(1))),
224    )
225}
226/// NP βŠ† PSPACE
227pub fn np_subset_pspace_ty() -> Expr {
228    pi(
229        BinderInfo::Default,
230        "L",
231        language_ty(),
232        arrow(app(cst("NP"), bvar(0)), app(cst("PSPACE"), bvar(1))),
233    )
234}
235/// PSPACE βŠ† EXP
236pub fn pspace_subset_exp_ty() -> Expr {
237    pi(
238        BinderInfo::Default,
239        "L",
240        language_ty(),
241        arrow(app(cst("PSPACE"), bvar(0)), app(cst("EXP"), bvar(1))),
242    )
243}
244/// Savitch's theorem: NPSPACE = PSPACE
245pub fn savitch_theorem_ty() -> Expr {
246    pi(
247        BinderInfo::Default,
248        "L",
249        language_ty(),
250        app2(
251            cst("Iff"),
252            app(cst("NPSPACE"), bvar(0)),
253            app(cst("PSPACE"), bvar(1)),
254        ),
255    )
256}
257/// Immerman-SzelepcsΓ©nyi: NL = coNL
258pub fn nl_eq_conl_ty() -> Expr {
259    pi(
260        BinderInfo::Default,
261        "L",
262        language_ty(),
263        app2(
264            cst("Iff"),
265            app(cst("NL"), bvar(0)),
266            app(cst("coNL"), bvar(1)),
267        ),
268    )
269}
270/// Cook-Levin theorem: SAT is NP-complete
271pub fn cook_levin_theorem_ty() -> Expr {
272    app(cst("NPComplete"), cst("SAT"))
273}
274/// 3-SAT is NP-complete (reduction from SAT)
275pub fn three_sat_np_complete_ty() -> Expr {
276    app(cst("NPComplete"), cst("ThreeSAT"))
277}
278/// CLIQUE is NP-complete
279pub fn clique_np_complete_ty() -> Expr {
280    app(cst("NPComplete"), cst("CLIQUE"))
281}
282/// VERTEX-COVER is NP-complete
283pub fn vertex_cover_np_complete_ty() -> Expr {
284    app(cst("NPComplete"), cst("VertexCover"))
285}
286/// HAM-PATH is NP-complete (Hamiltonian path)
287pub fn ham_path_np_complete_ty() -> Expr {
288    app(cst("NPComplete"), cst("HamiltonianPath"))
289}
290/// 3-COLORING is NP-complete
291pub fn three_coloring_np_complete_ty() -> Expr {
292    app(cst("NPComplete"), cst("GraphThreeColoring"))
293}
294/// SUBSET-SUM is NP-complete
295pub fn subset_sum_np_complete_ty() -> Expr {
296    app(cst("NPComplete"), cst("SubsetSum"))
297}
298/// KNAPSACK is NP-complete
299pub fn knapsack_np_complete_ty() -> Expr {
300    app(cst("NPComplete"), cst("Knapsack"))
301}
302/// QBF (Quantified Boolean Formula) is PSPACE-complete
303pub fn qbf_pspace_complete_ty() -> Expr {
304    app(cst("PSPACEComplete"), cst("QBF"))
305}
306/// TQBF is PSPACE-complete (also known as QBF)
307pub fn tqbf_pspace_complete_ty() -> Expr {
308    app(cst("PSPACEComplete"), cst("TQBF"))
309}
310/// Time hierarchy theorem: DTIME(f) ⊊ DTIME(g) when g ≫ f
311/// βˆ€ f g, TimeConstructible g β†’ (βˆ€ n, f(n) * log(f(n)) < g(n)) β†’
312///   βˆƒ L, L ∈ DTIME(g) ∧ L βˆ‰ DTIME(f)
313pub fn time_hierarchy_theorem_ty() -> Expr {
314    pi(
315        BinderInfo::Default,
316        "f",
317        arrow(nat_ty(), nat_ty()),
318        pi(
319            BinderInfo::Default,
320            "g",
321            arrow(nat_ty(), nat_ty()),
322            arrow(
323                app(cst("TimeConstructible"), bvar(0)),
324                arrow(
325                    pi(
326                        BinderInfo::Default,
327                        "n",
328                        nat_ty(),
329                        app2(
330                            cst("Nat.lt"),
331                            app2(
332                                cst("Nat.mul"),
333                                app(bvar(3), bvar(0)),
334                                app2(
335                                    cst("Nat.add"),
336                                    app(cst("Nat.log2"), app(bvar(3), bvar(1))),
337                                    nat_lit(1),
338                                ),
339                            ),
340                            app(bvar(2), bvar(1)),
341                        ),
342                    ),
343                    app(
344                        cst("Exists"),
345                        pi(
346                            BinderInfo::Default,
347                            "L",
348                            language_ty(),
349                            app2(
350                                cst("And"),
351                                app2(cst("DTIME"), bvar(3), bvar(0)),
352                                app(cst("Not"), app2(cst("DTIME"), bvar(4), bvar(1))),
353                            ),
354                        ),
355                    ),
356                ),
357            ),
358        ),
359    )
360}
361/// Space hierarchy theorem: DSPACE(f) ⊊ DSPACE(g) when g ≫ f
362pub fn space_hierarchy_theorem_ty() -> Expr {
363    pi(
364        BinderInfo::Default,
365        "f",
366        arrow(nat_ty(), nat_ty()),
367        pi(
368            BinderInfo::Default,
369            "g",
370            arrow(nat_ty(), nat_ty()),
371            arrow(
372                app(cst("SpaceConstructible"), bvar(0)),
373                arrow(
374                    pi(
375                        BinderInfo::Default,
376                        "n",
377                        nat_ty(),
378                        app2(cst("Nat.lt"), app(bvar(3), bvar(0)), app(bvar(2), bvar(1))),
379                    ),
380                    app(
381                        cst("Exists"),
382                        pi(
383                            BinderInfo::Default,
384                            "L",
385                            language_ty(),
386                            app2(
387                                cst("And"),
388                                app2(cst("DSPACE"), bvar(3), bvar(0)),
389                                app(cst("Not"), app2(cst("DSPACE"), bvar(4), bvar(1))),
390                            ),
391                        ),
392                    ),
393                ),
394            ),
395        ),
396    )
397}
398/// Ladner's theorem: if P β‰  NP, there exist NP-intermediate problems
399pub fn ladner_theorem_ty() -> Expr {
400    arrow(
401        app(cst("Not"), app2(cst("Eq"), cst("ClassP"), cst("ClassNP"))),
402        app(
403            cst("Exists"),
404            pi(
405                BinderInfo::Default,
406                "L",
407                language_ty(),
408                app2(
409                    cst("And"),
410                    app2(
411                        cst("And"),
412                        app(cst("NP"), bvar(0)),
413                        app(cst("Not"), app(cst("P"), bvar(1))),
414                    ),
415                    app(cst("Not"), app(cst("NPComplete"), bvar(2))),
416                ),
417            ),
418        ),
419    )
420}
421/// Baker-Gill-Solovay: There exist oracles A, B such that P^A = NP^A and P^B β‰  NP^B
422pub fn bgs_theorem_ty() -> Expr {
423    app2(
424        cst("And"),
425        app(
426            cst("Exists"),
427            pi(
428                BinderInfo::Default,
429                "A",
430                language_ty(),
431                app2(
432                    cst("Eq"),
433                    app(cst("OracleP"), bvar(0)),
434                    app(cst("OracleNP"), bvar(1)),
435                ),
436            ),
437        ),
438        app(
439            cst("Exists"),
440            pi(
441                BinderInfo::Default,
442                "B",
443                language_ty(),
444                app(
445                    cst("Not"),
446                    app2(
447                        cst("Eq"),
448                        app(cst("OracleP"), bvar(0)),
449                        app(cst("OracleNP"), bvar(1)),
450                    ),
451                ),
452            ),
453        ),
454    )
455}
456/// IP = PSPACE (Shamir's theorem)
457pub fn shamir_theorem_ty() -> Expr {
458    pi(
459        BinderInfo::Default,
460        "L",
461        language_ty(),
462        app2(
463            cst("Iff"),
464            app(cst("IP"), bvar(0)),
465            app(cst("PSPACE"), bvar(1)),
466        ),
467    )
468}
469/// PCP theorem: NP = PCP(log n, 1)
470pub fn pcp_theorem_ty() -> Expr {
471    pi(
472        BinderInfo::Default,
473        "L",
474        language_ty(),
475        app2(
476            cst("Iff"),
477            app(cst("NP"), bvar(0)),
478            app(cst("PCP"), bvar(1)),
479        ),
480    )
481}
482pub fn nat_lit(n: u64) -> Expr {
483    Expr::Lit(oxilean_kernel::Literal::Nat(n))
484}
485/// BoolCircuit : Nat β†’ Type β€” a Boolean circuit of size n
486pub fn bool_circuit_ty() -> Expr {
487    arrow(nat_ty(), type0())
488}
489/// NC (k : Nat) : Language β†’ Prop β€” NC^k class (logspace-uniform NC^k circuits)
490pub fn nc_class_ty() -> Expr {
491    arrow(nat_ty(), arrow(language_ty(), prop()))
492}
493/// AC (k : Nat) : Language β†’ Prop β€” AC^k class (unbounded fan-in)
494pub fn ac_class_ty() -> Expr {
495    arrow(nat_ty(), arrow(language_ty(), prop()))
496}
497/// TC (k : Nat) : Language β†’ Prop β€” TC^k class (threshold gates)
498pub fn tc_class_ty() -> Expr {
499    arrow(nat_ty(), arrow(language_ty(), prop()))
500}
501/// NC^1 βŠ† L βŠ† NL βŠ† NC^2 βŠ† P
502pub fn nc_l_containment_ty() -> Expr {
503    pi(
504        BinderInfo::Default,
505        "L",
506        language_ty(),
507        pi(
508            BinderInfo::Default,
509            "k",
510            nat_ty(),
511            arrow(
512                app2(cst("NC"), nat_lit(1), bvar(1)),
513                app(cst("LogSpace"), bvar(2)),
514            ),
515        ),
516    )
517}
518/// AC^0 ⊊ NC^1 β€” parity is not in AC^0 (Furst-Saxe-Sipser/HΓ₯stad)
519pub fn ac0_strict_nc1_ty() -> Expr {
520    app(
521        cst("Not"),
522        app2(cst("Eq"), cst("ClassAC0"), cst("ClassNC1")),
523    )
524}
525/// IsApproximable (r : Rat) (L : Language) : Prop
526/// L has a polynomial-time r-approximation algorithm
527pub fn is_approximable_ty() -> Expr {
528    arrow(cst("Rat"), arrow(language_ty(), prop()))
529}
530/// MaxClique is not approximable within n^(1-Ξ΅) unless P=NP
531pub fn clique_inapprox_ty() -> Expr {
532    arrow(
533        app(cst("Not"), app2(cst("Eq"), cst("ClassP"), cst("ClassNP"))),
534        pi(
535            BinderInfo::Default,
536            "Ξ΅",
537            cst("Real"),
538            arrow(
539                app2(cst("Real.lt"), nat_lit(0).into_real(), bvar(0)),
540                app(cst("Not"), app(cst("Approximable"), cst("MaxClique"))),
541            ),
542        ),
543    )
544}
545/// FPT : Language β†’ Prop β€” fixed-parameter tractable
546pub fn fpt_ty() -> Expr {
547    arrow(language_ty(), prop())
548}
549/// W[1] : Language β†’ Prop β€” first level of W-hierarchy (parameterized complexity)
550pub fn w1_ty() -> Expr {
551    arrow(language_ty(), prop())
552}
553/// CLIQUE (parameterized by clique size) is W[1]-complete
554pub fn clique_w1_complete_ty() -> Expr {
555    app(cst("W1Complete"), cst("ParameterizedCLIQUE"))
556}
557/// Build the computational complexity theory environment.
558pub fn build_complexity_env(env: &mut Environment) -> Result<(), String> {
559    for (name, ty) in [
560        ("Language", language_ty()),
561        ("TuringMachine", turing_machine_ty()),
562        ("NTM", ntm_ty()),
563        ("DTIME", dtime_ty()),
564        ("NTIME", ntime_ty()),
565        ("DSPACE", dspace_ty()),
566        ("NSPACE", nspace_ty()),
567        ("P", class_p_ty()),
568        ("NP", class_np_ty()),
569        ("coNP", class_conp_ty()),
570        ("PSPACE", class_pspace_ty()),
571        ("NPSPACE", class_npspace_ty()),
572        ("EXP", class_exp_ty()),
573        ("NEXP", class_nexp_ty()),
574        ("L", class_l_ty()),
575        ("LogSpace", class_l_ty()),
576        ("coNL", class_nl_ty()),
577        ("NL", class_nl_ty()),
578        ("PH", class_ph_ty()),
579        ("SigmaP", sigma_p_ty()),
580        ("PiP", pi_p_ty()),
581        ("DeltaP", delta_p_ty()),
582        ("SharpP", class_sharp_p_ty()),
583        ("RP", class_rp_ty()),
584        ("coRP", class_corp_ty()),
585        ("BPP", class_bpp_ty()),
586        ("ZPP", class_zpp_ty()),
587        ("PP", class_pp_ty()),
588        ("IP", class_ip_ty()),
589        ("NC", nc_class_ty()),
590        ("AC", ac_class_ty()),
591        ("TC", tc_class_ty()),
592        ("FPT", fpt_ty()),
593        ("W1", w1_ty()),
594        ("PolyManyOneReducible", poly_many_one_reducible_ty()),
595        ("PolyTuringReducible", poly_turing_reducible_ty()),
596        ("LogSpaceReducible", logspace_reducible_ty()),
597        ("NPHard", np_hard_ty()),
598        ("NPComplete", np_complete_ty()),
599        ("PSPACEComplete", pspace_complete_ty()),
600        ("ExpComplete", exp_complete_ty()),
601        ("W1Complete", fpt_ty()),
602        ("IsApproximable", is_approximable_ty()),
603        ("Approximable", arrow(language_ty(), prop())),
604        (
605            "TimeConstructible",
606            arrow(arrow(nat_ty(), nat_ty()), prop()),
607        ),
608        (
609            "SpaceConstructible",
610            arrow(arrow(nat_ty(), nat_ty()), prop()),
611        ),
612        (
613            "OracleP",
614            arrow(language_ty(), arrow(language_ty(), prop())),
615        ),
616        (
617            "OracleNP",
618            arrow(language_ty(), arrow(language_ty(), prop())),
619        ),
620        ("PCP", class_np_ty()),
621        ("ClassP", type0()),
622        ("ClassNP", type0()),
623        ("ClassAC0", type0()),
624        ("ClassNC1", type0()),
625        ("SAT", arrow(cst("String"), prop())),
626        ("ThreeSAT", arrow(cst("String"), prop())),
627        ("CLIQUE", arrow(cst("String"), prop())),
628        ("VertexCover", arrow(cst("String"), prop())),
629        ("HamiltonianPath", arrow(cst("String"), prop())),
630        ("GraphThreeColoring", arrow(cst("String"), prop())),
631        ("SubsetSum", arrow(cst("String"), prop())),
632        ("Knapsack", arrow(cst("String"), prop())),
633        ("QBF", arrow(cst("String"), prop())),
634        ("TQBF", arrow(cst("String"), prop())),
635        ("MaxClique", arrow(cst("String"), prop())),
636        ("ParameterizedCLIQUE", arrow(cst("String"), prop())),
637    ] {
638        env.add(Declaration::Axiom {
639            name: Name::str(name),
640            univ_params: vec![],
641            ty,
642        })
643        .ok();
644    }
645    for (name, ty) in [
646        ("Complexity.p_subset_np", p_subset_np_ty()),
647        ("Complexity.np_subset_pspace", np_subset_pspace_ty()),
648        ("Complexity.pspace_subset_exp", pspace_subset_exp_ty()),
649        ("Complexity.savitch", savitch_theorem_ty()),
650        ("Complexity.nl_eq_conl", nl_eq_conl_ty()),
651        ("Complexity.cook_levin", cook_levin_theorem_ty()),
652        (
653            "Complexity.three_sat_np_complete",
654            three_sat_np_complete_ty(),
655        ),
656        ("Complexity.clique_np_complete", clique_np_complete_ty()),
657        (
658            "Complexity.vertex_cover_np_complete",
659            vertex_cover_np_complete_ty(),
660        ),
661        ("Complexity.ham_path_np_complete", ham_path_np_complete_ty()),
662        (
663            "Complexity.three_coloring_np_complete",
664            three_coloring_np_complete_ty(),
665        ),
666        (
667            "Complexity.subset_sum_np_complete",
668            subset_sum_np_complete_ty(),
669        ),
670        ("Complexity.knapsack_np_complete", knapsack_np_complete_ty()),
671        ("Complexity.qbf_pspace_complete", qbf_pspace_complete_ty()),
672        ("Complexity.tqbf_pspace_complete", tqbf_pspace_complete_ty()),
673        ("Complexity.time_hierarchy", time_hierarchy_theorem_ty()),
674        ("Complexity.space_hierarchy", space_hierarchy_theorem_ty()),
675        ("Complexity.shamir", shamir_theorem_ty()),
676        ("Complexity.pcp", pcp_theorem_ty()),
677        ("Complexity.ac0_strict_nc1", ac0_strict_nc1_ty()),
678        ("Complexity.clique_w1_complete", clique_w1_complete_ty()),
679    ] {
680        env.add(Declaration::Axiom {
681            name: Name::str(name),
682            univ_params: vec![],
683            ty,
684        })
685        .ok();
686    }
687    for (name, ty) in [
688        ("Algorithm", type0()),
689        ("kSAT", cst("ParameterizedProblem")),
690        ("ThreeSum", language_ty()),
691        ("APSP", language_ty()),
692        ("OrthogonalVectors", language_ty()),
693        ("SubExpTime", type0()),
694        ("SubCubicAlgorithmFor", arrow(language_ty(), prop())),
695        ("HasAlgorithmRunningIn", arrow(language_ty(), prop())),
696        ("SETHHolds", arrow(prop(), prop())),
697        ("ThreeSumHardnessHolds", arrow(prop(), prop())),
698        (
699            "Solves",
700            arrow(cst("Algorithm"), arrow(cst("ParameterizedProblem"), prop())),
701        ),
702        ("RunsIn", arrow(cst("Algorithm"), arrow(type0(), prop()))),
703        ("ParameterizedProblem", type0()),
704        (
705            "WClass",
706            arrow(nat_ty(), arrow(cst("ParameterizedProblem"), prop())),
707        ),
708        ("XP", arrow(cst("ParameterizedProblem"), prop())),
709        ("KClique", cst("ParameterizedProblem")),
710        ("W1Hard", arrow(cst("ParameterizedProblem"), prop())),
711        (
712            "HasKernelOfSize",
713            arrow(cst("ParameterizedProblem"), arrow(nat_ty(), prop())),
714        ),
715        (
716            "RunsInFPTTime",
717            arrow(
718                cst("ParameterizedProblem"),
719                arrow(arrow(nat_ty(), nat_ty()), prop()),
720            ),
721        ),
722        ("AC0", ac0_class_ty()),
723        ("TC0", tc0_class_ty()),
724        ("NC1Class", nc1_class_ty()),
725        ("Parity", language_ty()),
726        ("MAJORITY", arrow(nat_ty(), arrow(type0(), language_ty()))),
727        ("FormulaSize", arrow(language_ty(), nat_ty())),
728        ("ClassNC", type0()),
729        ("NCClass", arrow(nat_ty(), type0())),
730        ("Bits", type0()),
731        ("Bool", type0()),
732        (
733            "MatrixRank",
734            arrow(
735                arrow(cst("Bits"), arrow(cst("Bits"), cst("Bool"))),
736                nat_ty(),
737            ),
738        ),
739        ("DetCommComplexity", det_comm_complexity_ty()),
740        ("RandCommComplexity", rand_comm_complexity_ty()),
741        ("QuantumCommComplexity", quantum_comm_complexity_ty()),
742        ("Distribution", type0()),
743        (
744            "InfoCost",
745            arrow(cst("Protocol"), arrow(cst("Distribution"), real_ty())),
746        ),
747        ("Protocol", type0()),
748        ("CNFFormula", type0()),
749        ("IntegerProgram", type0()),
750        ("ResolutionWidth", resolution_width_ty()),
751        ("ResolutionSize", arrow(cst("CNFFormula"), nat_ty())),
752        ("HasPolySizeMonotoneCircuit", arrow(language_ty(), prop())),
753        ("PolyFamily", type0()),
754        ("VP", vp_class_ty()),
755        ("VNP", vnp_class_ty()),
756        ("VNPComplete", arrow(cst("PolyFamily"), prop())),
757        ("PermanentFamily", cst("PolyFamily")),
758        ("ClassVP", type0()),
759        ("ClassVNP", type0()),
760        ("DistProblem", type0()),
761        ("OWFExists", arrow(prop(), prop())),
762        ("HardOnAverage", arrow(language_ty(), prop())),
763        ("SomeNPProblem", language_ty()),
764        (
765            "EfficientlyComputable",
766            arrow(arrow(cst("Bits"), cst("Bits")), prop()),
767        ),
768        (
769            "HardToInvert",
770            arrow(arrow(cst("Bits"), cst("Bits")), prop()),
771        ),
772        ("WeakOWFExists", arrow(prop(), prop())),
773        ("StrongOWFExists", arrow(prop(), prop())),
774        ("PRGExists", arrow(prop(), prop())),
775        ("BQP", class_bqp_ty()),
776        ("QMA", class_qma_ty()),
777        ("QCMA", class_qcma_ty()),
778        ("QMAComplete", arrow(language_ty(), prop())),
779        ("LocalHamiltonian", language_ty()),
780        ("QMAClass", type0()),
781        ("PCPClass", type0()),
782        (
783            "IsEpsilonTester",
784            arrow(
785                arrow(arrow(cst("Bits"), cst("Bool")), prop()),
786                arrow(arrow(real_ty(), nat_ty()), prop()),
787            ),
788        ),
789        ("Graph", type0()),
790        (
791            "BLRTest",
792            arrow(arrow(cst("Bits"), cst("Bool")), arrow(nat_ty(), prop())),
793        ),
794        ("Passes", arrow(prop(), prop())),
795        ("IsLinear", arrow(arrow(cst("Bits"), cst("Bool")), prop())),
796        ("StreamingAlgorithm", type0()),
797        ("StreamSpaceBound", arrow(language_ty(), nat_ty())),
798        ("OnePassStreamingSpace", arrow(language_ty(), nat_ty())),
799        ("DistinctElements", language_ty()),
800        (
801            "ApproxDegree",
802            arrow(arrow(cst("Bits"), cst("Bool")), nat_ty()),
803        ),
804        (
805            "QuantumQueryComplexity",
806            arrow(arrow(cst("Bits"), cst("Bool")), nat_ty()),
807        ),
808        ("PolyDegree", poly_degree_ty()),
809        ("Sensitivity", sensitivity_ty()),
810        ("BlockSensitivity", block_sensitivity_ty()),
811    ] {
812        env.add(Declaration::Axiom {
813            name: Name::str(name),
814            univ_params: vec![],
815            ty,
816        })
817        .ok();
818    }
819    for (name, ty) in [
820        ("Complexity.seth_hypothesis", seth_hypothesis_ty()),
821        ("Complexity.three_sum_hypothesis", three_sum_hypothesis_ty()),
822        ("Complexity.apsp_conjecture", apsp_conjecture_ty()),
823        ("Complexity.ov_conjecture", ov_conjecture_ty()),
824        ("Complexity.seth_implies_3sum", seth_implies_3sum_ty()),
825        ("Complexity.fpt_algorithm", fpt_algorithm_ty()),
826        ("Complexity.w_hierarchy", w_hierarchy_ty()),
827        ("Complexity.polynomial_kernel", polynomial_kernel_ty()),
828        ("Complexity.fpt_subset_xp", fpt_subset_xp_ty()),
829        (
830            "Complexity.param_clique_w1_complete",
831            param_clique_w1_complete_ty(),
832        ),
833        (
834            "Complexity.circuit_hierarchy_containment",
835            circuit_hierarchy_containment_ty(),
836        ),
837        ("Complexity.parity_not_ac0", parity_not_ac0_ty()),
838        (
839            "Complexity.majority_formula_size",
840            majority_formula_size_ty(),
841        ),
842        ("Complexity.nc_hierarchy", nc_hierarchy_ty()),
843        ("Complexity.log_rank_conjecture", log_rank_conjecture_ty()),
844        (
845            "Complexity.information_complexity_lb",
846            information_complexity_lb_ty(),
847        ),
848        ("Complexity.size_width_tradeoff", size_width_tradeoff_ty()),
849        ("Complexity.clique_monotone_lb", clique_monotone_lb_ty()),
850        ("Complexity.vp_subset_vnp", vp_subset_vnp_ty()),
851        (
852            "Complexity.permanent_vnp_complete",
853            permanent_vnp_complete_ty(),
854        ),
855        (
856            "Complexity.vp_neq_vnp_conjecture",
857            vp_neq_vnp_conjecture_ty(),
858        ),
859        ("Complexity.impagliazzo_world", impagliazzo_world_ty()),
860        ("Complexity.owf_exists", owf_exists_ty()),
861        (
862            "Complexity.hardness_amplification",
863            hardness_amplification_ty(),
864        ),
865        ("Complexity.prg_from_owf", prg_from_owf_ty()),
866        ("Complexity.bqp_subset_pspace", bqp_subset_pspace_ty()),
867        ("Complexity.bpp_subset_bqp", bpp_subset_bqp_ty()),
868        (
869            "Complexity.quantum_pcp_conjecture",
870            quantum_pcp_conjecture_ty(),
871        ),
872        (
873            "Complexity.local_hamiltonian_qma_complete",
874            local_hamiltonian_qma_complete_ty(),
875        ),
876        ("Complexity.linearity_testing", linearity_testing_ty()),
877        ("Complexity.comm_space_tradeoff", comm_space_tradeoff_ty()),
878        (
879            "Complexity.distinct_elements_space_lb",
880            distinct_elements_space_lb_ty(),
881        ),
882        (
883            "Complexity.sensitivity_conjecture",
884            sensitivity_conjecture_ty(),
885        ),
886        ("Complexity.poly_method_lb", poly_method_lb_ty()),
887        (
888            "Complexity.bs_sensitivity_relation",
889            bs_sensitivity_relation_ty(),
890        ),
891    ] {
892        env.add(Declaration::Axiom {
893            name: Name::str(name),
894            univ_params: vec![],
895            ty,
896        })
897        .ok();
898    }
899    Ok(())
900}
901/// Subset sum solver: given a set of integers and a target, find a subset summing to target.
902pub fn subset_sum(nums: &[i64], target: i64) -> Option<Vec<usize>> {
903    use std::collections::HashMap;
904    let mut dp: HashMap<i64, Vec<usize>> = HashMap::new();
905    dp.insert(0, vec![]);
906    for (i, &num) in nums.iter().enumerate() {
907        let old_dp: Vec<(i64, Vec<usize>)> = dp.iter().map(|(&s, v)| (s, v.clone())).collect();
908        for (sum, mut indices) in old_dp {
909            let new_sum = sum + num;
910            dp.entry(new_sum).or_insert_with(|| {
911                indices.push(i);
912                indices
913            });
914        }
915    }
916    dp.remove(&target)
917}
918/// Knapsack 0/1 solver: maximize value with weight capacity.
919/// Returns (total_value, selected_item_indices).
920pub fn knapsack_01(weights: &[usize], values: &[usize], capacity: usize) -> (usize, Vec<usize>) {
921    let n = weights.len();
922    let mut dp = vec![vec![0usize; capacity + 1]; n + 1];
923    for i in 1..=n {
924        for w in 0..=capacity {
925            dp[i][w] = dp[i - 1][w];
926            if weights[i - 1] <= w {
927                let alt = dp[i - 1][w - weights[i - 1]] + values[i - 1];
928                if alt > dp[i][w] {
929                    dp[i][w] = alt;
930                }
931            }
932        }
933    }
934    let total = dp[n][capacity];
935    let mut selected = vec![];
936    let mut w = capacity;
937    for i in (1..=n).rev() {
938        if dp[i][w] != dp[i - 1][w] {
939            selected.push(i - 1);
940            w -= weights[i - 1];
941        }
942    }
943    selected.reverse();
944    (total, selected)
945}
946/// Graph coloring checker: given a coloring, verify it uses at most k colors
947/// and no two adjacent vertices share a color.
948pub fn verify_coloring(adj: &[Vec<usize>], coloring: &[usize], k: usize) -> bool {
949    for (u, neighbors) in adj.iter().enumerate() {
950        if coloring[u] >= k {
951            return false;
952        }
953        for &v in neighbors {
954            if coloring[u] == coloring[v] {
955                return false;
956            }
957        }
958    }
959    true
960}
961/// Greedy graph coloring (returns number of colors used and the coloring).
962pub fn greedy_coloring(adj: &[Vec<usize>]) -> (usize, Vec<usize>) {
963    let n = adj.len();
964    let mut colors = vec![usize::MAX; n];
965    let mut max_color = 0;
966    for v in 0..n {
967        let mut used = std::collections::HashSet::new();
968        for &u in &adj[v] {
969            if colors[u] != usize::MAX {
970                used.insert(colors[u]);
971            }
972        }
973        let mut c = 0;
974        while used.contains(&c) {
975            c += 1;
976        }
977        colors[v] = c;
978        if c + 1 > max_color {
979            max_color = c + 1;
980        }
981    }
982    (max_color, colors)
983}
984trait IntoReal {
985    fn into_real(self) -> Expr;
986}
987impl IntoReal for Expr {
988    fn into_real(self) -> Expr {
989        app(cst("Nat.toReal"), self)
990    }
991}
992pub fn real_ty() -> Expr {
993    cst("Real")
994}
995/// SETH (Strong Exponential Time Hypothesis):
996/// k-SAT cannot be solved in time O(2^((1-Ξ΅)n)) for any Ξ΅ > 0
997pub fn seth_hypothesis_ty() -> Expr {
998    pi(
999        BinderInfo::Default,
1000        "Ξ΅",
1001        real_ty(),
1002        arrow(
1003            app2(cst("Real.lt"), nat_lit(0).into_real(), bvar(0)),
1004            app(
1005                cst("Not"),
1006                pi(
1007                    BinderInfo::Default,
1008                    "k",
1009                    nat_ty(),
1010                    app(
1011                        cst("Exists"),
1012                        pi(
1013                            BinderInfo::Default,
1014                            "alg",
1015                            cst("Algorithm"),
1016                            app2(
1017                                cst("And"),
1018                                app2(cst("Solves"), bvar(0), cst("kSAT")),
1019                                app2(cst("RunsIn"), bvar(1), cst("SubExpTime")),
1020                            ),
1021                        ),
1022                    ),
1023                ),
1024            ),
1025        ),
1026    )
1027}
1028/// 3SUM hypothesis: no O(n^(2-Ξ΅)) algorithm for 3SUM on n integers
1029pub fn three_sum_hypothesis_ty() -> Expr {
1030    pi(
1031        BinderInfo::Default,
1032        "Ξ΅",
1033        real_ty(),
1034        arrow(
1035            app2(cst("Real.lt"), nat_lit(0).into_real(), bvar(0)),
1036            app(
1037                cst("Not"),
1038                app(
1039                    cst("Exists"),
1040                    pi(
1041                        BinderInfo::Default,
1042                        "alg",
1043                        cst("Algorithm"),
1044                        app2(
1045                            cst("And"),
1046                            app2(cst("Solves"), bvar(0), cst("ThreeSum")),
1047                            app(cst("SubQuadratic"), bvar(1)),
1048                        ),
1049                    ),
1050                ),
1051            ),
1052        ),
1053    )
1054}
1055/// APSP conjecture: All-Pairs Shortest Paths requires Omega(n^3 / polylog n) time
1056pub fn apsp_conjecture_ty() -> Expr {
1057    app(cst("Not"), app(cst("SubCubicAlgorithmFor"), cst("APSP")))
1058}
1059/// OV conjecture: Orthogonal Vectors cannot be solved in O(n^(2-Ξ΅)) time
1060pub fn ov_conjecture_ty() -> Expr {
1061    pi(
1062        BinderInfo::Default,
1063        "Ξ΅",
1064        real_ty(),
1065        arrow(
1066            app2(cst("Real.lt"), nat_lit(0).into_real(), bvar(0)),
1067            app(
1068                cst("Not"),
1069                app(cst("HasAlgorithmRunningIn"), cst("OrthogonalVectors")),
1070            ),
1071        ),
1072    )
1073}
1074/// SETH implies 3SUM hardness (reduction)
1075pub fn seth_implies_3sum_ty() -> Expr {
1076    arrow(
1077        app(cst("SETHHolds"), prop()),
1078        app(cst("ThreeSumHardnessHolds"), prop()),
1079    )
1080}
1081/// FPT algorithm running in f(k) * poly(n) time
1082pub fn fpt_algorithm_ty() -> Expr {
1083    pi(
1084        BinderInfo::Default,
1085        "prob",
1086        cst("ParameterizedProblem"),
1087        arrow(
1088            app(cst("FPT"), bvar(0)),
1089            app(
1090                cst("Exists"),
1091                pi(
1092                    BinderInfo::Default,
1093                    "f",
1094                    arrow(nat_ty(), nat_ty()),
1095                    app2(cst("RunsInFPTTime"), bvar(1), bvar(0)),
1096                ),
1097            ),
1098        ),
1099    )
1100}
1101/// W-hierarchy: W[1] βŠ† W[2] βŠ† ... βŠ† W[P]
1102pub fn w_hierarchy_ty() -> Expr {
1103    pi(
1104        BinderInfo::Default,
1105        "i",
1106        nat_ty(),
1107        pi(
1108            BinderInfo::Default,
1109            "L",
1110            cst("ParameterizedProblem"),
1111            arrow(
1112                app2(cst("WClass"), bvar(1), bvar(0)),
1113                app2(
1114                    cst("WClass"),
1115                    app2(cst("Nat.add"), bvar(2), nat_lit(1)),
1116                    bvar(1),
1117                ),
1118            ),
1119        ),
1120    )
1121}
1122/// Kernelization: a problem has a polynomial kernel
1123pub fn polynomial_kernel_ty() -> Expr {
1124    pi(
1125        BinderInfo::Default,
1126        "prob",
1127        cst("ParameterizedProblem"),
1128        pi(
1129            BinderInfo::Default,
1130            "c",
1131            nat_ty(),
1132            arrow(
1133                app2(
1134                    cst("HasKernelOfSize"),
1135                    bvar(1),
1136                    app2(cst("Nat.pow"), bvar(0), nat_lit(2)),
1137                ),
1138                app(cst("FPT"), bvar(2)),
1139            ),
1140        ),
1141    )
1142}
1143/// FPT βŠ† XP (slice-wise polynomial)
1144pub fn fpt_subset_xp_ty() -> Expr {
1145    pi(
1146        BinderInfo::Default,
1147        "L",
1148        cst("ParameterizedProblem"),
1149        arrow(app(cst("FPT"), bvar(0)), app(cst("XP"), bvar(1))),
1150    )
1151}
1152/// CLIQUE parameterized by k is W[1]-complete (parameterized version)
1153pub fn param_clique_w1_complete_ty() -> Expr {
1154    app2(
1155        cst("And"),
1156        app(cst("W1Hard"), cst("KClique")),
1157        app(cst("WClass"), nat_lit(1)),
1158    )
1159}
1160/// AC0 circuit class: constant depth, polynomial size, unbounded fan-in
1161pub fn ac0_class_ty() -> Expr {
1162    arrow(language_ty(), prop())
1163}
1164/// TC0 circuit class: constant depth threshold circuits
1165pub fn tc0_class_ty() -> Expr {
1166    arrow(language_ty(), prop())
1167}
1168/// NC1 circuit class: log-depth, polynomial size, fan-in 2
1169pub fn nc1_class_ty() -> Expr {
1170    arrow(language_ty(), prop())
1171}
1172/// AC0 βŠ† TC0 βŠ† NC1
1173pub fn circuit_hierarchy_containment_ty() -> Expr {
1174    pi(
1175        BinderInfo::Default,
1176        "L",
1177        language_ty(),
1178        arrow(
1179            app(cst("AC0"), bvar(0)),
1180            arrow(app(cst("TC0"), bvar(1)), app(cst("NC1Class"), bvar(2))),
1181        ),
1182    )
1183}
1184/// Parity not in AC0 (HΓ₯stad's switching lemma)
1185pub fn parity_not_ac0_ty() -> Expr {
1186    app(cst("Not"), app(cst("AC0"), cst("Parity")))
1187}
1188/// Formula size lower bound: MAJORITY requires Omega(n^2) formula size
1189pub fn majority_formula_size_ty() -> Expr {
1190    pi(
1191        BinderInfo::Default,
1192        "n",
1193        nat_ty(),
1194        app2(
1195            cst("Nat.le"),
1196            app2(cst("Nat.mul"), bvar(0), bvar(0)),
1197            app(cst("FormulaSize"), app2(cst("MAJORITY"), bvar(1), nat_ty())),
1198        ),
1199    )
1200}
1201/// NC hierarchy: NC^k ⊊ NC^(k+1) assuming NC β‰  P
1202pub fn nc_hierarchy_ty() -> Expr {
1203    arrow(
1204        app(cst("Not"), app2(cst("Eq"), cst("ClassNC"), cst("ClassP"))),
1205        pi(
1206            BinderInfo::Default,
1207            "k",
1208            nat_ty(),
1209            app(
1210                cst("Not"),
1211                app2(
1212                    cst("Eq"),
1213                    app(cst("NCClass"), bvar(0)),
1214                    app(cst("NCClass"), app2(cst("Nat.add"), bvar(1), nat_lit(1))),
1215                ),
1216            ),
1217        ),
1218    )
1219}
1220/// Deterministic communication complexity of a function f
1221pub fn det_comm_complexity_ty() -> Expr {
1222    arrow(
1223        arrow(cst("Bits"), arrow(cst("Bits"), cst("Bool"))),
1224        nat_ty(),
1225    )
1226}
1227/// Randomized communication complexity
1228pub fn rand_comm_complexity_ty() -> Expr {
1229    arrow(
1230        arrow(cst("Bits"), arrow(cst("Bits"), cst("Bool"))),
1231        nat_ty(),
1232    )
1233}
1234/// Quantum communication complexity
1235pub fn quantum_comm_complexity_ty() -> Expr {
1236    arrow(
1237        arrow(cst("Bits"), arrow(cst("Bits"), cst("Bool"))),
1238        nat_ty(),
1239    )
1240}
1241/// Log-rank conjecture: D(f) ≀ poly(log rank(M_f))
1242pub fn log_rank_conjecture_ty() -> Expr {
1243    pi(
1244        BinderInfo::Default,
1245        "f",
1246        arrow(cst("Bits"), arrow(cst("Bits"), cst("Bool"))),
1247        app(
1248            cst("Exists"),
1249            pi(
1250                BinderInfo::Default,
1251                "c",
1252                nat_ty(),
1253                app2(
1254                    cst("Nat.le"),
1255                    app(cst("DetCommComplexity"), bvar(1)),
1256                    app2(
1257                        cst("Nat.pow"),
1258                        app(cst("Nat.log2"), app(cst("MatrixRank"), bvar(2))),
1259                        bvar(0),
1260                    ),
1261                ),
1262            ),
1263        ),
1264    )
1265}
1266/// Information complexity lower bound for communication
1267pub fn information_complexity_lb_ty() -> Expr {
1268    pi(
1269        BinderInfo::Default,
1270        "f",
1271        arrow(cst("Bits"), arrow(cst("Bits"), cst("Bool"))),
1272        pi(
1273            BinderInfo::Default,
1274            "ΞΌ",
1275            cst("Distribution"),
1276            arrow(
1277                app2(
1278                    cst("Nat.le"),
1279                    app(cst("InfoCost"), bvar(0)),
1280                    app(cst("RandCommComplexity"), bvar(1)),
1281                ),
1282                prop(),
1283            ),
1284        ),
1285    )
1286}
1287/// Resolution proof system: a refutation of a CNF formula
1288pub fn resolution_proof_ty() -> Expr {
1289    arrow(cst("CNFFormula"), type0())
1290}
1291/// Width of a resolution refutation
1292pub fn resolution_width_ty() -> Expr {
1293    arrow(cst("CNFFormula"), nat_ty())
1294}
1295/// Size-width tradeoff for resolution (Ben-Sasson and Wigderson)
1296pub fn size_width_tradeoff_ty() -> Expr {
1297    pi(
1298        BinderInfo::Default,
1299        "F",
1300        cst("CNFFormula"),
1301        app2(
1302            cst("Nat.le"),
1303            app2(
1304                cst("Nat.mul"),
1305                app(cst("ResolutionWidth"), bvar(0)),
1306                app(cst("ResolutionWidth"), bvar(1)),
1307            ),
1308            app(cst("Nat.log2"), app(cst("ResolutionSize"), bvar(2))),
1309        ),
1310    )
1311}
1312/// Monotone circuit lower bound: CLIQUE requires super-polynomial monotone circuits
1313pub fn clique_monotone_lb_ty() -> Expr {
1314    app(
1315        cst("Not"),
1316        app(cst("HasPolySizeMonotoneCircuit"), cst("CLIQUE")),
1317    )
1318}
1319/// Cutting planes proof system
1320pub fn cutting_planes_ty() -> Expr {
1321    arrow(cst("IntegerProgram"), type0())
1322}
1323/// VP (Valiant's P): polynomial families computed by poly-size circuits
1324pub fn vp_class_ty() -> Expr {
1325    arrow(cst("PolyFamily"), prop())
1326}
1327/// VNP (Valiant's NP): polynomial families in the permanent class
1328pub fn vnp_class_ty() -> Expr {
1329    arrow(cst("PolyFamily"), prop())
1330}
1331/// Permanent polynomial family
1332pub fn permanent_ty() -> Expr {
1333    cst("PolyFamily")
1334}
1335/// Determinant polynomial family
1336pub fn determinant_ty() -> Expr {
1337    cst("PolyFamily")
1338}
1339/// VP βŠ† VNP
1340pub fn vp_subset_vnp_ty() -> Expr {
1341    pi(
1342        BinderInfo::Default,
1343        "f",
1344        cst("PolyFamily"),
1345        arrow(app(cst("VP"), bvar(0)), app(cst("VNP"), bvar(1))),
1346    )
1347}
1348/// Valiant's theorem: Permanent is VNP-complete
1349pub fn permanent_vnp_complete_ty() -> Expr {
1350    app(cst("VNPComplete"), cst("PermanentFamily"))
1351}
1352/// VP β‰  VNP conjecture (algebraic P vs NP)
1353pub fn vp_neq_vnp_conjecture_ty() -> Expr {
1354    app(cst("Not"), app2(cst("Eq"), cst("ClassVP"), cst("ClassVNP")))
1355}
1356/// Distributional NP: NP with a distribution over inputs
1357pub fn dist_np_ty() -> Expr {
1358    arrow(cst("Distribution"), arrow(language_ty(), prop()))
1359}
1360/// Levin reduction (average-case reduction)
1361pub fn levin_reduction_ty() -> Expr {
1362    pi(
1363        BinderInfo::Default,
1364        "A",
1365        cst("DistProblem"),
1366        pi(BinderInfo::Default, "B", cst("DistProblem"), prop()),
1367    )
1368}
1369/// Average-case complete problem
1370pub fn avg_case_complete_ty() -> Expr {
1371    arrow(cst("DistProblem"), prop())
1372}
1373/// Impagliazzo's worlds hypothesis (simplified: OWF exists ↔ hard on avg)
1374pub fn impagliazzo_world_ty() -> Expr {
1375    app2(
1376        cst("Iff"),
1377        app(cst("OWFExists"), prop()),
1378        app(cst("HardOnAverage"), cst("SomeNPProblem")),
1379    )
1380}
1381/// One-way function existence
1382pub fn owf_exists_ty() -> Expr {
1383    app(
1384        cst("Exists"),
1385        pi(
1386            BinderInfo::Default,
1387            "f",
1388            arrow(cst("Bits"), cst("Bits")),
1389            app2(
1390                cst("And"),
1391                app(cst("EfficientlyComputable"), bvar(0)),
1392                app(cst("HardToInvert"), bvar(1)),
1393            ),
1394        ),
1395    )
1396}
1397/// Hardness amplification: weak OWF β†’ strong OWF
1398pub fn hardness_amplification_ty() -> Expr {
1399    arrow(
1400        app(cst("WeakOWFExists"), prop()),
1401        app(cst("StrongOWFExists"), prop()),
1402    )
1403}
1404/// PRG (Pseudorandom Generator) existence from OWF
1405pub fn prg_from_owf_ty() -> Expr {
1406    arrow(app(cst("OWFExists"), prop()), app(cst("PRGExists"), prop()))
1407}
1408/// Computational indistinguishability
1409pub fn comp_indist_ty() -> Expr {
1410    pi(
1411        BinderInfo::Default,
1412        "D1",
1413        cst("Distribution"),
1414        pi(BinderInfo::Default, "D2", cst("Distribution"), prop()),
1415    )
1416}
1417/// BQP: bounded-error quantum polynomial time
1418pub fn class_bqp_ty() -> Expr {
1419    arrow(language_ty(), prop())
1420}
1421/// QMA: quantum Merlin-Arthur (quantum analog of NP)
1422pub fn class_qma_ty() -> Expr {
1423    arrow(language_ty(), prop())
1424}
1425/// QCMA: classical witness quantum verifier
1426pub fn class_qcma_ty() -> Expr {
1427    arrow(language_ty(), prop())
1428}
1429/// BQP βŠ† PSPACE
1430pub fn bqp_subset_pspace_ty() -> Expr {
1431    pi(
1432        BinderInfo::Default,
1433        "L",
1434        language_ty(),
1435        arrow(app(cst("BQP"), bvar(0)), app(cst("PSPACE"), bvar(1))),
1436    )
1437}
1438/// BPP βŠ† BQP
1439pub fn bpp_subset_bqp_ty() -> Expr {
1440    pi(
1441        BinderInfo::Default,
1442        "L",
1443        language_ty(),
1444        arrow(app(cst("BPP"), bvar(0)), app(cst("BQP"), bvar(1))),
1445    )
1446}
1447/// Quantum PCP conjecture: QMA βŠ† MIP* = RE (negation of classical PCP analog)
1448pub fn quantum_pcp_conjecture_ty() -> Expr {
1449    app(
1450        cst("Not"),
1451        app2(cst("Eq"), cst("QMAClass"), cst("PCPClass")),
1452    )
1453}
1454/// Local Hamiltonian problem is QMA-complete
1455pub fn local_hamiltonian_qma_complete_ty() -> Expr {
1456    app(cst("QMAComplete"), cst("LocalHamiltonian"))
1457}
1458/// Testability of a boolean function property with query complexity q(Ξ΅)
1459pub fn property_testable_ty() -> Expr {
1460    pi(
1461        BinderInfo::Default,
1462        "P",
1463        arrow(arrow(cst("Bits"), cst("Bool")), prop()),
1464        arrow(
1465            app(
1466                cst("Exists"),
1467                pi(
1468                    BinderInfo::Default,
1469                    "q",
1470                    arrow(real_ty(), nat_ty()),
1471                    app2(cst("IsEpsilonTester"), bvar(0), bvar(1)),
1472                ),
1473            ),
1474            prop(),
1475        ),
1476    )
1477}
1478/// Graph property testable if it has a constant query complexity tester
1479pub fn graph_property_testable_ty() -> Expr {
1480    arrow(arrow(cst("Graph"), prop()), prop())
1481}
1482/// Tolerant property testing: distinguishes Ξ΅1-close from Ξ΅2-far
1483pub fn tolerant_testing_ty() -> Expr {
1484    pi(
1485        BinderInfo::Default,
1486        "P",
1487        arrow(arrow(cst("Bits"), cst("Bool")), prop()),
1488        pi(
1489            BinderInfo::Default,
1490            "Ξ΅1",
1491            real_ty(),
1492            pi(
1493                BinderInfo::Default,
1494                "Ξ΅2",
1495                real_ty(),
1496                arrow(app2(cst("Real.lt"), bvar(1), bvar(0)), prop()),
1497            ),
1498        ),
1499    )
1500}
1501/// Linearity testing (BLR test)
1502pub fn linearity_testing_ty() -> Expr {
1503    pi(
1504        BinderInfo::Default,
1505        "f",
1506        arrow(cst("Bits"), cst("Bool")),
1507        arrow(
1508            app(cst("Passes"), app2(cst("BLRTest"), bvar(0), nat_lit(3))),
1509            app(cst("IsLinear"), bvar(1)),
1510        ),
1511    )
1512}
1513/// Space complexity of streaming algorithm
1514pub fn stream_space_ty() -> Expr {
1515    arrow(cst("StreamingAlgorithm"), nat_ty())
1516}
1517/// Communication-space lower bound tradeoff
1518pub fn comm_space_tradeoff_ty() -> Expr {
1519    pi(
1520        BinderInfo::Default,
1521        "f",
1522        arrow(cst("Bits"), arrow(cst("Bits"), cst("Bool"))),
1523        app2(
1524            cst("Nat.le"),
1525            app(cst("RandCommComplexity"), bvar(0)),
1526            app(cst("StreamSpaceBound"), bvar(1)),
1527        ),
1528    )
1529}
1530/// Information cost of a protocol
1531pub fn information_cost_ty() -> Expr {
1532    pi(
1533        BinderInfo::Default,
1534        "Ο€",
1535        cst("Protocol"),
1536        pi(BinderInfo::Default, "ΞΌ", cst("Distribution"), real_ty()),
1537    )
1538}
1539/// Distinct elements requires Omega(n) space in one-pass streaming
1540pub fn distinct_elements_space_lb_ty() -> Expr {
1541    pi(
1542        BinderInfo::Default,
1543        "n",
1544        nat_ty(),
1545        app2(
1546            cst("Nat.le"),
1547            bvar(0),
1548            app(cst("OnePassStreamingSpace"), cst("DistinctElements")),
1549        ),
1550    )
1551}
1552/// Polynomial degree of a Boolean function
1553pub fn poly_degree_ty() -> Expr {
1554    arrow(arrow(cst("Bits"), cst("Bool")), nat_ty())
1555}
1556/// Block sensitivity of a Boolean function
1557pub fn block_sensitivity_ty() -> Expr {
1558    arrow(arrow(cst("Bits"), cst("Bool")), nat_ty())
1559}
1560/// Sensitivity of a Boolean function
1561pub fn sensitivity_ty() -> Expr {
1562    arrow(arrow(cst("Bits"), cst("Bool")), nat_ty())
1563}
1564/// Sensitivity conjecture (Huang 2019): s(f) β‰₯ sqrt(deg(f))
1565pub fn sensitivity_conjecture_ty() -> Expr {
1566    pi(
1567        BinderInfo::Default,
1568        "f",
1569        arrow(cst("Bits"), cst("Bool")),
1570        app2(
1571            cst("Nat.le"),
1572            app(cst("Sensitivity"), bvar(0)),
1573            app(cst("Nat.sqrt"), app(cst("PolyDegree"), bvar(1))),
1574        ),
1575    )
1576}
1577/// Polynomial method: deg(f) ≀ D(f) (approximate degree lower bounds)
1578pub fn poly_method_lb_ty() -> Expr {
1579    pi(
1580        BinderInfo::Default,
1581        "f",
1582        arrow(cst("Bits"), cst("Bool")),
1583        app2(
1584            cst("Nat.le"),
1585            app(cst("ApproxDegree"), bvar(0)),
1586            app(cst("QuantumQueryComplexity"), bvar(1)),
1587        ),
1588    )
1589}
1590/// Block sensitivity vs sensitivity: bs(f) ≀ s(f)^6 (old bound; now s(f)^2 β‰₯ bs(f) by Huang)
1591pub fn bs_sensitivity_relation_ty() -> Expr {
1592    pi(
1593        BinderInfo::Default,
1594        "f",
1595        arrow(cst("Bits"), cst("Bool")),
1596        app2(
1597            cst("Nat.le"),
1598            app(cst("BlockSensitivity"), bvar(0)),
1599            app2(cst("Nat.pow"), app(cst("Sensitivity"), bvar(1)), nat_lit(2)),
1600        ),
1601    )
1602}
1603#[cfg(test)]
1604mod tests {
1605    use super::*;
1606    use std::fmt;
1607    #[test]
1608    fn test_two_sat_simple() {
1609        let mut solver = TwoSatSolver::new(2);
1610        solver.add_clause(0, 2);
1611        solver.add_clause(1, 2);
1612        solver.add_clause(0, 3);
1613        let result = solver.solve();
1614        assert!(result.is_some(), "should be satisfiable");
1615    }
1616    #[test]
1617    fn test_two_sat_unsat() {
1618        let mut solver = TwoSatSolver::new(1);
1619        solver.add_clause(0, 0);
1620        solver.add_clause(1, 1);
1621        let result = solver.solve();
1622        assert!(result.is_none(), "should be unsatisfiable");
1623    }
1624    #[test]
1625    fn test_dpll_satisfiable() {
1626        let mut solver = DpllSolver::new(3);
1627        solver.add_clause(vec![1, 2]);
1628        solver.add_clause(vec![-1, 3]);
1629        solver.add_clause(vec![2, 3]);
1630        assert!(solver.solve().is_some());
1631    }
1632    #[test]
1633    fn test_dpll_unsatisfiable() {
1634        let mut solver = DpllSolver::new(1);
1635        solver.add_clause(vec![1]);
1636        solver.add_clause(vec![-1]);
1637        assert!(solver.solve().is_none());
1638    }
1639    #[test]
1640    fn test_subset_sum_found() {
1641        let nums = vec![3i64, 1, 4, 1, 5, 9, 2, 6];
1642        let target = 10;
1643        let result = subset_sum(&nums, target);
1644        assert!(result.is_some(), "Should find subset summing to 10");
1645        let indices = result.expect("result should be valid");
1646        let sum: i64 = indices.iter().map(|&i| nums[i]).sum();
1647        assert_eq!(sum, target);
1648    }
1649    #[test]
1650    fn test_knapsack() {
1651        let weights = vec![2, 3, 4, 5];
1652        let values = vec![3, 4, 5, 6];
1653        let capacity = 8;
1654        let (total, selected) = knapsack_01(&weights, &values, capacity);
1655        assert!(total > 0);
1656        let total_weight: usize = selected.iter().map(|&i| weights[i]).sum();
1657        assert!(total_weight <= capacity);
1658    }
1659    #[test]
1660    fn test_greedy_coloring() {
1661        let adj = vec![vec![1, 2], vec![0, 2], vec![0, 1]];
1662        let (colors, coloring) = greedy_coloring(&adj);
1663        assert!(colors >= 3);
1664        assert!(verify_coloring(&adj, &coloring, colors));
1665    }
1666    #[test]
1667    fn test_sudoku_solver() {
1668        #[rustfmt::skip]
1669        let grid: [u8; 81] = [
1670            5, 3, 0, 0, 7, 0, 0, 0, 0, 6, 0, 0, 1, 9, 5, 0, 0, 0, 0, 9, 8, 0, 0, 0, 0, 6,
1671            0, 8, 0, 0, 0, 6, 0, 0, 0, 3, 4, 0, 0, 8, 0, 3, 0, 0, 1, 7, 0, 0, 0, 2, 0, 0,
1672            0, 6, 0, 6, 0, 0, 0, 0, 2, 8, 0, 0, 0, 0, 4, 1, 9, 0, 0, 5, 0, 0, 0, 0, 8, 0,
1673            0, 7, 9,
1674        ];
1675        let mut solver = SudokuSolver::new(grid);
1676        assert!(solver.solve());
1677    }
1678    #[test]
1679    fn test_parameterized_algorithm_checker_within_bound() {
1680        let checker = ParameterizedAlgorithmChecker::new("treewidth");
1681        assert!(checker.check(70, 3, 10, |k| 1u64 << k, 1));
1682    }
1683    #[test]
1684    fn test_parameterized_algorithm_checker_exceeds_bound() {
1685        let checker = ParameterizedAlgorithmChecker::new("pathwidth");
1686        assert!(!checker.check(100, 3, 10, |k| 1u64 << k, 1));
1687    }
1688    #[test]
1689    fn test_parameterized_check_2k_n() {
1690        let checker = ParameterizedAlgorithmChecker::new("vertex_cover");
1691        assert!(checker.check_2k_n(300, 4, 20));
1692        assert!(!checker.check_2k_n(400, 4, 20));
1693    }
1694    #[test]
1695    fn test_circuit_evaluator_and() {
1696        let mut circ = CircuitEvaluator::new();
1697        let i0 = circ.add_gate(GateKind::Input(0), None, None);
1698        let i1 = circ.add_gate(GateKind::Input(1), None, None);
1699        circ.add_gate(GateKind::And, Some(i0), Some(i1));
1700        assert!(!circ.evaluate(&[false, true]));
1701        assert!(circ.evaluate(&[true, true]));
1702    }
1703    #[test]
1704    fn test_circuit_evaluator_or_not() {
1705        let mut circ = CircuitEvaluator::new();
1706        let i0 = circ.add_gate(GateKind::Input(0), None, None);
1707        let n0 = circ.add_gate(GateKind::Not, Some(i0), None);
1708        let i1 = circ.add_gate(GateKind::Input(1), None, None);
1709        circ.add_gate(GateKind::Or, Some(n0), Some(i1));
1710        assert!(circ.evaluate(&[false, false]));
1711        assert!(!circ.evaluate(&[true, false]));
1712    }
1713    #[test]
1714    fn test_communication_matrix_rank_gf2() {
1715        let mat = vec![vec![1u8, 0, 0], vec![0, 1, 0], vec![0, 0, 1]];
1716        let analyzer = CommunicationMatrixAnalyzer::new(mat);
1717        assert_eq!(analyzer.rank_gf2(), 3);
1718    }
1719    #[test]
1720    fn test_communication_matrix_rank_gf2_zero_matrix() {
1721        let mat = vec![vec![0u8, 0], vec![0, 0]];
1722        let analyzer = CommunicationMatrixAnalyzer::new(mat);
1723        assert_eq!(analyzer.rank_gf2(), 0);
1724    }
1725    #[test]
1726    fn test_communication_matrix_log_rank_lb() {
1727        let mat = vec![
1728            vec![1u8, 0, 0, 0],
1729            vec![0, 1, 0, 0],
1730            vec![0, 0, 1, 0],
1731            vec![0, 0, 0, 1],
1732        ];
1733        let analyzer = CommunicationMatrixAnalyzer::new(mat);
1734        assert_eq!(analyzer.log_rank_lower_bound(), 2);
1735    }
1736    #[test]
1737    fn test_resolution_prover_refutes_contradiction() {
1738        let mut prover = ResolutionProverSmall::new();
1739        prover.add_clause(vec![1]);
1740        prover.add_clause(vec![-1]);
1741        assert!(prover.refute(100));
1742    }
1743    #[test]
1744    fn test_resolution_prover_satisfiable() {
1745        let mut prover = ResolutionProverSmall::new();
1746        prover.add_clause(vec![1, 2]);
1747        prover.add_clause(vec![-1, 2]);
1748        assert!(!prover.refute(200));
1749    }
1750    #[test]
1751    fn test_resolution_prover_three_variable_unsat() {
1752        let mut prover = ResolutionProverSmall::new();
1753        prover.add_clause(vec![1]);
1754        prover.add_clause(vec![-1, 2]);
1755        prover.add_clause(vec![-2]);
1756        assert!(prover.refute(500));
1757    }
1758    #[test]
1759    fn test_sensitivity_checker_parity_2bit() {
1760        let table = vec![false, true, true, false];
1761        let checker = SensitivityChecker::new(table);
1762        assert_eq!(checker.max_sensitivity(), 2);
1763    }
1764    #[test]
1765    fn test_sensitivity_checker_constant_function() {
1766        let table = vec![false; 8];
1767        let checker = SensitivityChecker::new(table);
1768        assert_eq!(checker.max_sensitivity(), 0);
1769        assert_eq!(checker.max_block_sensitivity(), 0);
1770    }
1771    #[test]
1772    fn test_sensitivity_checker_huang_theorem() {
1773        let table = vec![false, true, true, true];
1774        let checker = SensitivityChecker::new(table);
1775        assert!(checker.check_huang_theorem());
1776    }
1777    #[test]
1778    fn test_new_axiom_types_build_ok() {
1779        let mut env = Environment::new();
1780        let result = build_complexity_env(&mut env);
1781        assert!(result.is_ok(), "build_complexity_env should succeed");
1782    }
1783}