1use 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}
47pub fn language_ty() -> Expr {
49 arrow(cst("String"), prop())
50}
51pub fn time_complexity_ty() -> Expr {
54 type0()
55}
56pub fn turing_machine_ty() -> Expr {
58 type0()
59}
60pub fn ntm_ty() -> Expr {
62 type0()
63}
64pub fn oracle_machine_ty() -> Expr {
66 arrow(language_ty(), type0())
67}
68pub fn dtime_ty() -> Expr {
71 arrow(arrow(nat_ty(), nat_ty()), arrow(language_ty(), prop()))
72}
73pub fn ntime_ty() -> Expr {
76 arrow(arrow(nat_ty(), nat_ty()), arrow(language_ty(), prop()))
77}
78pub fn dspace_ty() -> Expr {
81 arrow(arrow(nat_ty(), nat_ty()), arrow(language_ty(), prop()))
82}
83pub fn nspace_ty() -> Expr {
85 arrow(arrow(nat_ty(), nat_ty()), arrow(language_ty(), prop()))
86}
87pub fn class_p_ty() -> Expr {
89 arrow(language_ty(), prop())
90}
91pub fn class_np_ty() -> Expr {
93 arrow(language_ty(), prop())
94}
95pub fn class_conp_ty() -> Expr {
97 arrow(language_ty(), prop())
98}
99pub fn class_pspace_ty() -> Expr {
101 arrow(language_ty(), prop())
102}
103pub fn class_npspace_ty() -> Expr {
105 arrow(language_ty(), prop())
106}
107pub fn class_exp_ty() -> Expr {
109 arrow(language_ty(), prop())
110}
111pub fn class_nexp_ty() -> Expr {
113 arrow(language_ty(), prop())
114}
115pub fn class_l_ty() -> Expr {
117 arrow(language_ty(), prop())
118}
119pub fn class_nl_ty() -> Expr {
121 arrow(language_ty(), prop())
122}
123pub fn class_ph_ty() -> Expr {
125 arrow(language_ty(), prop())
126}
127pub fn sigma_p_ty() -> Expr {
129 arrow(nat_ty(), arrow(language_ty(), prop()))
130}
131pub fn pi_p_ty() -> Expr {
133 arrow(nat_ty(), arrow(language_ty(), prop()))
134}
135pub fn delta_p_ty() -> Expr {
137 arrow(nat_ty(), arrow(language_ty(), prop()))
138}
139pub fn class_sharp_p_ty() -> Expr {
141 arrow(language_ty(), prop())
142}
143pub fn class_rp_ty() -> Expr {
145 arrow(language_ty(), prop())
146}
147pub fn class_corp_ty() -> Expr {
149 arrow(language_ty(), prop())
150}
151pub fn class_bpp_ty() -> Expr {
153 arrow(language_ty(), prop())
154}
155pub fn class_zpp_ty() -> Expr {
157 arrow(language_ty(), prop())
158}
159pub fn class_pp_ty() -> Expr {
161 arrow(language_ty(), prop())
162}
163pub fn class_ip_ty() -> Expr {
165 arrow(language_ty(), prop())
166}
167pub fn in_pspace_ty() -> Expr {
169 arrow(language_ty(), prop())
170}
171pub 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}
181pub 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}
191pub 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}
201pub fn np_hard_ty() -> Expr {
203 arrow(language_ty(), prop())
204}
205pub fn np_complete_ty() -> Expr {
207 arrow(language_ty(), prop())
208}
209pub fn pspace_complete_ty() -> Expr {
211 arrow(language_ty(), prop())
212}
213pub fn exp_complete_ty() -> Expr {
215 arrow(language_ty(), prop())
216}
217pub 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}
226pub 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}
235pub 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}
244pub 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}
257pub 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}
270pub fn cook_levin_theorem_ty() -> Expr {
272 app(cst("NPComplete"), cst("SAT"))
273}
274pub fn three_sat_np_complete_ty() -> Expr {
276 app(cst("NPComplete"), cst("ThreeSAT"))
277}
278pub fn clique_np_complete_ty() -> Expr {
280 app(cst("NPComplete"), cst("CLIQUE"))
281}
282pub fn vertex_cover_np_complete_ty() -> Expr {
284 app(cst("NPComplete"), cst("VertexCover"))
285}
286pub fn ham_path_np_complete_ty() -> Expr {
288 app(cst("NPComplete"), cst("HamiltonianPath"))
289}
290pub fn three_coloring_np_complete_ty() -> Expr {
292 app(cst("NPComplete"), cst("GraphThreeColoring"))
293}
294pub fn subset_sum_np_complete_ty() -> Expr {
296 app(cst("NPComplete"), cst("SubsetSum"))
297}
298pub fn knapsack_np_complete_ty() -> Expr {
300 app(cst("NPComplete"), cst("Knapsack"))
301}
302pub fn qbf_pspace_complete_ty() -> Expr {
304 app(cst("PSPACEComplete"), cst("QBF"))
305}
306pub fn tqbf_pspace_complete_ty() -> Expr {
308 app(cst("PSPACEComplete"), cst("TQBF"))
309}
310pub 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}
361pub 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}
398pub 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}
421pub 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}
456pub 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}
469pub 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}
485pub fn bool_circuit_ty() -> Expr {
487 arrow(nat_ty(), type0())
488}
489pub fn nc_class_ty() -> Expr {
491 arrow(nat_ty(), arrow(language_ty(), prop()))
492}
493pub fn ac_class_ty() -> Expr {
495 arrow(nat_ty(), arrow(language_ty(), prop()))
496}
497pub fn tc_class_ty() -> Expr {
499 arrow(nat_ty(), arrow(language_ty(), prop()))
500}
501pub 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}
518pub fn ac0_strict_nc1_ty() -> Expr {
520 app(
521 cst("Not"),
522 app2(cst("Eq"), cst("ClassAC0"), cst("ClassNC1")),
523 )
524}
525pub fn is_approximable_ty() -> Expr {
528 arrow(cst("Rat"), arrow(language_ty(), prop()))
529}
530pub 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}
545pub fn fpt_ty() -> Expr {
547 arrow(language_ty(), prop())
548}
549pub fn w1_ty() -> Expr {
551 arrow(language_ty(), prop())
552}
553pub fn clique_w1_complete_ty() -> Expr {
555 app(cst("W1Complete"), cst("ParameterizedCLIQUE"))
556}
557pub 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}
901pub 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}
918pub 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}
946pub 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}
961pub 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}
995pub 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}
1028pub 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}
1055pub fn apsp_conjecture_ty() -> Expr {
1057 app(cst("Not"), app(cst("SubCubicAlgorithmFor"), cst("APSP")))
1058}
1059pub 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}
1074pub fn seth_implies_3sum_ty() -> Expr {
1076 arrow(
1077 app(cst("SETHHolds"), prop()),
1078 app(cst("ThreeSumHardnessHolds"), prop()),
1079 )
1080}
1081pub 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}
1101pub 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}
1122pub 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}
1143pub 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}
1152pub 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}
1160pub fn ac0_class_ty() -> Expr {
1162 arrow(language_ty(), prop())
1163}
1164pub fn tc0_class_ty() -> Expr {
1166 arrow(language_ty(), prop())
1167}
1168pub fn nc1_class_ty() -> Expr {
1170 arrow(language_ty(), prop())
1171}
1172pub 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}
1184pub fn parity_not_ac0_ty() -> Expr {
1186 app(cst("Not"), app(cst("AC0"), cst("Parity")))
1187}
1188pub 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}
1201pub 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}
1220pub fn det_comm_complexity_ty() -> Expr {
1222 arrow(
1223 arrow(cst("Bits"), arrow(cst("Bits"), cst("Bool"))),
1224 nat_ty(),
1225 )
1226}
1227pub fn rand_comm_complexity_ty() -> Expr {
1229 arrow(
1230 arrow(cst("Bits"), arrow(cst("Bits"), cst("Bool"))),
1231 nat_ty(),
1232 )
1233}
1234pub fn quantum_comm_complexity_ty() -> Expr {
1236 arrow(
1237 arrow(cst("Bits"), arrow(cst("Bits"), cst("Bool"))),
1238 nat_ty(),
1239 )
1240}
1241pub 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}
1266pub 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}
1287pub fn resolution_proof_ty() -> Expr {
1289 arrow(cst("CNFFormula"), type0())
1290}
1291pub fn resolution_width_ty() -> Expr {
1293 arrow(cst("CNFFormula"), nat_ty())
1294}
1295pub 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}
1312pub fn clique_monotone_lb_ty() -> Expr {
1314 app(
1315 cst("Not"),
1316 app(cst("HasPolySizeMonotoneCircuit"), cst("CLIQUE")),
1317 )
1318}
1319pub fn cutting_planes_ty() -> Expr {
1321 arrow(cst("IntegerProgram"), type0())
1322}
1323pub fn vp_class_ty() -> Expr {
1325 arrow(cst("PolyFamily"), prop())
1326}
1327pub fn vnp_class_ty() -> Expr {
1329 arrow(cst("PolyFamily"), prop())
1330}
1331pub fn permanent_ty() -> Expr {
1333 cst("PolyFamily")
1334}
1335pub fn determinant_ty() -> Expr {
1337 cst("PolyFamily")
1338}
1339pub 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}
1348pub fn permanent_vnp_complete_ty() -> Expr {
1350 app(cst("VNPComplete"), cst("PermanentFamily"))
1351}
1352pub fn vp_neq_vnp_conjecture_ty() -> Expr {
1354 app(cst("Not"), app2(cst("Eq"), cst("ClassVP"), cst("ClassVNP")))
1355}
1356pub fn dist_np_ty() -> Expr {
1358 arrow(cst("Distribution"), arrow(language_ty(), prop()))
1359}
1360pub 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}
1369pub fn avg_case_complete_ty() -> Expr {
1371 arrow(cst("DistProblem"), prop())
1372}
1373pub fn impagliazzo_world_ty() -> Expr {
1375 app2(
1376 cst("Iff"),
1377 app(cst("OWFExists"), prop()),
1378 app(cst("HardOnAverage"), cst("SomeNPProblem")),
1379 )
1380}
1381pub 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}
1397pub fn hardness_amplification_ty() -> Expr {
1399 arrow(
1400 app(cst("WeakOWFExists"), prop()),
1401 app(cst("StrongOWFExists"), prop()),
1402 )
1403}
1404pub fn prg_from_owf_ty() -> Expr {
1406 arrow(app(cst("OWFExists"), prop()), app(cst("PRGExists"), prop()))
1407}
1408pub 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}
1417pub fn class_bqp_ty() -> Expr {
1419 arrow(language_ty(), prop())
1420}
1421pub fn class_qma_ty() -> Expr {
1423 arrow(language_ty(), prop())
1424}
1425pub fn class_qcma_ty() -> Expr {
1427 arrow(language_ty(), prop())
1428}
1429pub 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}
1438pub 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}
1447pub fn quantum_pcp_conjecture_ty() -> Expr {
1449 app(
1450 cst("Not"),
1451 app2(cst("Eq"), cst("QMAClass"), cst("PCPClass")),
1452 )
1453}
1454pub fn local_hamiltonian_qma_complete_ty() -> Expr {
1456 app(cst("QMAComplete"), cst("LocalHamiltonian"))
1457}
1458pub 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}
1478pub fn graph_property_testable_ty() -> Expr {
1480 arrow(arrow(cst("Graph"), prop()), prop())
1481}
1482pub 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}
1501pub 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}
1513pub fn stream_space_ty() -> Expr {
1515 arrow(cst("StreamingAlgorithm"), nat_ty())
1516}
1517pub 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}
1530pub fn information_cost_ty() -> Expr {
1532 pi(
1533 BinderInfo::Default,
1534 "Ο",
1535 cst("Protocol"),
1536 pi(BinderInfo::Default, "ΞΌ", cst("Distribution"), real_ty()),
1537 )
1538}
1539pub 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}
1552pub fn poly_degree_ty() -> Expr {
1554 arrow(arrow(cst("Bits"), cst("Bool")), nat_ty())
1555}
1556pub fn block_sensitivity_ty() -> Expr {
1558 arrow(arrow(cst("Bits"), cst("Bool")), nat_ty())
1559}
1560pub fn sensitivity_ty() -> Expr {
1562 arrow(arrow(cst("Bits"), cst("Bool")), nat_ty())
1563}
1564pub 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}
1577pub 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}
1590pub 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}